diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,7 @@
 # Changelog
 
+see latest changes on [Github](https://github.com/morpheusgraphql/morpheus-graphql/releases)
+
 ## 0.19.0 - 21.03.2022
 
 ## 0.18.0 - 08.11.2021
diff --git a/morpheus-graphql-client.cabal b/morpheus-graphql-client.cabal
--- a/morpheus-graphql-client.cabal
+++ b/morpheus-graphql-client.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           morpheus-graphql-client
-version:        0.19.0
+version:        0.19.1
 synopsis:       Morpheus GraphQL Client
 description:    Build GraphQL APIs with your favourite functional language!
 category:       web, graphql, client
@@ -18,8 +18,8 @@
 license-file:   LICENSE
 build-type:     Simple
 extra-source-files:
-    changelog.md
     README.md
+    changelog.md
 data-files:
     test/Case/Enum/schema.gql
     test/Case/Github/schema.gql
@@ -73,11 +73,11 @@
     , bytestring >=0.10.4 && <0.11
     , morpheus-graphql-code-gen >=0.19.0 && <0.20.0
     , morpheus-graphql-core >=0.19.0 && <0.20.0
-    , mtl >=2.0 && <=3.0
-    , relude >=0.3.0
-    , template-haskell >=2.0 && <=3.0
+    , mtl >=2.0 && <3.0
+    , relude >=0.3.0 && <2.0
+    , template-haskell >=2.0 && <3.0
     , text >=1.2.3.0 && <1.3
-    , transformers >=0.3.0.0 && <1.0
+    , transformers >=0.3 && <0.6
     , unordered-containers >=0.2.8.0 && <0.3
   default-language: Haskell2010
 
@@ -103,19 +103,19 @@
       test
   ghc-options: -Wall
   build-depends:
-      aeson
+      aeson >=1.4.4.0 && <3
     , base >=4.7 && <5
     , bytestring >=0.10.4 && <0.11
-    , directory >=1.0
+    , directory >=1.0 && <2.0
     , morpheus-graphql-client
     , morpheus-graphql-code-gen >=0.19.0 && <0.20.0
     , morpheus-graphql-core >=0.19.0 && <0.20.0
-    , mtl >=2.0 && <=3.0
-    , relude >=0.3.0
-    , tasty
-    , tasty-hunit
-    , template-haskell >=2.0 && <=3.0
+    , mtl >=2.0 && <3.0
+    , relude >=0.3.0 && <2.0
+    , tasty >=0.1 && <1.5
+    , tasty-hunit >=0.1 && <1.0
+    , template-haskell >=2.0 && <3.0
     , text >=1.2.3.0 && <1.3
-    , transformers >=0.3.0.0 && <1.0
+    , transformers >=0.3 && <0.6
     , unordered-containers >=0.2.8.0 && <0.3
   default-language: Haskell2010
diff --git a/src/Data/Morpheus/Client/Declare/Aeson.hs b/src/Data/Morpheus/Client/Declare/Aeson.hs
--- a/src/Data/Morpheus/Client/Declare/Aeson.hs
+++ b/src/Data/Morpheus/Client/Declare/Aeson.hs
@@ -23,6 +23,8 @@
     failExp,
     matchWith,
     mkFieldsE,
+    isTypeDeclared,
+    hasInstance
   )
 import Data.Morpheus.Client.Internal.Types
   ( ClientConstructorDefinition (..),
@@ -69,21 +71,45 @@
     cxt,
     instanceD,
     tupP,
-  )
+ )
+import Language.Haskell.TH.Syntax (Dec)
 import Relude hiding (toString)
 
-aesonDeclarations :: TypeKind -> [ClientTypeDefinition -> DecQ]
-aesonDeclarations KindEnum = [deriveFromJSON, deriveToJSON]
-aesonDeclarations KindScalar = deriveScalarJSON
-aesonDeclarations kind
-  | isResolverType kind = [deriveFromJSON]
-  | otherwise = [deriveToJSON]
+aesonDeclarations :: TypeKind -> ClientTypeDefinition -> Q [Dec]
+aesonDeclarations KindEnum clientDef = do
+    a <- deriveIfNotDefined deriveFromJSON ''FromJSON clientDef
+    b <- deriveIfNotDefined deriveToJSON ''ToJSON clientDef
+    pure (a <> b)
+aesonDeclarations KindScalar clientDef = deriveScalarJSON clientDef
+aesonDeclarations kind clientDef
+    | isResolverType kind = deriveIfNotDefined deriveFromJSON ''FromJSON clientDef
+    | otherwise = deriveIfNotDefined deriveToJSON ''ToJSON clientDef
 
+deriveIfNotDefined :: (ClientTypeDefinition -> Q Dec) -> Name -> ClientTypeDefinition -> Q [Dec]
+deriveIfNotDefined derivation typeClass clientDef = do
+    exists <- isTypeDeclared clientDef
+    if exists
+        then do
+            has <- hasInstance typeClass clientDef
+            if has
+                then pure []
+                else mkDerivation
+        else mkDerivation
+  where
+    mkDerivation :: Q [Dec]
+    mkDerivation = do
+        derived <- derivation clientDef
+        pure [derived]
+
+
 failure :: GQLError -> Q a
 failure = fail . show
 
-deriveScalarJSON :: [ClientTypeDefinition -> DecQ]
-deriveScalarJSON = [deriveScalarFromJSON, deriveScalarToJSON]
+deriveScalarJSON :: ClientTypeDefinition -> Q [Dec]
+deriveScalarJSON clientDef = do
+    a <- deriveIfNotDefined deriveScalarFromJSON ''FromJSON clientDef
+    b <- deriveIfNotDefined deriveScalarToJSON ''ToJSON clientDef
+    pure (a <> b)
 
 deriveScalarFromJSON :: ClientTypeDefinition -> DecQ
 deriveScalarFromJSON ClientTypeDefinition {clientTypeName} =
@@ -223,7 +249,7 @@
           body =
             pure $
               AppE
-                (VarE 'object)
+                (VarE 'omitNulls)
                 (mkFieldsE typename '(.=) cFields)
 deriveToJSON
   ClientTypeDefinition
@@ -235,3 +261,9 @@
     where
       typeDef = applyCons ''ToJSON [typename]
       body = [funDSimple 'toJSON [] (aesonToJSONEnumBody clientTypeName clientCons)]
+
+omitNulls :: [Pair] -> Value
+omitNulls = object . filter notNull
+  where
+    notNull (_, Null) = False
+    notNull _ = True
diff --git a/src/Data/Morpheus/Client/Declare/Client.hs b/src/Data/Morpheus/Client/Declare/Client.hs
--- a/src/Data/Morpheus/Client/Declare/Client.hs
+++ b/src/Data/Morpheus/Client/Declare/Client.hs
@@ -38,11 +38,10 @@
     <*> (concat <$> traverse declareType subTypes)
 
 declareType :: ClientTypeDefinition -> Q [Dec]
-declareType clientType@ClientTypeDefinition {clientKind} =
-  apply clientType (typeDeclarations clientKind <> aesonDeclarations clientKind)
-
-apply :: Applicative f => a -> [a -> f b] -> f [b]
-apply a = traverse (\f -> f a)
+declareType clientType@ClientTypeDefinition{clientKind} = do
+    types <- typeDeclarations clientKind clientType
+    instances <- aesonDeclarations clientKind clientType
+    pure (types <> instances)
 
 queryArgumentType :: Maybe ClientTypeDefinition -> (Type, Q [Dec])
 queryArgumentType Nothing = (toCon ("()" :: String), pure [])
diff --git a/src/Data/Morpheus/Client/Declare/Type.hs b/src/Data/Morpheus/Client/Declare/Type.hs
--- a/src/Data/Morpheus/Client/Declare/Type.hs
+++ b/src/Data/Morpheus/Client/Declare/Type.hs
@@ -34,10 +34,15 @@
   )
 import Language.Haskell.TH
 import Relude hiding (Type)
+import Data.Morpheus.Client.Internal.TH (isTypeDeclared)
 
-typeDeclarations :: TypeKind -> [ClientTypeDefinition -> Q Dec]
-typeDeclarations KindScalar = []
-typeDeclarations _ = [pure . declareType]
+typeDeclarations :: TypeKind -> ClientTypeDefinition -> Q [Dec]
+typeDeclarations KindScalar _ = pure []
+typeDeclarations _ c = do
+    exists <- isTypeDeclared c
+    if exists
+        then pure []
+        else pure [declareType c]
 
 declareType :: ClientTypeDefinition -> Dec
 declareType
diff --git a/src/Data/Morpheus/Client/Internal/TH.hs b/src/Data/Morpheus/Client/Internal/TH.hs
--- a/src/Data/Morpheus/Client/Internal/TH.hs
+++ b/src/Data/Morpheus/Client/Internal/TH.hs
@@ -17,12 +17,16 @@
     mkFieldsE,
     destructRecord,
     failExp,
+    isTypeDeclared,
+    hasInstance,
   )
 where
 
 import Data.Foldable (foldr1)
+import Data.Morpheus.Client.Internal.Types (ClientTypeDefinition (..), TypeNameTH (..))
 import Data.Morpheus.CodeGen.Internal.TH
   ( camelCaseFieldName,
+    camelCaseTypeName,
     toCon,
     toName,
     toString,
@@ -117,3 +121,21 @@
 destructRecord conName fields = conP (toName conName) (vars names)
   where
     names = map (camelCaseFieldName conName . fieldName) fields
+
+isTypeDeclared :: ClientTypeDefinition -> Q Bool
+isTypeDeclared clientDef = do
+    let name = mkTypeName clientDef
+    m <- lookupTypeName (show name)
+    case m of
+        Nothing -> pure False
+        _ -> pure True
+
+hasInstance :: Name -> ClientTypeDefinition -> Q Bool
+hasInstance typeClass clientDef = do
+    isInstance typeClass [ConT (mkTypeName clientDef)]
+
+mkTypeName :: ClientTypeDefinition -> Name
+mkTypeName ClientTypeDefinition{clientTypeName = TypeNameTH namespace typeName} =
+    toType typeName
+  where
+    toType = toName . camelCaseTypeName namespace
