diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Morpheus GraphQL [![Hackage](https://img.shields.io/hackage/v/morpheus-graphql.svg)](https://hackage.haskell.org/package/morpheus-graphql) [![CircleCI](https://circleci.com/gh/morpheusgraphql/morpheus-graphql.svg?style=svg)](https://circleci.com/gh/morpheusgraphql/morpheus-graphql)
+# Morpheus GraphQL [![Hackage](https://img.shields.io/hackage/v/morpheus-graphql.svg)](https://hackage.haskell.org/package/morpheus-graphql) ![CI](https://github.com/morpheusgraphql/morpheus-graphql/workflows/CI/badge.svg)
 
 Build GraphQL APIs with your favourite functional language!
 
@@ -26,10 +26,10 @@
 _stack.yml_
 
 ```yaml
-resolver: lts-14.8
+resolver: lts-15.13
 
 extra-deps:
-  - morpheus-graphql-0.12.0
+  - morpheus-graphql-0.13.0
 ```
 
 As Morpheus is quite new, make sure stack can find morpheus-graphql by running `stack upgrade` and `stack update`
@@ -42,7 +42,7 @@
 
 ```gql
 type Query {
-  deity(name: String!): Deity!
+  deity(name: String! = "Morpheus"): Deity!
 }
 
 """
@@ -76,14 +76,14 @@
 
 import           Data.Morpheus              (interpreter)
 import           Data.Morpheus.Document     (importGQLDocumentWithNamespace)
-import           Data.Morpheus.Types        (GQLRootResolver (..), ResolverQ, Undefined(..))
+import           Data.Morpheus.Types        (RootResolver (..), ResolverQ, Undefined(..))
 import           Data.Text                  (Text)
 
 importGQLDocumentWithNamespace "schema.gql"
 
-rootResolver :: GQLRootResolver IO () Query Undefined Undefined
+rootResolver :: RootResolver IO () Query Undefined Undefined
 rootResolver =
-  GQLRootResolver
+  RootResolver
     {
       queryResolver = Query {queryDeity},
       mutationResolver = Undefined,
@@ -150,12 +150,12 @@
 askDB = ...
 ```
 
-To make this `Query` type available as an API, we define a `GQLRootResolver` and feed it to the Morpheus `interpreter`. A `GQLRootResolver` consists of `query`, `mutation` and `subscription` definitions, while we omit the latter for this example:
+To make this `Query` type available as an API, we define a `RootResolver` and feed it to the Morpheus `interpreter`. A `RootResolver` consists of `query`, `mutation` and `subscription` definitions, while we omit the latter for this example:
 
 ```haskell
-rootResolver :: GQLRootResolver IO () Query Undefined Undefined
+rootResolver :: RootResolver IO () Query Undefined Undefined
 rootResolver =
-  GQLRootResolver
+  RootResolver
     { queryResolver = Query {deity = resolveDeity}
     , mutationResolver = Undefined
     , subscriptionResolver = Undefined
@@ -259,7 +259,6 @@
   | CharacterInt
   | SomeMutli
   | CharacterEnumObject # no-argument constructors all wrapped into an enum
-
 type Creature {
   creatureName: String!
   creatureAge: Int!
@@ -313,7 +312,6 @@
 You will get the following schema:
 
 ```gql
-
 # has wrapper types
 union WrappedNode = WrappedSong | WrappedSkit
 
@@ -337,7 +335,6 @@
   skitDuration: Float!
   skitName: String!
 }
-
 ```
 
 - for all other unions will be generated new object type. for types without record syntax, fields will be automatally indexed.
@@ -417,9 +414,9 @@
   { createDeity :: MutArgs -> m Deity
   } deriving (Generic, GQLType)
 
-rootResolver :: GQLRootResolver IO  () Query Mutation Undefined
+rootResolver :: RootResolver IO  () Query Mutation Undefined
 rootResolver =
-  GQLRootResolver
+  RootResolver
     { queryResolver = Query {...}
     , mutationResolver = Mutation { createDeity }
     , subscriptionResolver = Undefined
@@ -465,8 +462,8 @@
 
 type APIEvent = Event Channel Content
 
-rootResolver :: GQLRootResolver IO APIEvent Query Mutation Subscription
-rootResolver = GQLRootResolver
+rootResolver :: RootResolver IO APIEvent Query Mutation Subscription
+rootResolver = RootResolver
   { queryResolver        = Query { deity = fetchDeity }
   , mutationResolver     = Mutation { createDeity }
   , subscriptionResolver = Subscription { newDeity }
@@ -488,33 +485,33 @@
 ```
 
 ### Interface
-  
+
 1. defining interface with Haskell Types (runtime validation):
-  
-    ```hs
-      -- interface is just regular type derived as interface
-    newtype Person m = Person {name ::  m Text}
-      deriving (Generic)
 
-    instance GQLType (Person m) where
-      type KIND (Person m) = INTERFACE
+   ```haskell
+     -- interface is just regular type derived as interface
+   newtype Person m = Person {name ::  m Text}
+     deriving (Generic)
 
-    -- with GQLType user can links interfaces to implementing object
-    instance GQLType Deity where
-      implements _ = [interface (Proxy @Person)]
-    ```
+   instance GQLType (Person m) where
+     type KIND (Person m) = INTERFACE
 
+   -- with GQLType user can links interfaces to implementing object
+   instance GQLType Deity where
+     implements _ = [interface (Proxy @Person)]
+   ```
+
 2. defining with `importGQLDocument` and `DSL` (compile time validation):
 
-    ```gql
-      interface Account {
-        name: String!
-      }
+   ```graphql
+   interface Account {
+     name: String!
+   }
 
-      type User implements Account {
-        name: String!
-      }
-    ```
+   type User implements Account {
+     name: String!
+   }
+   ```
 
 ## Morpheus `GraphQL Client` with Template haskell QuasiQuotes
 
@@ -583,11 +580,11 @@
   | PowerOmniscience
 
 data GetHeroArgs = GetHeroArgs {
-  getHeroArgsCharacter: Character
+  character: Character
 }
 
 data Character = Character {
-  characterName: Person
+  name: Person
 }
 ```
 
@@ -599,7 +596,7 @@
   fetchHero :: Args GetHero -> m (Either String GetHero)
   fetchHero = fetch jsonRes args
       where
-        args = GetHeroArgs {getHeroArgsCharacter = Person {characterName = "Zeus"}}
+        args = GetHeroArgs {character = Person {name = "Zeus"}}
         jsonRes :: ByteString -> m ByteString
         jsonRes = <GraphQL APi>
 ```
@@ -643,7 +640,7 @@
 - https://github.com/dandoh/web-haskell
   - Modern webserver boilerplate in Haskell: Morpheus Graphql + Postgresql + Authentication + DB migration + Dotenv and more
 
-*Edit this section and send PR if you want to share your project*.
+_Edit this section and send PR if you want to share your project_.
 
 # About
 
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,16 @@
 # Changelog
 
+## 0.13.0 - Unreleased Changes
+
+### breaking changes
+
+- renamed `GQLRootResolver` -> `RootResolver`
+
+### new features
+
+- `importGQLDocument` automatically defines `GQLType` instances for scalar definitions
+- supports default values
+
 ## 0.12.0 - 21.05.2020
 
 ### Breaking Changes
@@ -7,6 +18,7 @@
 Package was extracted as:
 
 - `morpheus-graphql-core`: core components like: parser, validator, executor, utils.
+
   - Data.Morpheus.Core
   - Data.Morpheus.QuasiQuoter
   - Data.Morpheus.Error
@@ -18,6 +30,7 @@
   - Data.Morpheus.Types.IO
 
 - `morpheus-graphql-client`: lightweight version of morpheus client without server implementation
+
   - Data.Morpheus.Client
 
 - `morpheus-graphql`: morpheus graphql server
@@ -60,11 +73,11 @@
 
 - flexible compsed Resolver Type alias: `ComposedResolver`. extends `ResolverO` with
   parameter `(f :: * -> *)`. so that you can compose Resolvers e.g:
-  
+
   ```hs
   resolveList :: ComposedResolver o EVENT IO [] Object
   -- is alias to: Resolver o () IO [Object (Resolver o () IO))]
-  
+
   resolveList :: ComposedResolver o EVENT IO Maybe Int
   -- is alias to: Resolver o () IO (Maybe Int)
   ```
@@ -90,22 +103,24 @@
 - Client generated enum data constructors are now prefixed with with the type name to avoid name conflicts.
 - for Variant selection inputUnion uses `inputname` insead of `__typename`
 
-- in `Data.Morpheus.Server`  
+- in `Data.Morpheus.Server`
+
   - `gqlSocketApp` and `gqlSocketMonadIOApp` are replaced with `webSocketsApp`
   - removed `initGQLState`, `GQLState`
 
 - for better control of subscriptions
-  - replaced instance  `interpreter gqlRoot state` with
+
+  - replaced instance `interpreter gqlRoot state` with
     `interpreter gqlRoot`.
   - added: `Input`, `Stream`, `httpPubApp`
-  
+
   from now on you can define API that can be
   used in websockets as well as in http servers
 
   ```hs
   api :: Input api -> Stream api EVENT IO
   api = interpreter gqlRoot
-  
+
   server :: IO ()
   server = do
     (wsApp, publish) <- webSocketsApp api
@@ -113,10 +128,10 @@
     ...
     runBoth wsApp httpApp
   ```
-  
+
   where `publish :: e -> m ()`
 
-  websockets and http app do not have to be on the same server. 
+  websockets and http app do not have to be on the same server.
   e.g. you can pass events between servers with webhooks.
 
 - subscription can select only one top level field (based on the GraphQL specification).
@@ -131,7 +146,7 @@
 ### minor
 
 - changes to internal types
-- fixed validation of apollo websockets requests  
+- fixed validation of apollo websockets requests
 
 ## 0.10.0 - 07.01.2020
 
diff --git a/morpheus-graphql.cabal b/morpheus-graphql.cabal
--- a/morpheus-graphql.cabal
+++ b/morpheus-graphql.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: c98d51df8567b3a33a0b9f3dcf93217534d9f3a1d666f1ac2ab69b5ce6cfe0b6
+-- hash: 55c61a113411654d318235d761f68f5115a1c3ffcd5f287c90ddfcc38b9fd393
 
 name:           morpheus-graphql
-version:        0.12.0
+version:        0.13.0
 synopsis:       Morpheus GraphQL
 description:    Build GraphQL APIs with your favourite functional language!
 category:       web, graphql
@@ -108,6 +108,12 @@
     test/Feature/Holistic/selection/subscription/singleTopLevelField/fail/query.gql
     test/Feature/Holistic/selection/subscription/singleTopLevelField/failAnonymous/query.gql
     test/Feature/Holistic/selection/unknownField/query.gql
+    test/Feature/Input/DefaultValue/intorspection/arguments/query.gql
+    test/Feature/Input/DefaultValue/intorspection/input-compound/query.gql
+    test/Feature/Input/DefaultValue/intorspection/input-simple/query.gql
+    test/Feature/Input/DefaultValue/resolving/compound/query.gql
+    test/Feature/Input/DefaultValue/resolving/simple/query.gql
+    test/Feature/Input/DefaultValue/schema.gql
     test/Feature/Input/Enum/decode2Con/query.gql
     test/Feature/Input/Enum/decode3Con/query.gql
     test/Feature/Input/Enum/decodeInvalidValue/query.gql
@@ -118,6 +124,10 @@
     test/Feature/Input/Enum/decodeMany/con4/query.gql
     test/Feature/Input/Enum/decodeMany/con5/query.gql
     test/Feature/Input/Enum/decodeMany/con6/query.gql
+    test/Feature/Input/Enum/invalidEnumFromJSONVariable/query.gql
+    test/Feature/Input/Enum/invalidStringDefaultValue/query.gql
+    test/Feature/Input/Enum/invalidStringInput/query.gql
+    test/Feature/Input/Enum/validEnumFromJSONVariable/query.gql
     test/Feature/Input/Object/nullableUndefinedField/query.gql
     test/Feature/Input/Object/resolveObject/query.gql
     test/Feature/Input/Object/resolveVariable/query.gql
@@ -261,6 +271,12 @@
     test/Feature/Holistic/selection/subscription/singleTopLevelField/fail/response.json
     test/Feature/Holistic/selection/subscription/singleTopLevelField/failAnonymous/response.json
     test/Feature/Holistic/selection/unknownField/response.json
+    test/Feature/Input/DefaultValue/cases.json
+    test/Feature/Input/DefaultValue/intorspection/arguments/response.json
+    test/Feature/Input/DefaultValue/intorspection/input-compound/response.json
+    test/Feature/Input/DefaultValue/intorspection/input-simple/response.json
+    test/Feature/Input/DefaultValue/resolving/compound/response.json
+    test/Feature/Input/DefaultValue/resolving/simple/response.json
     test/Feature/Input/Enum/cases.json
     test/Feature/Input/Enum/decode2Con/response.json
     test/Feature/Input/Enum/decode3Con/response.json
@@ -272,6 +288,12 @@
     test/Feature/Input/Enum/decodeMany/con4/response.json
     test/Feature/Input/Enum/decodeMany/con5/response.json
     test/Feature/Input/Enum/decodeMany/con6/response.json
+    test/Feature/Input/Enum/invalidEnumFromJSONVariable/response.json
+    test/Feature/Input/Enum/invalidEnumFromJSONVariable/variables.json
+    test/Feature/Input/Enum/invalidStringDefaultValue/response.json
+    test/Feature/Input/Enum/invalidStringInput/response.json
+    test/Feature/Input/Enum/validEnumFromJSONVariable/response.json
+    test/Feature/Input/Enum/validEnumFromJSONVariable/variables.json
     test/Feature/Input/Object/cases.json
     test/Feature/Input/Object/nullableUndefinedField/response.json
     test/Feature/Input/Object/resolveObject/response.json
@@ -368,17 +390,17 @@
       Data.Morpheus.Server.Deriving.Introspect
       Data.Morpheus.Server.Deriving.Resolve
       Data.Morpheus.Server.Deriving.Utils
-      Data.Morpheus.Server.Document.Compile
-      Data.Morpheus.Server.Document.Convert
-      Data.Morpheus.Server.Document.Declare
-      Data.Morpheus.Server.Document.Decode
-      Data.Morpheus.Server.Document.Encode
-      Data.Morpheus.Server.Document.GQLType
-      Data.Morpheus.Server.Document.Introspect
       Data.Morpheus.Server.Internal.TH.Decode
-      Data.Morpheus.Server.Types.GQLScalar
+      Data.Morpheus.Server.Internal.TH.Types
+      Data.Morpheus.Server.TH.Compile
+      Data.Morpheus.Server.TH.Declare
+      Data.Morpheus.Server.TH.Declare.Decode
+      Data.Morpheus.Server.TH.Declare.Encode
+      Data.Morpheus.Server.TH.Declare.GQLType
+      Data.Morpheus.Server.TH.Declare.Introspect
+      Data.Morpheus.Server.TH.Declare.Type
+      Data.Morpheus.Server.TH.Transform
       Data.Morpheus.Server.Types.GQLType
-      Data.Morpheus.Server.Types.ID
       Data.Morpheus.Server.Types.Types
       Data.Morpheus.Types.Internal.Subscription.Apollo
       Data.Morpheus.Types.Internal.Subscription.ClientConnectionStore
@@ -393,7 +415,7 @@
     , bytestring >=0.10.4 && <0.11
     , containers >=0.4.2.1 && <0.7
     , megaparsec >=7.0.0 && <9.0.0
-    , morpheus-graphql-core >=0.12.0
+    , morpheus-graphql-core >=0.13.0
     , mtl >=2.0 && <=3.0
     , scientific >=0.3.6.2 && <0.4
     , template-haskell >=2.0 && <=3.0
@@ -411,6 +433,7 @@
   main-is: Spec.hs
   other-modules:
       Feature.Holistic.API
+      Feature.Input.DefaultValue.API
       Feature.Input.Enum.API
       Feature.Input.Object.API
       Feature.Input.Scalar.API
@@ -441,7 +464,7 @@
     , containers >=0.4.2.1 && <0.7
     , megaparsec >=7.0.0 && <9.0.0
     , morpheus-graphql
-    , morpheus-graphql-core >=0.12.0
+    , morpheus-graphql-core >=0.13.0
     , mtl >=2.0 && <=3.0
     , scientific >=0.3.6.2 && <0.4
     , tasty
diff --git a/src/Data/Morpheus/Document.hs b/src/Data/Morpheus/Document.hs
--- a/src/Data/Morpheus/Document.hs
+++ b/src/Data/Morpheus/Document.hs
@@ -19,11 +19,11 @@
   ( RootResCon,
     fullSchema,
   )
-import Data.Morpheus.Server.Document.Compile
+import Data.Morpheus.Server.TH.Compile
   ( compileDocument,
     gqlDocument,
   )
-import Data.Morpheus.Types (GQLRootResolver)
+import Data.Morpheus.Types (RootResolver)
 import Data.Morpheus.Types.Internal.Resolving
   ( resultOr,
   )
@@ -40,10 +40,10 @@
 importGQLDocumentWithNamespace src =
   runIO (readFile src) >>= compileDocument True
 
--- | Generates schema.gql file from 'GQLRootResolver'
+-- | Generates schema.gql file from 'RootResolver'
 toGraphQLDocument ::
   RootResCon m event query mut sub =>
-  proxy (GQLRootResolver m event query mut sub) ->
+  proxy (RootResolver m event query mut sub) ->
   ByteString
 toGraphQLDocument =
   resultOr (pack . show) (encodeUtf8 . LT.fromStrict . render)
diff --git a/src/Data/Morpheus/Server/Deriving/Decode.hs b/src/Data/Morpheus/Server/Deriving/Decode.hs
--- a/src/Data/Morpheus/Server/Deriving/Decode.hs
+++ b/src/Data/Morpheus/Server/Deriving/Decode.hs
@@ -46,11 +46,11 @@
     withObject,
     withUnion,
   )
-import Data.Morpheus.Server.Types.GQLScalar
+import Data.Morpheus.Server.Types.GQLType (GQLType (KIND, __typeName))
+import Data.Morpheus.Types.GQLScalar
   ( GQLScalar (..),
     toScalar,
   )
-import Data.Morpheus.Server.Types.GQLType (GQLType (KIND, __typeName))
 import Data.Morpheus.Types.Internal.AST
   ( Argument (..),
     Arguments,
diff --git a/src/Data/Morpheus/Server/Deriving/Encode.hs b/src/Data/Morpheus/Server/Deriving/Encode.hs
--- a/src/Data/Morpheus/Server/Deriving/Encode.hs
+++ b/src/Data/Morpheus/Server/Deriving/Encode.hs
@@ -44,7 +44,6 @@
     datatypeNameProxy,
     isRecordProxy,
   )
-import Data.Morpheus.Server.Types.GQLScalar (GQLScalar (..))
 import Data.Morpheus.Server.Types.GQLType (GQLType (..))
 import Data.Morpheus.Server.Types.Types
   ( MapKind,
@@ -52,8 +51,9 @@
     mapKindFromList,
   )
 import Data.Morpheus.Types
-  ( GQLRootResolver (..),
+  ( RootResolver (..),
   )
+import Data.Morpheus.Types.GQLScalar (GQLScalar (..))
 import Data.Morpheus.Types.Internal.AST
   ( FieldName,
     FieldName (..),
@@ -238,10 +238,10 @@
     Applicative m,
     Monad m
   ) =>
-  GQLRootResolver m e query mut sub ->
+  RootResolver m e query mut sub ->
   RootResModel e m
 deriveModel
-  GQLRootResolver
+  RootResolver
     { queryResolver,
       mutationResolver,
       subscriptionResolver
diff --git a/src/Data/Morpheus/Server/Deriving/Interpreter.hs b/src/Data/Morpheus/Server/Deriving/Interpreter.hs
--- a/src/Data/Morpheus/Server/Deriving/Interpreter.hs
+++ b/src/Data/Morpheus/Server/Deriving/Interpreter.hs
@@ -16,7 +16,7 @@
     statelessResolver,
   )
 import Data.Morpheus.Types
-  ( GQLRootResolver (..),
+  ( RootResolver (..),
   )
 import Data.Morpheus.Types.IO
   ( GQLRequest,
@@ -50,7 +50,7 @@
   interpreter ::
     Monad m =>
     (RootResCon m e query mut sub) =>
-    GQLRootResolver m e query mut sub ->
+    RootResolver m e query mut sub ->
     a ->
     b
 
diff --git a/src/Data/Morpheus/Server/Deriving/Introspect.hs b/src/Data/Morpheus/Server/Deriving/Introspect.hs
--- a/src/Data/Morpheus/Server/Deriving/Introspect.hs
+++ b/src/Data/Morpheus/Server/Deriving/Introspect.hs
@@ -22,12 +22,14 @@
   ( TypeUpdater,
     Introspect (..),
     DeriveTypeContent (..),
+    introspectOUT,
     IntroCon,
     updateLib,
     buildType,
     introspectObjectFields,
     deriveCustomInputObjectType,
     TypeScope (..),
+    ProxyRep (..),
   )
 where
 
@@ -55,25 +57,24 @@
     isRecordProxy,
     selNameProxy,
   )
-import Data.Morpheus.Server.Types.GQLScalar (GQLScalar (..))
 import Data.Morpheus.Server.Types.GQLType (GQLType (..))
 import Data.Morpheus.Server.Types.Types
   ( MapKind,
     Pair,
   )
+import Data.Morpheus.Types.GQLScalar (GQLScalar (..))
 import Data.Morpheus.Types.Internal.AST
-  ( ANY,
-    ArgumentsDefinition (..),
+  ( ArgumentsDefinition (..),
     DataFingerprint (..),
     DataUnion,
     FALSE,
+    FieldContent (..),
     FieldDefinition (..),
     FieldName,
     FieldName (..),
     FieldsDefinition,
     IN,
     Message,
-    Meta (..),
     OUT,
     TRUE,
     TypeCategory,
@@ -82,13 +83,14 @@
     TypeName (..),
     TypeRef (..),
     TypeUpdater,
+    UnionMember (..),
     createAlias,
     createEnumValue,
     defineType,
     fieldsToArguments,
+    mkField,
+    mkUnionMember,
     msg,
-    toAny,
-    toAny,
     toListField,
     toNullableField,
     unsafeFromFields,
@@ -107,83 +109,90 @@
   )
 import GHC.Generics
 
-type IntroCon a = (GQLType a, DeriveTypeContent (CUSTOM a) a)
+type IntroCon a = (GQLType a, DeriveTypeContent OUT (CUSTOM a) a)
 
+data ProxyRep (cat :: TypeCategory) a
+  = ProxyRep
+
+introspectOUT :: forall a. (GQLType a, Introspect OUT a) => Proxy a -> TypeUpdater
+introspectOUT _ = introspect (ProxyRep :: ProxyRep OUT a)
+
+instance {-# OVERLAPPABLE #-} (GQLType a, IntrospectKind (KIND a) a) => Introspect cat a where
+  introspect _ = introspectKind (Context :: Context (KIND a) a)
+
 -- |  Generates internal GraphQL Schema for query validation and introspection rendering
-class Introspect a where
-  isObject :: proxy a -> Bool
-  default isObject :: GQLType a => proxy a -> Bool
+class Introspect (cat :: TypeCategory) a where
+  introspect :: proxy cat a -> TypeUpdater
+  isObject :: proxy cat a -> Bool
+  default isObject :: GQLType a => proxy cat a -> Bool
   isObject _ = isObjectKind (Proxy @a)
-  field :: proxy a -> FieldName -> FieldDefinition cat
-  introspect :: proxy a -> TypeUpdater
-
+  field :: proxy cat a -> FieldName -> FieldDefinition cat
   -----------------------------------------------
   default field ::
     GQLType a =>
-    proxy a ->
+    proxy cat a ->
     FieldName ->
     FieldDefinition cat
-  field _ = buildField (Proxy @a) NoArguments
-
-instance {-# OVERLAPPABLE #-} (GQLType a, IntrospectKind (KIND a) a) => Introspect a where
-  introspect _ = introspectKind (Context :: Context (KIND a) a)
+  field _ = buildField (Proxy @a) Nothing
 
 -- Maybe
-instance Introspect a => Introspect (Maybe a) where
+instance Introspect cat a => Introspect cat (Maybe a) where
   isObject _ = False
-  field _ = toNullableField . field (Proxy @a)
-  introspect _ = introspect (Proxy @a)
+  field _ = toNullableField . field (ProxyRep :: ProxyRep cat a)
+  introspect _ = introspect (ProxyRep :: ProxyRep cat a)
 
 -- List
-instance Introspect a => Introspect [a] where
+instance Introspect cat a => Introspect cat [a] where
   isObject _ = False
-  field _ = toListField . field (Proxy @a)
-  introspect _ = introspect (Proxy @a)
+  field _ = toListField . field (ProxyRep :: ProxyRep cat a)
+  introspect _ = introspect (ProxyRep :: ProxyRep cat a)
 
 -- Tuple
-instance Introspect (Pair k v) => Introspect (k, v) where
+instance Introspect cat (Pair k v) => Introspect cat (k, v) where
   isObject _ = True
-  field _ = field (Proxy @(Pair k v))
-  introspect _ = introspect (Proxy @(Pair k v))
+  field _ = field (ProxyRep :: ProxyRep cat (Pair k v))
+  introspect _ = introspect (ProxyRep :: ProxyRep cat (Pair k v))
 
 -- Set
-instance Introspect [a] => Introspect (Set a) where
+instance Introspect cat [a] => Introspect cat (Set a) where
   isObject _ = False
-  field _ = field (Proxy @[a])
-  introspect _ = introspect (Proxy @[a])
+  field _ = field (ProxyRep :: ProxyRep cat [a])
+  introspect _ = introspect (ProxyRep :: ProxyRep cat [a])
 
 -- Map
-instance Introspect (MapKind k v Maybe) => Introspect (Map k v) where
+instance Introspect cat (MapKind k v Maybe) => Introspect cat (Map k v) where
   isObject _ = True
-  field _ = field (Proxy @(MapKind k v Maybe))
-  introspect _ = introspect (Proxy @(MapKind k v Maybe))
+  field _ = field (ProxyRep :: ProxyRep cat (MapKind k v Maybe))
+  introspect _ = introspect (ProxyRep :: ProxyRep cat (MapKind k v Maybe))
 
 -- Resolver : a -> Resolver b
-instance (GQLType b, DeriveTypeContent 'False a, Introspect b) => Introspect (a -> m b) where
+instance (GQLType b, DeriveTypeContent IN 'False a, Introspect OUT b) => Introspect OUT (a -> m b) where
   isObject _ = False
-  field _ name = fieldObj {fieldArgs}
+  field _ name = fieldObj {fieldContent = Just (FieldArgs fieldArgs)}
     where
-      fieldObj = field (Proxy @b) name
+      fieldObj = field (ProxyRep :: ProxyRep OUT b) name
+      fieldArgs :: ArgumentsDefinition
       fieldArgs =
-        fieldsToArguments $ mockFieldsDefinition $ fst $
-          introspectObjectFields
+        fieldsToArguments
+          $ fst
+          $ introspectInputObjectFields
             (Proxy :: Proxy 'False)
-            (__typeName (Proxy @b), InputType, Proxy @a)
+            (__typeName (Proxy @b), Proxy @a)
   introspect _ typeLib =
     resolveUpdates
       typeLib
-      (introspect (Proxy @b) : inputs)
+      (introspect (ProxyRep :: ProxyRep OUT b) : inputs)
     where
       name = "Arguments for " <> __typeName (Proxy @b)
       inputs :: [TypeUpdater]
       inputs =
-        snd $ introspectObjectFields (Proxy :: Proxy 'False) (name, InputType, Proxy @a)
+        snd $ introspectInputObjectFields (Proxy :: Proxy 'False) (name, Proxy @a)
 
 --  GQL Resolver b, MUTATION, SUBSCRIPTION, QUERY
-instance (GQLType b, Introspect b) => Introspect (Resolver fo e m b) where
+instance (GQLType b, Introspect cat b) => Introspect cat (Resolver fo e m b) where
   isObject _ = False
-  field _ = field (Proxy @b)
-  introspect _ = introspect (Proxy @b)
+  field _ = field (ProxyRep :: ProxyRep cat b)
+  introspect _ = introspect (ProxyRep :: ProxyRep cat b)
 
 -- | Introspect With specific Kind: 'kind': object, scalar, enum ...
 class IntrospectKind (kind :: GQL_KIND) a where
@@ -202,24 +211,24 @@
       enumType =
         buildType $ DataEnum $ map (createEnumValue . TypeName) $ enumTags (Proxy @(Rep a))
 
-instance (GQL_TYPE a, DeriveTypeContent (CUSTOM a) a) => IntrospectKind INPUT a where
+instance (GQL_TYPE a, DeriveTypeContent IN (CUSTOM a) a) => IntrospectKind INPUT a where
   introspectKind _ = derivingData (Proxy @a) InputType
 
-instance (GQL_TYPE a, DeriveTypeContent (CUSTOM a) a) => IntrospectKind OUTPUT a where
+instance (GQL_TYPE a, DeriveTypeContent OUT (CUSTOM a) a) => IntrospectKind OUTPUT a where
   introspectKind _ = derivingData (Proxy @a) OutputType
 
-instance (GQL_TYPE a, DeriveTypeContent (CUSTOM a) a) => IntrospectKind INTERFACE a where
-  introspectKind _ = updateLib (buildType (DataInterface (mockFieldsDefinition fields) :: TypeContent TRUE OUT)) types (Proxy @a)
+instance (GQL_TYPE a, DeriveTypeContent OUT (CUSTOM a) a) => IntrospectKind INTERFACE a where
+  introspectKind _ = updateLibOUT (buildType (DataInterface fields)) types (Proxy @a)
     where
       (fields, types) =
         introspectObjectFields
           (Proxy @(CUSTOM a))
-          (baseName, OutputType, Proxy @a)
+          (baseName, Proxy @a)
       baseName = __typeName (Proxy @a)
 
 derivingData ::
   forall a cat.
-  (GQLType a, DeriveTypeContent (CUSTOM a) a) =>
+  (GQLType a, DeriveTypeContent cat (CUSTOM a) a) =>
   Proxy a ->
   TypeScope cat ->
   TypeUpdater
@@ -235,56 +244,65 @@
 type GQL_TYPE a = (Generic a, GQLType a)
 
 deriveCustomInputObjectType ::
-  DeriveTypeContent TRUE a =>
+  DeriveTypeContent IN TRUE a =>
   (TypeName, proxy a) ->
   TypeUpdater
 deriveCustomInputObjectType (name, proxy) =
   flip
     resolveUpdates
-    (deriveCustomObjectType (name, InputType, proxy))
+    (snd $ introspectInputObjectFields (Proxy :: Proxy TRUE) (name, proxy))
 
-deriveCustomObjectType ::
-  DeriveTypeContent TRUE a =>
-  (TypeName, TypeScope cat, proxy a) ->
-  [TypeUpdater]
-deriveCustomObjectType = snd . introspectObjectFields (Proxy :: Proxy TRUE)
+introspectInputObjectFields ::
+  DeriveTypeContent IN custom a =>
+  proxy1 (custom :: Bool) ->
+  (TypeName, proxy2 a) ->
+  (FieldsDefinition IN, [TypeUpdater])
+introspectInputObjectFields p1 (name, proxy) =
+  withObject (deriveTypeContent p1 (proxy, ([], []), InputType, "", DataFingerprint "" []))
+  where
+    withObject (DataInputObject {inputObjectFields}, ts) = (inputObjectFields, ts)
+    withObject _ = (empty, [introspectFailure (msg name <> " should have only one nonempty constructor")])
 
 introspectObjectFields ::
-  DeriveTypeContent custom a =>
+  DeriveTypeContent OUT custom a =>
   proxy1 (custom :: Bool) ->
-  (TypeName, TypeScope cat, proxy2 a) ->
-  (FieldsDefinition cat, [TypeUpdater])
-introspectObjectFields p1 (name, scope, proxy) =
-  withObject name (deriveTypeContent p1 (proxy, ([], []), scope, "", DataFingerprint "" []))
-
-withObject :: TypeName -> (TypeContent TRUE (cat :: TypeCategory), [TypeUpdater]) -> (FieldsDefinition cat2, [TypeUpdater])
-withObject _ (DataObject {objectFields}, ts) = (mockFieldsDefinition objectFields, ts)
-withObject _ (DataInputObject {inputObjectFields}, ts) = (mockFieldsDefinition inputObjectFields, ts)
-withObject name _ = (empty, [introspectFailure (msg name <> " should have only one nonempty constructor")])
+  (TypeName, proxy2 a) ->
+  (FieldsDefinition OUT, [TypeUpdater])
+introspectObjectFields p1 (name, proxy) =
+  withObject (deriveTypeContent p1 (proxy, ([], []), OutputType, "", DataFingerprint "" []))
+  where
+    withObject (DataObject {objectFields}, ts) = (objectFields, ts)
+    withObject _ = (empty, [introspectFailure (msg name <> " should have only one nonempty constructor")])
 
 introspectFailure :: Message -> TypeUpdater
 introspectFailure = const . failure . globalErrorMessage . ("invalid schema: " <>)
 
 -- Object Fields
-class DeriveTypeContent (custom :: Bool) a where
-  deriveTypeContent :: proxy1 custom -> (proxy2 a, ([TypeName], [TypeUpdater]), TypeScope cat, TypeName, DataFingerprint) -> (TypeContent TRUE ANY, [TypeUpdater])
+class DeriveTypeContent cat (custom :: Bool) a where
+  deriveTypeContent :: proxy1 custom -> (proxy2 a, ([TypeName], [TypeUpdater]), TypeScope cat, TypeName, DataFingerprint) -> (TypeContent TRUE cat, [TypeUpdater])
 
-instance (TypeRep (Rep a), Generic a) => DeriveTypeContent FALSE a where
+instance (TypeRep cat (Rep a), Generic a) => DeriveTypeContent cat FALSE a where
   deriveTypeContent _ (_, interfaces, scope, baseName, baseFingerprint) =
-    fa $ builder $ typeRep $ Proxy @(Rep a)
+    builder $ typeRep (ProxyRep :: ProxyRep cat (Rep a))
     where
-      fa (x, y) = (toAny x, y)
       builder [ConsRep {consFields}] = buildObject interfaces scope consFields
       builder cons = genericUnion scope cons
         where
           genericUnion InputType = buildInputUnion (baseName, baseFingerprint)
           genericUnion OutputType = buildUnionType (baseName, baseFingerprint) DataUnion (DataObject [])
 
-buildField :: GQLType a => Proxy a -> ArgumentsDefinition -> FieldName -> FieldDefinition cat
-buildField proxy fieldArgs fieldName =
+buildField ::
+  GQLType a =>
+  Proxy a ->
+  Maybe (FieldContent TRUE cat) ->
+  FieldName ->
+  FieldDefinition cat
+buildField proxy fieldContent fieldName =
   FieldDefinition
-    { fieldType = createAlias $ __typeName proxy,
-      fieldMeta = Nothing,
+    { fieldType = createAlias (__typeName proxy),
+      fieldDescription = Nothing,
+      fieldDirectives = empty,
+      fieldContent = fieldContent,
       ..
     }
 
@@ -293,12 +311,8 @@
   TypeDefinition
     { typeName = __typeName proxy,
       typeFingerprint = __typeFingerprint proxy,
-      typeMeta =
-        Just
-          Meta
-            { metaDescription = description proxy,
-              metaDirectives = []
-            },
+      typeDescription = description proxy,
+      typeDirectives = [],
       typeContent
     }
 
@@ -310,37 +324,45 @@
   TypeUpdater
 updateLib f stack proxy = updateSchema (__typeName proxy) (__typeFingerprint proxy) stack f proxy
 
+updateLibOUT ::
+  GQLType a =>
+  (Proxy a -> TypeDefinition OUT) ->
+  [TypeUpdater] ->
+  Proxy a ->
+  TypeUpdater
+updateLibOUT f stack proxy = updateSchema (__typeName proxy) (__typeFingerprint proxy) stack f proxy
+
 -- NEW AUTOMATIC DERIVATION SYSTEM
 
-data ConsRep = ConsRep
+data ConsRep cat = ConsRep
   { consName :: TypeName,
     consIsRecord :: Bool,
-    consFields :: [FieldRep]
+    consFields :: [FieldRep cat]
   }
 
-data FieldRep = FieldRep
+data FieldRep cat = FieldRep
   { fieldTypeName :: TypeName,
-    fieldData :: FieldDefinition ANY,
+    fieldData :: FieldDefinition cat,
     fieldTypeUpdater :: TypeUpdater,
     fieldIsObject :: Bool
   }
 
-data ResRep = ResRep
+data ResRep cat = ResRep
   { enumCons :: [TypeName],
     unionRef :: [TypeName],
-    unionRecordRep :: [ConsRep]
+    unionRecordRep :: [ConsRep cat]
   }
 
-isEmpty :: ConsRep -> Bool
+isEmpty :: ConsRep cat -> Bool
 isEmpty ConsRep {consFields = []} = True
 isEmpty _ = False
 
-isUnionRef :: TypeName -> ConsRep -> Bool
+isUnionRef :: TypeName -> ConsRep cat -> Bool
 isUnionRef baseName ConsRep {consName, consFields = [FieldRep {fieldIsObject = True, fieldTypeName}]} =
   consName == baseName <> fieldTypeName
 isUnionRef _ _ = False
 
-setFieldNames :: ConsRep -> ConsRep
+setFieldNames :: ConsRep cat -> ConsRep cat
 setFieldNames cons@ConsRep {consFields} =
   cons
     { consFields = zipWith setFieldName ([0 ..] :: [Int]) consFields
@@ -350,7 +372,7 @@
       where
         fieldName = FieldName ("_" <> pack (show i))
 
-analyseRep :: TypeName -> [ConsRep] -> ResRep
+analyseRep :: TypeName -> [ConsRep cat] -> ResRep cat
 analyseRep baseName cons =
   ResRep
     { enumCons = map consName enumRep,
@@ -363,20 +385,19 @@
     (unionRecordRep, anyonimousUnionRep) = partition consIsRecord left2
 
 buildInputUnion ::
-  (TypeName, DataFingerprint) -> [ConsRep] -> (TypeContent TRUE IN, [TypeUpdater])
+  (TypeName, DataFingerprint) -> [ConsRep IN] -> (TypeContent TRUE IN, [TypeUpdater])
 buildInputUnion (baseName, baseFingerprint) cons =
   datatype
     (analyseRep baseName cons)
   where
-    datatype :: ResRep -> (TypeContent TRUE IN, [TypeUpdater])
+    datatype :: ResRep IN -> (TypeContent TRUE IN, [TypeUpdater])
     datatype ResRep {unionRef = [], unionRecordRep = [], enumCons} =
       (DataEnum (map createEnumValue enumCons), types)
     datatype ResRep {unionRef, unionRecordRep, enumCons} =
       (DataInputUnion typeMembers, types <> unionTypes)
       where
-        typeMembers :: [(TypeName, Bool)]
-        typeMembers =
-          map (,True) (unionRef <> unionMembers) <> map (,False) enumCons
+        typeMembers :: [UnionMember IN]
+        typeMembers = map mkUnionMember (unionRef <> unionMembers) <> map (`UnionMember` False) enumCons
         (unionMembers, unionTypes) =
           buildUnions wrapInputObject baseFingerprint unionRecordRep
     types = map fieldTypeUpdater $ concatMap consFields cons
@@ -387,7 +408,7 @@
   (TypeName, DataFingerprint) ->
   (DataUnion -> TypeContent TRUE cat) ->
   (FieldsDefinition cat -> TypeContent TRUE cat) ->
-  [ConsRep] ->
+  [ConsRep cat] ->
   (TypeContent TRUE cat, [TypeUpdater])
 buildUnionType (baseName, baseFingerprint) wrapUnion wrapObject cons =
   datatype
@@ -397,7 +418,7 @@
     datatype ResRep {unionRef = [], unionRecordRep = [], enumCons} =
       (DataEnum (map createEnumValue enumCons), types)
     datatype ResRep {unionRef, unionRecordRep, enumCons} =
-      (wrapUnion typeMembers, types <> enumTypes <> unionTypes)
+      (wrapUnion (map mkUnionMember typeMembers), types <> enumTypes <> unionTypes)
       where
         typeMembers = unionRef <> enumMembers <> unionMembers
         (enumMembers, enumTypes) =
@@ -406,9 +427,9 @@
           buildUnions wrapObject baseFingerprint unionRecordRep
     types = map fieldTypeUpdater $ concatMap consFields cons
 
-buildObject :: ([TypeName], [TypeUpdater]) -> TypeScope cat -> [FieldRep] -> (TypeContent TRUE cat, [TypeUpdater])
+buildObject :: ([TypeName], [TypeUpdater]) -> TypeScope cat -> [FieldRep cat] -> (TypeContent TRUE cat, [TypeUpdater])
 buildObject (interfaces, interfaceTypes) scope consFields =
-  ( wrapWith scope (mockFieldsDefinition fields),
+  ( wrapWith scope fields,
     types <> interfaceTypes
   )
   where
@@ -418,7 +439,7 @@
     wrapWith InputType = DataInputObject
     wrapWith OutputType = DataObject interfaces
 
-buildDataObject :: [FieldRep] -> (FieldsDefinition ANY, [TypeUpdater])
+buildDataObject :: [FieldRep cat] -> (FieldsDefinition cat, [TypeUpdater])
 buildDataObject consFields = (fields, types)
   where
     fields = unsafeFromFields $ map fieldData consFields
@@ -427,7 +448,7 @@
 buildUnions ::
   (FieldsDefinition cat -> TypeContent TRUE cat) ->
   DataFingerprint ->
-  [ConsRep] ->
+  [ConsRep cat] ->
   ([TypeName], [TypeUpdater])
 buildUnions wrapObject baseFingerprint cons = (members, map buildURecType cons)
   where
@@ -437,22 +458,16 @@
           (buildUnionRecord wrapObject baseFingerprint consRep)
     members = map consName cons
 
-mockFieldsDefinition :: FieldsDefinition a -> FieldsDefinition b
-mockFieldsDefinition = fmap mockFieldDefinition
-
-mockFieldDefinition :: FieldDefinition a -> FieldDefinition b
-mockFieldDefinition FieldDefinition {..} = FieldDefinition {..}
-
 buildUnionRecord ::
-  (FieldsDefinition cat -> TypeContent TRUE cat) -> DataFingerprint -> ConsRep -> TypeDefinition cat
+  (FieldsDefinition cat -> TypeContent TRUE cat) -> DataFingerprint -> ConsRep cat -> TypeDefinition cat
 buildUnionRecord wrapObject typeFingerprint ConsRep {consName, consFields} =
   TypeDefinition
     { typeName = consName,
       typeFingerprint,
-      typeMeta = Nothing,
+      typeDescription = Nothing,
+      typeDirectives = empty,
       typeContent =
         wrapObject
-          $ mockFieldsDefinition
           $ unsafeFromFields
           $ map fieldData consFields
     }
@@ -489,7 +504,8 @@
   pure
     . defineType
       TypeDefinition
-        { typeMeta = Nothing,
+        { typeDescription = Nothing,
+          typeDirectives = empty,
           typeContent = DataEnum $ map createEnumValue tags,
           ..
         }
@@ -506,16 +522,12 @@
       TypeDefinition
         { typeName,
           typeFingerprint,
-          typeMeta = Nothing,
+          typeDescription = Nothing,
+          typeDirectives = empty,
           typeContent =
             wrapObject $
               singleton
-                FieldDefinition
-                  { fieldName = "enum",
-                    fieldArgs = NoArguments,
-                    fieldType = createAlias enumTypeName,
-                    fieldMeta = Nothing
-                  }
+                (mkField "enum" ([], enumTypeName))
         }
 
 data TypeScope (cat :: TypeCategory) where
@@ -529,44 +541,44 @@
 deriving instance Ord (TypeScope cat)
 
 --  GENERIC UNION
-class TypeRep f where
-  typeRep :: Proxy f -> [ConsRep]
+class TypeRep (cat :: TypeCategory) f where
+  typeRep :: ProxyRep cat f -> [ConsRep cat]
 
-instance TypeRep f => TypeRep (M1 D d f) where
-  typeRep _ = typeRep (Proxy @f)
+instance TypeRep cat f => TypeRep cat (M1 D d f) where
+  typeRep _ = typeRep (ProxyRep :: ProxyRep cat f)
 
 -- | recursion for Object types, both of them : 'INPUT_OBJECT' and 'OBJECT'
-instance (TypeRep a, TypeRep b) => TypeRep (a :+: b) where
-  typeRep _ = typeRep (Proxy @a) <> typeRep (Proxy @b)
+instance (TypeRep cat a, TypeRep cat b) => TypeRep cat (a :+: b) where
+  typeRep _ = typeRep (ProxyRep :: ProxyRep cat a) <> typeRep (ProxyRep :: ProxyRep cat b)
 
-instance (ConRep f, Constructor c) => TypeRep (M1 C c f) where
+instance (ConRep cat f, Constructor c) => TypeRep cat (M1 C c f) where
   typeRep _ =
     [ ConsRep
         { consName = conNameProxy (Proxy @c),
-          consFields = conRep (Proxy @f),
+          consFields = conRep (ProxyRep :: ProxyRep cat f),
           consIsRecord = isRecordProxy (Proxy @c)
         }
     ]
 
-class ConRep f where
-  conRep :: Proxy f -> [FieldRep]
+class ConRep cat f where
+  conRep :: ProxyRep cat f -> [FieldRep cat]
 
 -- | recursion for Object types, both of them : 'UNION' and 'INPUT_UNION'
-instance (ConRep a, ConRep b) => ConRep (a :*: b) where
-  conRep _ = conRep (Proxy @a) <> conRep (Proxy @b)
+instance (ConRep cat a, ConRep cat b) => ConRep cat (a :*: b) where
+  conRep _ = conRep (ProxyRep :: ProxyRep cat a) <> conRep (ProxyRep :: ProxyRep cat b)
 
-instance (Selector s, Introspect a) => ConRep (M1 S s (Rec0 a)) where
+instance (Selector s, Introspect cat a) => ConRep cat (M1 S s (Rec0 a)) where
   conRep _ =
     [ FieldRep
         { fieldTypeName = typeConName $ fieldType fieldData,
           fieldData = fieldData,
-          fieldTypeUpdater = introspect (Proxy @a),
-          fieldIsObject = isObject (Proxy @a)
+          fieldTypeUpdater = introspect (ProxyRep :: ProxyRep cat a),
+          fieldIsObject = isObject (ProxyRep :: ProxyRep cat a)
         }
     ]
     where
       name = selNameProxy (Proxy @s)
-      fieldData = field (Proxy @a) name
+      fieldData = field (ProxyRep :: ProxyRep cat a) name
 
-instance ConRep U1 where
+instance ConRep cat U1 where
   conRep _ = []
diff --git a/src/Data/Morpheus/Server/Deriving/Resolve.hs b/src/Data/Morpheus/Server/Deriving/Resolve.hs
--- a/src/Data/Morpheus/Server/Deriving/Resolve.hs
+++ b/src/Data/Morpheus/Server/Deriving/Resolve.hs
@@ -22,18 +22,20 @@
 import Data.Morpheus.Core
   ( runApi,
   )
+import Data.Morpheus.Internal.Utils
+  ( empty,
+  )
 import Data.Morpheus.Server.Deriving.Encode
   ( EncodeCon,
     deriveModel,
   )
 import Data.Morpheus.Server.Deriving.Introspect
   ( IntroCon,
-    TypeScope (..),
     introspectObjectFields,
   )
 import Data.Morpheus.Server.Types.GQLType (GQLType (CUSTOM))
 import Data.Morpheus.Types
-  ( GQLRootResolver (..),
+  ( RootResolver (..),
   )
 import Data.Morpheus.Types.IO
   ( GQLRequest (..),
@@ -90,7 +92,7 @@
 
 statelessResolver ::
   (Monad m, RootResCon m event query mut sub) =>
-  GQLRootResolver m event query mut sub ->
+  RootResolver m event query mut sub ->
   GQLRequest ->
   m GQLResponse
 statelessResolver root req =
@@ -99,7 +101,7 @@
 coreResolver ::
   forall event m query mut sub.
   (Monad m, RootResCon m event query mut sub) =>
-  GQLRootResolver m event query mut sub ->
+  RootResolver m event query mut sub ->
   GQLRequest ->
   ResponseStream event m ValidValue
 coreResolver root request =
@@ -115,7 +117,7 @@
 fullSchema ::
   forall proxy m event query mutation subscription.
   (IntrospectConstraint m event query mutation subscription) =>
-  proxy (GQLRootResolver m event query mutation subscription) ->
+  proxy (RootResolver m event query mutation subscription) ->
   Eventless Schema
 fullSchema _ = querySchema >>= mutationSchema >>= subscriptionSchema
   where
@@ -125,7 +127,7 @@
         (fields, types) =
           introspectObjectFields
             (Proxy @(CUSTOM (query (Resolver QUERY event m))))
-            ("type for query", OutputType, Proxy @(query (Resolver QUERY event m)))
+            ("type for query", Proxy @(query (Resolver QUERY event m)))
     ------------------------------
     mutationSchema lib =
       resolveUpdates
@@ -136,7 +138,6 @@
           introspectObjectFields
             (Proxy @(CUSTOM (mutation (Resolver MUTATION event m))))
             ( "type for mutation",
-              OutputType,
               Proxy @(mutation (Resolver MUTATION event m))
             )
     ------------------------------
@@ -149,7 +150,6 @@
           introspectObjectFields
             (Proxy @(CUSTOM (subscription (Resolver SUBSCRIPTION event m))))
             ( "type for subscription",
-              OutputType,
               Proxy @(subscription (Resolver SUBSCRIPTION event m))
             )
     maybeOperator :: FieldsDefinition OUT -> TypeName -> Maybe (TypeDefinition OUT)
@@ -163,5 +163,6 @@
         { typeContent = DataObject [] fields,
           typeName,
           typeFingerprint = DataFingerprint typeName [],
-          typeMeta = Nothing
+          typeDescription = Nothing,
+          typeDirectives = empty
         }
diff --git a/src/Data/Morpheus/Server/Document/Compile.hs b/src/Data/Morpheus/Server/Document/Compile.hs
deleted file mode 100644
--- a/src/Data/Morpheus/Server/Document/Compile.hs
+++ /dev/null
@@ -1,64 +0,0 @@
-{-# LANGUAGE NamedFieldPuns #-}
-
-module Data.Morpheus.Server.Document.Compile
-  ( compileDocument,
-    gqlDocument,
-    gqlDocumentNamespace,
-  )
-where
-
---
---  Morpheus
-
-import Data.Morpheus.Core
-  ( parseTypeDefinitions,
-  )
-import Data.Morpheus.Error
-  ( gqlWarnings,
-    renderGQLErrors,
-  )
-import Data.Morpheus.Server.Document.Convert
-  ( toTHDefinitions,
-  )
-import Data.Morpheus.Server.Document.Declare
-  ( declare,
-  )
-import Data.Morpheus.Types.Internal.Resolving
-  ( Result (..),
-  )
-import qualified Data.Text as T
-  ( pack,
-  )
-import Language.Haskell.TH
-import Language.Haskell.TH.Quote
-
-gqlDocumentNamespace :: QuasiQuoter
-gqlDocumentNamespace =
-  QuasiQuoter
-    { quoteExp = notHandled "Expressions",
-      quotePat = notHandled "Patterns",
-      quoteType = notHandled "Types",
-      quoteDec = compileDocument True
-    }
-  where
-    notHandled things =
-      error $ things ++ " are not supported by the GraphQL QuasiQuoter"
-
-gqlDocument :: QuasiQuoter
-gqlDocument =
-  QuasiQuoter
-    { quoteExp = notHandled "Expressions",
-      quotePat = notHandled "Patterns",
-      quoteType = notHandled "Types",
-      quoteDec = compileDocument False
-    }
-  where
-    notHandled things =
-      error $ things ++ " are not supported by the GraphQL QuasiQuoter"
-
-compileDocument :: Bool -> String -> Q [Dec]
-compileDocument namespace documentTXT =
-  case parseTypeDefinitions (T.pack documentTXT) of
-    Failure errors -> fail (renderGQLErrors errors)
-    Success {result = schema, warnings} ->
-      gqlWarnings warnings >> toTHDefinitions namespace schema >>= declare namespace
diff --git a/src/Data/Morpheus/Server/Document/Convert.hs b/src/Data/Morpheus/Server/Document/Convert.hs
deleted file mode 100644
--- a/src/Data/Morpheus/Server/Document/Convert.hs
+++ /dev/null
@@ -1,205 +0,0 @@
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE GADTs #-}
-{-# LANGUAGE NamedFieldPuns #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE RecordWildCards #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TypeOperators #-}
-
-module Data.Morpheus.Server.Document.Convert
-  ( toTHDefinitions,
-  )
-where
-
--- MORPHEUS
-import Data.Morpheus.Internal.TH
-  ( infoTyVars,
-    mkTypeName,
-  )
-import Data.Morpheus.Internal.Utils
-  ( capitalTypeName,
-    elems,
-    singleton,
-  )
-import Data.Morpheus.Types.Internal.AST
-  ( ANY,
-    ArgumentsDefinition (..),
-    ConsD,
-    DataTypeKind (..),
-    FieldDefinition (..),
-    FieldName,
-    FieldsDefinition,
-    GQLTypeD (..),
-    OUT,
-    TRUE,
-    TypeContent (..),
-    TypeD (..),
-    TypeDefinition (..),
-    TypeName,
-    TypeRef (..),
-    argumentsToFields,
-    hasArguments,
-    hsTypeName,
-    kindOf,
-    lookupWith,
-    mkCons,
-    mkConsEnum,
-    toFieldName,
-  )
-import Data.Semigroup ((<>))
-import Language.Haskell.TH
-
-m_ :: TypeName
-m_ = "m"
-
-getTypeArgs :: TypeName -> [TypeDefinition ANY] -> Q (Maybe TypeName)
-getTypeArgs "__TypeKind" _ = pure Nothing
-getTypeArgs "Boolean" _ = pure Nothing
-getTypeArgs "String" _ = pure Nothing
-getTypeArgs "Int" _ = pure Nothing
-getTypeArgs "Float" _ = pure Nothing
-getTypeArgs key lib = case typeContent <$> lookupWith typeName key lib of
-  Just x -> pure (kindToTyArgs x)
-  Nothing -> getTyArgs <$> reify (mkTypeName key)
-
-getTyArgs :: Info -> Maybe TypeName
-getTyArgs x
-  | null (infoTyVars x) = Nothing
-  | otherwise = Just m_
-
-kindToTyArgs :: TypeContent TRUE ANY -> Maybe TypeName
-kindToTyArgs DataObject {} = Just m_
-kindToTyArgs DataUnion {} = Just m_
-kindToTyArgs DataInterface {} = Just m_
-kindToTyArgs _ = Nothing
-
-toTHDefinitions :: Bool -> [TypeDefinition ANY] -> Q [GQLTypeD]
-toTHDefinitions namespace lib = traverse renderTHType lib
-  where
-    renderTHType :: TypeDefinition ANY -> Q GQLTypeD
-    renderTHType x = generateType x
-      where
-        genArgsTypeName :: FieldName -> TypeName
-        genArgsTypeName fieldName
-          | namespace = hsTypeName (typeName x) <> argTName
-          | otherwise = argTName
-          where
-            argTName = capitalTypeName (fieldName <> "Args")
-        ---------------------------------------------------------------------------------------------
-        genResField :: FieldDefinition OUT -> Q (FieldDefinition OUT)
-        genResField field@FieldDefinition {fieldName, fieldArgs, fieldType = typeRef@TypeRef {typeConName}} =
-          do
-            typeArgs <- getTypeArgs typeConName lib
-            pure $
-              field
-                { fieldType = typeRef {typeConName = hsTypeName typeConName, typeArgs},
-                  fieldArgs = fieldArguments
-                }
-          where
-            fieldArguments
-              | hasArguments fieldArgs = fieldArgs {argumentsTypename = Just $ genArgsTypeName fieldName}
-              | otherwise = fieldArgs
-        --------------------------------------------
-        generateType :: TypeDefinition ANY -> Q GQLTypeD
-        generateType typeOriginal@TypeDefinition {typeName, typeContent, typeMeta} =
-          genType
-            typeContent
-          where
-            buildType :: [ConsD] -> TypeD
-            buildType tCons =
-              TypeD
-                { tName = hsTypeName typeName,
-                  tMeta = typeMeta,
-                  tNamespace = [],
-                  tCons,
-                  tKind
-                }
-            buildObjectCons :: FieldsDefinition cat -> [ConsD]
-            buildObjectCons fields = [mkCons typeName fields]
-            tKind = kindOf typeOriginal
-            genType :: TypeContent TRUE ANY -> Q GQLTypeD
-            genType (DataEnum tags) =
-              pure
-                GQLTypeD
-                  { typeD =
-                      TypeD
-                        { tName = hsTypeName typeName,
-                          tNamespace = [],
-                          tCons = map mkConsEnum tags,
-                          tMeta = typeMeta,
-                          tKind
-                        },
-                    typeArgD = [],
-                    ..
-                  }
-            genType DataScalar {} = fail "Scalar Types should defined By Native Haskell Types"
-            genType DataInputUnion {} = fail "Input Unions not Supported"
-            genType DataInterface {interfaceFields} = do
-              typeArgD <- concat <$> traverse (genArgumentType genArgsTypeName) (elems interfaceFields)
-              objCons <- buildObjectCons <$> traverse genResField interfaceFields
-              pure
-                GQLTypeD
-                  { typeD = buildType objCons,
-                    typeArgD,
-                    ..
-                  }
-            genType (DataInputObject fields) =
-              pure
-                GQLTypeD
-                  { typeD = buildType $ buildObjectCons fields,
-                    typeArgD = [],
-                    ..
-                  }
-            genType DataObject {objectFields} = do
-              typeArgD <- concat <$> traverse (genArgumentType genArgsTypeName) (elems objectFields)
-              objCons <- buildObjectCons <$> traverse genResField objectFields
-              pure
-                GQLTypeD
-                  { typeD = buildType objCons,
-                    typeArgD,
-                    ..
-                  }
-            genType (DataUnion members) =
-              pure
-                GQLTypeD
-                  { typeD = buildType (map unionCon members),
-                    typeArgD = [],
-                    ..
-                  }
-              where
-                unionCon memberName =
-                  mkCons
-                    cName
-                    ( singleton
-                        FieldDefinition
-                          { fieldName = "un" <> toFieldName cName,
-                            fieldType =
-                              TypeRef
-                                { typeConName = utName,
-                                  typeArgs = Just m_,
-                                  typeWrappers = []
-                                },
-                            fieldMeta = Nothing,
-                            fieldArgs = NoArguments
-                          }
-                    )
-                  where
-                    cName = hsTypeName typeName <> utName
-                    utName = hsTypeName memberName
-
-genArgumentType :: (FieldName -> TypeName) -> FieldDefinition OUT -> Q [TypeD]
-genArgumentType _ FieldDefinition {fieldArgs = NoArguments} = pure []
-genArgumentType namespaceWith FieldDefinition {fieldName, fieldArgs} =
-  pure
-    [ TypeD
-        { tName,
-          tNamespace = [],
-          tCons =
-            [ mkCons tName (argumentsToFields fieldArgs)
-            ],
-          tMeta = Nothing,
-          tKind = KindInputObject
-        }
-    ]
-  where
-    tName = hsTypeName (namespaceWith fieldName)
diff --git a/src/Data/Morpheus/Server/Document/Declare.hs b/src/Data/Morpheus/Server/Document/Declare.hs
deleted file mode 100644
--- a/src/Data/Morpheus/Server/Document/Declare.hs
+++ /dev/null
@@ -1,83 +0,0 @@
-{-# LANGUAGE DataKinds #-}
-{-# LANGUAGE NamedFieldPuns #-}
-{-# LANGUAGE TemplateHaskell #-}
-{-# LANGUAGE TypeFamilies #-}
-
-module Data.Morpheus.Server.Document.Declare
-  ( declare,
-  )
-where
-
--- MORPHEUS
-
-import Data.Morpheus.Internal.TH
-  ( Scope (..),
-    declareType,
-  )
-import Data.Morpheus.Server.Document.Decode
-  ( deriveDecode,
-  )
-import Data.Morpheus.Server.Document.Encode
-  ( deriveEncode,
-  )
-import Data.Morpheus.Server.Document.GQLType
-  ( deriveGQLType,
-  )
-import Data.Morpheus.Server.Document.Introspect
-  ( deriveObjectRep,
-    instanceIntrospect,
-  )
-import Data.Morpheus.Types.Internal.AST
-  ( GQLTypeD (..),
-    TypeD (..),
-    isInput,
-    isObject,
-  )
-import Data.Semigroup ((<>))
-import Language.Haskell.TH
-
-class Declare a where
-  type DeclareCtx a :: *
-  declare :: DeclareCtx a -> a -> Q [Dec]
-
-instance Declare a => Declare [a] where
-  type DeclareCtx [a] = DeclareCtx a
-  declare namespace = fmap concat . traverse (declare namespace)
-
-instance Declare GQLTypeD where
-  type DeclareCtx GQLTypeD = Bool
-  declare namespace gqlType@GQLTypeD {typeD = typeD@TypeD {tKind}, typeArgD, typeOriginal} =
-    do
-      mainType <- declareMainType
-      argTypes <- declareArgTypes
-      gqlInstances <- deriveGQLInstances
-      typeClasses <- deriveGQLType gqlType
-      introspectEnum <- instanceIntrospect typeOriginal
-      pure $ mainType <> typeClasses <> argTypes <> gqlInstances <> introspectEnum
-    where
-      deriveGQLInstances = concat <$> sequence gqlInstances
-        where
-          gqlInstances
-            | isObject tKind && isInput tKind =
-              [deriveObjectRep (typeD, Just typeOriginal, Nothing), deriveDecode typeD]
-            | isObject tKind =
-              [deriveObjectRep (typeD, Just typeOriginal, Just tKind), deriveEncode typeD]
-            | otherwise =
-              []
-      --------------------------------------------------
-      declareArgTypes = do
-        introspectArgs <- concat <$> traverse deriveArgsRep typeArgD
-        decodeArgs <- concat <$> traverse deriveDecode typeArgD
-        return $ argsTypeDecs <> decodeArgs <> introspectArgs
-        where
-          deriveArgsRep args = deriveObjectRep (args, Nothing, Nothing)
-          ----------------------------------------------------
-          argsTypeDecs = map (declareType SERVER namespace Nothing []) typeArgD
-      --------------------------------------------------
-      declareMainType = declareT
-        where
-          declareT =
-            pure [declareType SERVER namespace (Just tKind) derivingClasses typeD]
-          derivingClasses
-            | isInput tKind = [''Show]
-            | otherwise = []
diff --git a/src/Data/Morpheus/Server/Document/Decode.hs b/src/Data/Morpheus/Server/Document/Decode.hs
deleted file mode 100644
--- a/src/Data/Morpheus/Server/Document/Decode.hs
+++ /dev/null
@@ -1,51 +0,0 @@
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE MonoLocalBinds #-}
-{-# LANGUAGE NamedFieldPuns #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE QuasiQuotes #-}
-{-# LANGUAGE TemplateHaskell #-}
-
-module Data.Morpheus.Server.Document.Decode
-  ( deriveDecode,
-  )
-where
-
---
--- MORPHEUS
-
-import Data.Morpheus.Internal.TH
-  ( instanceHeadT,
-    nameVarP,
-  )
-import Data.Morpheus.Server.Deriving.Decode
-  ( Decode (..),
-    DecodeType (..),
-  )
-import Data.Morpheus.Server.Internal.TH.Decode
-  ( decodeFieldWith,
-    decodeObjectExpQ,
-    withObject,
-  )
-import Data.Morpheus.Types.Internal.AST
-  ( FieldName,
-    TypeD (..),
-    ValidValue,
-  )
-import Data.Morpheus.Types.Internal.Resolving
-  ( Eventless,
-  )
-import Language.Haskell.TH
-
-(.:) :: Decode a => ValidValue -> FieldName -> Eventless a
-value .: selectorName = withObject (decodeFieldWith decode selectorName) value
-
-deriveDecode :: TypeD -> Q [Dec]
-deriveDecode TypeD {tName, tCons = [cons]} =
-  pure <$> instanceD (cxt []) appHead methods
-  where
-    appHead = instanceHeadT ''DecodeType tName []
-    methods = [funD 'decodeType [clause argsE (normalB body) []]]
-      where
-        argsE = map nameVarP ["o"]
-        body = decodeObjectExpQ [|(.:)|] cons
-deriveDecode _ = pure []
diff --git a/src/Data/Morpheus/Server/Document/Encode.hs b/src/Data/Morpheus/Server/Document/Encode.hs
deleted file mode 100644
--- a/src/Data/Morpheus/Server/Document/Encode.hs
+++ /dev/null
@@ -1,131 +0,0 @@
-{-# LANGUAGE DataKinds #-}
-{-# LANGUAGE NamedFieldPuns #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE TemplateHaskell #-}
-
-module Data.Morpheus.Server.Document.Encode
-  ( deriveEncode,
-  )
-where
-
---
--- MORPHEUS
-
-import Data.Morpheus.Internal.TH
-  ( applyT,
-    destructRecord,
-    instanceHeadMultiT,
-    mkTypeName,
-    nameStringE,
-    nameVarE,
-    nameVarP,
-    nameVarT,
-    typeT,
-  )
-import Data.Morpheus.Server.Deriving.Encode
-  ( Encode (..),
-    ExploreResolvers (..),
-  )
-import Data.Morpheus.Server.Types.GQLType (TRUE)
-import Data.Morpheus.Types.Internal.AST
-  ( ConsD (..),
-    FieldDefinition (..),
-    QUERY,
-    SUBSCRIPTION,
-    TypeD (..),
-    TypeName (..),
-    isSubscription,
-  )
-import Data.Morpheus.Types.Internal.Resolving
-  ( LiftOperation,
-    MapStrategy (..),
-    ObjectResModel (..),
-    ResModel (..),
-    Resolver,
-  )
-import Data.Semigroup ((<>))
-import Data.Typeable (Typeable)
-import Language.Haskell.TH
-
-m_ :: TypeName
-m_ = "m"
-
-fo_ :: TypeName
-fo_ = "fieldOperationKind"
-
-po_ :: TypeName
-po_ = "parentOparation"
-
-e_ :: TypeName
-e_ = "encodeEvent"
-
-encodeVars :: [TypeName]
-encodeVars = [e_, m_]
-
-encodeVarsT :: [TypeQ]
-encodeVarsT = map nameVarT encodeVars
-
-deriveEncode :: TypeD -> Q [Dec]
-deriveEncode TypeD {tName, tCons = [ConsD {cFields}], tKind} =
-  pure <$> instanceD (cxt constrains) appHead methods
-  where
-    subARgs = conT ''SUBSCRIPTION : encodeVarsT
-    instanceArgs
-      | isSubscription tKind = subARgs
-      | otherwise = map nameVarT (po_ : encodeVars)
-    mainType = applyT (mkTypeName tName) [mainTypeArg]
-      where
-        mainTypeArg
-          | isSubscription tKind = applyT ''Resolver subARgs
-          | otherwise = typeT ''Resolver (fo_ : encodeVars)
-    -----------------------------------------------------------------------------------------
-    typeables
-      | isSubscription tKind =
-        [applyT ''MapStrategy $ map conT [''QUERY, ''SUBSCRIPTION]]
-      | otherwise =
-        [ iLiftOp po_,
-          iLiftOp fo_,
-          typeT ''MapStrategy [fo_, po_],
-          iTypeable fo_,
-          iTypeable po_
-        ]
-    -------------------------
-    iLiftOp op = applyT ''LiftOperation [nameVarT op]
-    -------------------------
-    iTypeable name = typeT ''Typeable [name]
-    -------------------------------------------
-    -- defines Constraint: (Typeable m, Monad m)
-    constrains =
-      typeables
-        <> [ typeT ''Monad [m_],
-             applyT ''Encode (mainType : instanceArgs),
-             iTypeable e_,
-             iTypeable m_
-           ]
-    -------------------------------------------------------------------
-    -- defines: instance <constraint> =>  ObjectResolvers ('TRUE) (<Type> (ResolveT m)) (ResolveT m value) where
-    appHead =
-      instanceHeadMultiT
-        ''ExploreResolvers
-        (conT ''TRUE)
-        (mainType : instanceArgs)
-    ------------------------------------------------------------------
-    -- defines: objectResolvers <Type field1 field2 ...> = [("field1",encode field1),("field2",encode field2), ...]
-    methods = [funD 'exploreResolvers [clause argsE (normalB body) []]]
-      where
-        argsE = [nameVarP "_", destructRecord tName varNames]
-        body =
-          appE (varE 'pure)
-            $ appE
-              (conE 'ResObject)
-            $ appE
-              ( appE
-                  (conE 'ObjectResModel)
-                  (nameStringE tName)
-              )
-              (listE $ map decodeVar varNames)
-        decodeVar name = [|(name, encode $(varName))|]
-          where
-            varName = nameVarE name
-        varNames = map fieldName cFields
-deriveEncode _ = pure []
diff --git a/src/Data/Morpheus/Server/Document/GQLType.hs b/src/Data/Morpheus/Server/Document/GQLType.hs
deleted file mode 100644
--- a/src/Data/Morpheus/Server/Document/GQLType.hs
+++ /dev/null
@@ -1,110 +0,0 @@
-{-# LANGUAGE DataKinds #-}
-{-# LANGUAGE GADTs #-}
-{-# LANGUAGE NamedFieldPuns #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE QuasiQuotes #-}
-{-# LANGUAGE TemplateHaskell #-}
-
-module Data.Morpheus.Server.Document.GQLType
-  ( deriveGQLType,
-  )
-where
-
---
--- MORPHEUS
-import Data.Morpheus.Internal.TH
-  ( instanceHeadT,
-    instanceProxyFunD,
-    mkTypeName,
-    tyConArgs,
-    typeInstanceDec,
-    typeT,
-  )
-import Data.Morpheus.Kind
-  ( ENUM,
-    INPUT,
-    INTERFACE,
-    OUTPUT,
-    SCALAR,
-    WRAPPER,
-  )
-import Data.Morpheus.Server.Types.GQLType
-  ( GQLType (..),
-    TRUE,
-  )
-import Data.Morpheus.Types (Resolver, interface)
-import Data.Morpheus.Types.Internal.AST
-  ( ANY,
-    DataTypeKind (..),
-    GQLTypeD (..),
-    Meta (..),
-    QUERY,
-    TypeContent (..),
-    TypeD (..),
-    TypeDefinition (..),
-    TypeName,
-    isObject,
-  )
-import Data.Proxy (Proxy (..))
-import Data.Semigroup ((<>))
-import Data.Typeable (Typeable)
-import Language.Haskell.TH
-
-interfaceF :: Name -> ExpQ
-interfaceF name = [|interface (Proxy :: (Proxy ($(conT name) (Resolver QUERY () Maybe))))|]
-
-introspectInterface :: TypeName -> ExpQ
-introspectInterface = interfaceF . mkTypeName
-
-deriveGQLType :: GQLTypeD -> Q [Dec]
-deriveGQLType GQLTypeD {typeD = TypeD {tName, tMeta, tKind}, typeOriginal} =
-  pure <$> instanceD (cxt constrains) iHead (functions <> typeFamilies)
-  where
-    functions =
-      map
-        instanceProxyFunD
-        [ ('__typeName, [|tName|]),
-          ('description, descriptionValue),
-          ('implements, implementsFunc)
-        ]
-      where
-        implementsFunc = listE $ map introspectInterface (interfacesFrom (Just typeOriginal))
-        descriptionValue = case tMeta >>= metaDescription of
-          Nothing -> [|Nothing|]
-          Just desc -> [|Just desc|]
-    --------------------------------
-    typeArgs = tyConArgs tKind
-    --------------------------------
-    iHead = instanceHeadT ''GQLType tName typeArgs
-    headSig = typeT (mkTypeName tName) typeArgs
-    ---------------------------------------------------
-    constrains = map conTypeable typeArgs
-      where
-        conTypeable name = typeT ''Typeable [name]
-    -------------------------------------------------
-    typeFamilies
-      | isObject tKind = [deriveKIND, deriveCUSTOM]
-      | otherwise = [deriveKIND]
-      where
-        deriveCUSTOM = deriveInstance ''CUSTOM ''TRUE
-        deriveKIND = deriveInstance ''KIND (kindName tKind)
-        -------------------------------------------------------
-        deriveInstance :: Name -> Name -> Q Dec
-        deriveInstance insName tyName = do
-          typeN <- headSig
-          pure $ typeInstanceDec insName typeN (ConT tyName)
-
-kindName :: DataTypeKind -> Name
-kindName KindObject {} = ''OUTPUT
-kindName KindScalar = ''SCALAR
-kindName KindEnum = ''ENUM
-kindName KindUnion = ''OUTPUT
-kindName KindInputObject = ''INPUT
-kindName KindList = ''WRAPPER
-kindName KindNonNull = ''WRAPPER
-kindName KindInputUnion = ''INPUT
-kindName KindInterface = ''INTERFACE
-
-interfacesFrom :: Maybe (TypeDefinition ANY) -> [TypeName]
-interfacesFrom (Just TypeDefinition {typeContent = DataObject {objectImplements}}) = objectImplements
-interfacesFrom _ = []
diff --git a/src/Data/Morpheus/Server/Document/Introspect.hs b/src/Data/Morpheus/Server/Document/Introspect.hs
deleted file mode 100644
--- a/src/Data/Morpheus/Server/Document/Introspect.hs
+++ /dev/null
@@ -1,135 +0,0 @@
-{-# LANGUAGE GADTs #-}
-{-# LANGUAGE NamedFieldPuns #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE QuasiQuotes #-}
-{-# LANGUAGE RecordWildCards #-}
-{-# LANGUAGE TemplateHaskell #-}
-
-module Data.Morpheus.Server.Document.Introspect
-  ( deriveObjectRep,
-    instanceIntrospect,
-  )
-where
-
-import Data.Maybe (maybeToList)
--- MORPHEUS
-import Data.Morpheus.Internal.TH
-  ( instanceFunD,
-    instanceHeadMultiT,
-    instanceHeadT,
-    instanceProxyFunD,
-    mkTypeName,
-    nameConT,
-    nameVarT,
-    tyConArgs,
-    typeT,
-  )
-import Data.Morpheus.Server.Deriving.Introspect
-  ( DeriveTypeContent (..),
-    Introspect (..),
-    deriveCustomInputObjectType,
-  )
-import Data.Morpheus.Server.Types.GQLType
-  ( GQLType (__typeName, implements),
-    TRUE,
-  )
-import Data.Morpheus.Types.Internal.AST
-  ( ANY,
-    ArgumentsDefinition (..),
-    ConsD (..),
-    DataTypeKind (..),
-    FieldDefinition (..),
-    TypeContent (..),
-    TypeD (..),
-    TypeDefinition (..),
-    TypeName,
-    TypeRef (..),
-    TypeUpdater,
-    insertType,
-    unsafeFromFields,
-  )
-import Data.Morpheus.Types.Internal.Resolving
-  ( resolveUpdates,
-  )
-import Data.Proxy (Proxy (..))
-import Data.Typeable (Typeable)
-import Language.Haskell.TH
-
-instanceIntrospect :: TypeDefinition cat -> Q [Dec]
-instanceIntrospect TypeDefinition {typeName, typeContent = DataEnum enumType, ..}
-  -- FIXME: dirty fix for introspection
-  | typeName `elem` ["__DirectiveLocation", "__TypeKind"] = pure []
-  | otherwise = pure <$> instanceD (cxt []) iHead [defineIntrospect]
-  where
-    iHead = instanceHeadT ''Introspect typeName []
-    defineIntrospect = instanceProxyFunD ('introspect, body)
-      where
-        body = [|insertType TypeDefinition {typeContent = DataEnum enumType, ..}|]
-instanceIntrospect _ = pure []
-
--- [(FieldDefinition, TypeUpdater)]
-deriveObjectRep :: (TypeD, Maybe (TypeDefinition ANY), Maybe DataTypeKind) -> Q [Dec]
-deriveObjectRep (TypeD {tName, tCons = [ConsD {cFields}]}, _, tKind) =
-  pure <$> instanceD (cxt constrains) iHead methods
-  where
-    mainTypeName = typeT (mkTypeName tName) typeArgs
-    typeArgs = concatMap tyConArgs (maybeToList tKind)
-    constrains = map conTypeable typeArgs
-      where
-        conTypeable name = typeT ''Typeable [name]
-    -----------------------------------------------
-    iHead = instanceHeadMultiT ''DeriveTypeContent (conT ''TRUE) [mainTypeName]
-    methods = [instanceFunD 'deriveTypeContent ["_proxy1", "_proxy2"] body]
-      where
-        body
-          | tKind == Just KindInputObject || null tKind =
-            [|
-              ( DataInputObject
-                  (unsafeFromFields $(buildFields cFields)),
-                $(typeUpdates)
-              )
-              |]
-          | otherwise =
-            [|
-              ( DataObject
-                  (interfaceNames $(proxy))
-                  (unsafeFromFields $(buildFields cFields)),
-                interfaceTypes $(proxy)
-                  : $(typeUpdates)
-              )
-              |]
-        -------------------------------------------------------------
-        typeUpdates = buildTypes cFields
-        proxy = [|(Proxy :: Proxy $(mainTypeName))|]
-deriveObjectRep _ = pure []
-
-interfaceNames :: GQLType a => Proxy a -> [TypeName]
-interfaceNames = map fst . implements
-
-interfaceTypes :: GQLType a => Proxy a -> TypeUpdater
-interfaceTypes = flip resolveUpdates . map snd . implements
-
-buildTypes :: [FieldDefinition cat] -> ExpQ
-buildTypes = listE . concatMap introspectField
-
-introspectField :: FieldDefinition cat -> [ExpQ]
-introspectField FieldDefinition {fieldType, fieldArgs} =
-  [|introspect $(proxyT fieldType)|] : inputTypes fieldArgs
-  where
-    inputTypes :: ArgumentsDefinition -> [ExpQ]
-    inputTypes ArgumentsDefinition {argumentsTypename = Just argsTypeName}
-      | argsTypeName /= "()" = [[|deriveCustomInputObjectType (argsTypeName, $(proxyT tAlias))|]]
-      where
-        tAlias = TypeRef {typeConName = argsTypeName, typeWrappers = [], typeArgs = Nothing}
-    inputTypes _ = []
-
-proxyT :: TypeRef -> Q Exp
-proxyT TypeRef {typeConName, typeArgs} = [|(Proxy :: Proxy $(genSig typeArgs))|]
-  where
-    genSig (Just m) = appT (nameConT typeConName) (nameVarT m)
-    genSig _ = nameConT typeConName
-
-buildFields :: [FieldDefinition cat] -> ExpQ
-buildFields = listE . map buildField
-  where
-    buildField f@FieldDefinition {fieldType} = [|f {fieldType = fieldType {typeConName = __typeName $(proxyT fieldType)}}|]
diff --git a/src/Data/Morpheus/Server/Internal/TH/Decode.hs b/src/Data/Morpheus/Server/Internal/TH/Decode.hs
--- a/src/Data/Morpheus/Server/Internal/TH/Decode.hs
+++ b/src/Data/Morpheus/Server/Internal/TH/Decode.hs
@@ -32,31 +32,34 @@
     FieldDefinition (..),
     FieldName,
     Message,
+    Message,
     ObjectEntry (..),
     TypeName (..),
     ValidObject,
     ValidValue,
     Value (..),
+    msg,
     toFieldName,
   )
 import Data.Morpheus.Types.Internal.Resolving
   ( Eventless,
     Failure (..),
   )
+import Data.Semigroup ((<>))
 import Language.Haskell.TH
   ( ExpQ,
     uInfixE,
     varE,
   )
 
-decodeObjectExpQ :: ExpQ -> ConsD -> ExpQ
+decodeObjectExpQ :: ExpQ -> ConsD cat -> ExpQ
 decodeObjectExpQ fieldDecoder ConsD {cName, cFields} = handleFields cFields
   where
     consName = nameConE cName
     ----------------------------------------------------------------------------------
     handleFields fNames = uInfixE consName (varE '(<$>)) (applyFields fNames)
       where
-        applyFields [] = fail "No Empty fields"
+        applyFields [] = fail $ show ("No Empty fields on " <> msg cName :: Message)
         applyFields [x] = defField x
         applyFields (x : xs) = uInfixE (defField x) (varE '(<*>)) (applyFields xs)
         ------------------------------------------------------------------------
diff --git a/src/Data/Morpheus/Server/Internal/TH/Types.hs b/src/Data/Morpheus/Server/Internal/TH/Types.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Morpheus/Server/Internal/TH/Types.hs
@@ -0,0 +1,25 @@
+module Data.Morpheus.Server.Internal.TH.Types
+  ( ServerTypeDefinition (..),
+  )
+where
+
+import Data.Morpheus.Types.Internal.AST
+  ( ANY,
+    ConsD (..),
+    FieldName,
+    IN,
+    TypeDefinition,
+    TypeKind,
+    TypeName,
+  )
+
+--- Core
+data ServerTypeDefinition cat = ServerTypeDefinition
+  { tName :: TypeName,
+    tNamespace :: [FieldName],
+    typeArgD :: [ServerTypeDefinition IN],
+    tCons :: [ConsD cat],
+    tKind :: TypeKind,
+    typeOriginal :: Maybe (TypeDefinition ANY)
+  }
+  deriving (Show)
diff --git a/src/Data/Morpheus/Server/TH/Compile.hs b/src/Data/Morpheus/Server/TH/Compile.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Morpheus/Server/TH/Compile.hs
@@ -0,0 +1,64 @@
+{-# LANGUAGE NamedFieldPuns #-}
+
+module Data.Morpheus.Server.TH.Compile
+  ( compileDocument,
+    gqlDocument,
+    gqlDocumentNamespace,
+  )
+where
+
+--
+--  Morpheus
+
+import Data.Morpheus.Core
+  ( parseTypeDefinitions,
+  )
+import Data.Morpheus.Error
+  ( gqlWarnings,
+    renderGQLErrors,
+  )
+import Data.Morpheus.Server.TH.Declare
+  ( declare,
+  )
+import Data.Morpheus.Server.TH.Transform
+  ( toTHDefinitions,
+  )
+import Data.Morpheus.Types.Internal.Resolving
+  ( Result (..),
+  )
+import qualified Data.Text as T
+  ( pack,
+  )
+import Language.Haskell.TH
+import Language.Haskell.TH.Quote
+
+gqlDocumentNamespace :: QuasiQuoter
+gqlDocumentNamespace =
+  QuasiQuoter
+    { quoteExp = notHandled "Expressions",
+      quotePat = notHandled "Patterns",
+      quoteType = notHandled "Types",
+      quoteDec = compileDocument True
+    }
+  where
+    notHandled things =
+      error $ things ++ " are not supported by the GraphQL QuasiQuoter"
+
+gqlDocument :: QuasiQuoter
+gqlDocument =
+  QuasiQuoter
+    { quoteExp = notHandled "Expressions",
+      quotePat = notHandled "Patterns",
+      quoteType = notHandled "Types",
+      quoteDec = compileDocument False
+    }
+  where
+    notHandled things =
+      error $ things ++ " are not supported by the GraphQL QuasiQuoter"
+
+compileDocument :: Bool -> String -> Q [Dec]
+compileDocument namespace documentTXT =
+  case parseTypeDefinitions (T.pack documentTXT) of
+    Failure errors -> fail (renderGQLErrors errors)
+    Success {result = schema, warnings} ->
+      gqlWarnings warnings >> toTHDefinitions namespace schema >>= declare namespace
diff --git a/src/Data/Morpheus/Server/TH/Declare.hs b/src/Data/Morpheus/Server/TH/Declare.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Morpheus/Server/TH/Declare.hs
@@ -0,0 +1,82 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE TypeFamilies #-}
+
+module Data.Morpheus.Server.TH.Declare
+  ( declare,
+  )
+where
+
+-- MORPHEUS
+
+import Data.Morpheus.Server.Internal.TH.Types
+  ( ServerTypeDefinition (..),
+  )
+import Data.Morpheus.Server.TH.Declare.Decode
+  ( deriveDecode,
+  )
+import Data.Morpheus.Server.TH.Declare.Encode
+  ( deriveEncode,
+  )
+import Data.Morpheus.Server.TH.Declare.GQLType
+  ( deriveGQLType,
+  )
+import Data.Morpheus.Server.TH.Declare.Introspect
+  ( deriveObjectRep,
+    instanceIntrospect,
+  )
+import Data.Morpheus.Server.TH.Declare.Type
+  ( declareType,
+  )
+import Data.Morpheus.Server.TH.Transform
+import Data.Morpheus.Types.Internal.AST
+  ( IN,
+    isInput,
+    isObject,
+  )
+import Data.Semigroup ((<>))
+import Language.Haskell.TH
+
+class Declare a where
+  type DeclareCtx a :: *
+  declare :: DeclareCtx a -> a -> Q [Dec]
+
+instance Declare a => Declare [a] where
+  type DeclareCtx [a] = DeclareCtx a
+  declare namespace = fmap concat . traverse (declare namespace)
+
+instance Declare TypeDec where
+  type DeclareCtx TypeDec = Bool
+  declare namespace (InputType typeD) = declare namespace typeD
+  declare namespace (OutputType typeD) = declare namespace typeD
+
+instance Declare (ServerTypeDefinition cat) where
+  type DeclareCtx (ServerTypeDefinition cat) = Bool
+  declare namespace typeD@ServerTypeDefinition {tKind, typeArgD, typeOriginal} =
+    do
+      let mainType = declareType namespace typeD
+      argTypes <- declareArgTypes namespace typeArgD
+      gqlInstances <- deriveGQLInstances
+      typeClasses <- deriveGQLType typeD
+      introspectEnum <- instanceIntrospect typeOriginal
+      pure $ mainType <> typeClasses <> argTypes <> gqlInstances <> introspectEnum
+    where
+      deriveGQLInstances = concat <$> sequence gqlInstances
+        where
+          gqlInstances
+            | isObject tKind && isInput tKind =
+              [deriveObjectRep typeD, deriveDecode typeD]
+            | isObject tKind =
+              [deriveObjectRep typeD, deriveEncode typeD]
+            | otherwise =
+              []
+
+declareArgTypes :: Bool -> [ServerTypeDefinition IN] -> Q [Dec]
+declareArgTypes namespace types = do
+  introspectArgs <- concat <$> traverse deriveObjectRep types
+  decodeArgs <- concat <$> traverse deriveDecode types
+  return $ argsTypeDecs <> decodeArgs <> introspectArgs
+  where
+    ----------------------------------------------------
+    argsTypeDecs = concatMap (declareType namespace) types
diff --git a/src/Data/Morpheus/Server/TH/Declare/Decode.hs b/src/Data/Morpheus/Server/TH/Declare/Decode.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Morpheus/Server/TH/Declare/Decode.hs
@@ -0,0 +1,51 @@
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE QuasiQuotes #-}
+{-# LANGUAGE TemplateHaskell #-}
+
+module Data.Morpheus.Server.TH.Declare.Decode
+  ( deriveDecode,
+  )
+where
+
+--
+-- MORPHEUS
+
+import Data.Morpheus.Internal.TH
+  ( instanceHeadT,
+    nameVarP,
+  )
+import Data.Morpheus.Server.Deriving.Decode
+  ( Decode (..),
+    DecodeType (..),
+  )
+import Data.Morpheus.Server.Internal.TH.Decode
+  ( decodeFieldWith,
+    decodeObjectExpQ,
+    withObject,
+  )
+import Data.Morpheus.Server.Internal.TH.Types (ServerTypeDefinition (..))
+import Data.Morpheus.Types.Internal.AST
+  ( FieldName,
+    ValidValue,
+  )
+import Data.Morpheus.Types.Internal.Resolving
+  ( Eventless,
+  )
+import Language.Haskell.TH
+
+(.:) :: Decode a => ValidValue -> FieldName -> Eventless a
+value .: selectorName = withObject (decodeFieldWith decode selectorName) value
+
+deriveDecode :: ServerTypeDefinition cat -> Q [Dec]
+deriveDecode ServerTypeDefinition {tName, tCons = [cons]} =
+  pure <$> instanceD (cxt []) appHead methods
+  where
+    appHead = instanceHeadT ''DecodeType tName []
+    methods = [funD 'decodeType [clause argsE (normalB body) []]]
+      where
+        argsE = map nameVarP ["o"]
+        body = decodeObjectExpQ [|(.:)|] cons
+deriveDecode _ = pure []
diff --git a/src/Data/Morpheus/Server/TH/Declare/Encode.hs b/src/Data/Morpheus/Server/TH/Declare/Encode.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Morpheus/Server/TH/Declare/Encode.hs
@@ -0,0 +1,131 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell #-}
+
+module Data.Morpheus.Server.TH.Declare.Encode
+  ( deriveEncode,
+  )
+where
+
+--
+-- MORPHEUS
+
+import Data.Morpheus.Internal.TH
+  ( applyT,
+    destructRecord,
+    instanceHeadMultiT,
+    mkTypeName,
+    nameStringE,
+    nameVarE,
+    nameVarP,
+    nameVarT,
+    typeT,
+  )
+import Data.Morpheus.Server.Deriving.Encode
+  ( Encode (..),
+    ExploreResolvers (..),
+  )
+import Data.Morpheus.Server.Internal.TH.Types (ServerTypeDefinition (..))
+import Data.Morpheus.Server.Types.GQLType (TRUE)
+import Data.Morpheus.Types.Internal.AST
+  ( ConsD (..),
+    FieldDefinition (..),
+    QUERY,
+    SUBSCRIPTION,
+    TypeName (..),
+    isSubscription,
+  )
+import Data.Morpheus.Types.Internal.Resolving
+  ( LiftOperation,
+    MapStrategy (..),
+    ObjectResModel (..),
+    ResModel (..),
+    Resolver,
+  )
+import Data.Semigroup ((<>))
+import Data.Typeable (Typeable)
+import Language.Haskell.TH
+
+m_ :: TypeName
+m_ = "m"
+
+fo_ :: TypeName
+fo_ = "fieldOperationKind"
+
+po_ :: TypeName
+po_ = "parentOparation"
+
+e_ :: TypeName
+e_ = "encodeEvent"
+
+encodeVars :: [TypeName]
+encodeVars = [e_, m_]
+
+encodeVarsT :: [TypeQ]
+encodeVarsT = map nameVarT encodeVars
+
+deriveEncode :: ServerTypeDefinition cat -> Q [Dec]
+deriveEncode ServerTypeDefinition {tName, tCons = [ConsD {cFields}], tKind} =
+  pure <$> instanceD (cxt constrains) appHead methods
+  where
+    subARgs = conT ''SUBSCRIPTION : encodeVarsT
+    instanceArgs
+      | isSubscription tKind = subARgs
+      | otherwise = map nameVarT (po_ : encodeVars)
+    mainType = applyT (mkTypeName tName) [mainTypeArg]
+      where
+        mainTypeArg
+          | isSubscription tKind = applyT ''Resolver subARgs
+          | otherwise = typeT ''Resolver (fo_ : encodeVars)
+    -----------------------------------------------------------------------------------------
+    typeables
+      | isSubscription tKind =
+        [applyT ''MapStrategy $ map conT [''QUERY, ''SUBSCRIPTION]]
+      | otherwise =
+        [ iLiftOp po_,
+          iLiftOp fo_,
+          typeT ''MapStrategy [fo_, po_],
+          iTypeable fo_,
+          iTypeable po_
+        ]
+    -------------------------
+    iLiftOp op = applyT ''LiftOperation [nameVarT op]
+    -------------------------
+    iTypeable name = typeT ''Typeable [name]
+    -------------------------------------------
+    -- defines Constraint: (Typeable m, Monad m)
+    constrains =
+      typeables
+        <> [ typeT ''Monad [m_],
+             applyT ''Encode (mainType : instanceArgs),
+             iTypeable e_,
+             iTypeable m_
+           ]
+    -------------------------------------------------------------------
+    -- defines: instance <constraint> =>  ObjectResolvers ('TRUE) (<Type> (ResolveT m)) (ResolveT m value) where
+    appHead =
+      instanceHeadMultiT
+        ''ExploreResolvers
+        (conT ''TRUE)
+        (mainType : instanceArgs)
+    ------------------------------------------------------------------
+    -- defines: objectResolvers <Type field1 field2 ...> = [("field1",encode field1),("field2",encode field2), ...]
+    methods = [funD 'exploreResolvers [clause argsE (normalB body) []]]
+      where
+        argsE = [nameVarP "_", destructRecord tName varNames]
+        body =
+          appE (varE 'pure)
+            $ appE
+              (conE 'ResObject)
+            $ appE
+              ( appE
+                  (conE 'ObjectResModel)
+                  (nameStringE tName)
+              )
+              (listE $ map decodeVar varNames)
+        decodeVar name = [|(name, encode $(varName))|]
+          where
+            varName = nameVarE name
+        varNames = map fieldName cFields
+deriveEncode _ = pure []
diff --git a/src/Data/Morpheus/Server/TH/Declare/GQLType.hs b/src/Data/Morpheus/Server/TH/Declare/GQLType.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Morpheus/Server/TH/Declare/GQLType.hs
@@ -0,0 +1,106 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE QuasiQuotes #-}
+{-# LANGUAGE TemplateHaskell #-}
+
+module Data.Morpheus.Server.TH.Declare.GQLType
+  ( deriveGQLType,
+  )
+where
+
+--
+-- MORPHEUS
+import Data.Morpheus.Internal.TH
+  ( instanceHeadT,
+    instanceProxyFunD,
+    mkTypeName,
+    tyConArgs,
+    typeInstanceDec,
+    typeT,
+  )
+import Data.Morpheus.Kind
+  ( ENUM,
+    INPUT,
+    INTERFACE,
+    OUTPUT,
+    SCALAR,
+    WRAPPER,
+  )
+import Data.Morpheus.Server.Internal.TH.Types (ServerTypeDefinition (..))
+import Data.Morpheus.Server.Types.GQLType
+  ( GQLType (..),
+    TRUE,
+  )
+import Data.Morpheus.Types (Resolver, interface)
+import Data.Morpheus.Types.Internal.AST
+  ( ANY,
+    QUERY,
+    TypeContent (..),
+    TypeDefinition (..),
+    TypeKind (..),
+    TypeName,
+    isObject,
+  )
+import Data.Proxy (Proxy (..))
+import Data.Semigroup ((<>))
+import Data.Typeable (Typeable)
+import Language.Haskell.TH
+
+interfaceF :: Name -> ExpQ
+interfaceF name = [|interface (Proxy :: (Proxy ($(conT name) (Resolver QUERY () Maybe))))|]
+
+introspectInterface :: TypeName -> ExpQ
+introspectInterface = interfaceF . mkTypeName
+
+deriveGQLType :: ServerTypeDefinition cat -> Q [Dec]
+deriveGQLType ServerTypeDefinition {tName, tKind, typeOriginal} =
+  pure <$> instanceD (cxt constrains) iHead (functions <> typeFamilies)
+  where
+    functions =
+      map
+        instanceProxyFunD
+        [ ('__typeName, [|tName|]),
+          ('description, [|tDescription|]),
+          ('implements, implementsFunc)
+        ]
+      where
+        tDescription = typeOriginal >>= typeDescription
+        implementsFunc = listE $ map introspectInterface (interfacesFrom typeOriginal)
+    --------------------------------
+    typeArgs = tyConArgs tKind
+    --------------------------------
+    iHead = instanceHeadT ''GQLType tName typeArgs
+    headSig = typeT (mkTypeName tName) typeArgs
+    ---------------------------------------------------
+    constrains = map conTypeable typeArgs
+      where
+        conTypeable name = typeT ''Typeable [name]
+    -------------------------------------------------
+    typeFamilies
+      | isObject tKind = [deriveKIND, deriveCUSTOM]
+      | otherwise = [deriveKIND]
+      where
+        deriveCUSTOM = deriveInstance ''CUSTOM ''TRUE
+        deriveKIND = deriveInstance ''KIND (kindName tKind)
+        -------------------------------------------------------
+        deriveInstance :: Name -> Name -> Q Dec
+        deriveInstance insName tyName = do
+          typeN <- headSig
+          pure $ typeInstanceDec insName typeN (ConT tyName)
+
+kindName :: TypeKind -> Name
+kindName KindObject {} = ''OUTPUT
+kindName KindScalar = ''SCALAR
+kindName KindEnum = ''ENUM
+kindName KindUnion = ''OUTPUT
+kindName KindInputObject = ''INPUT
+kindName KindList = ''WRAPPER
+kindName KindNonNull = ''WRAPPER
+kindName KindInputUnion = ''INPUT
+kindName KindInterface = ''INTERFACE
+
+interfacesFrom :: Maybe (TypeDefinition ANY) -> [TypeName]
+interfacesFrom (Just TypeDefinition {typeContent = DataObject {objectImplements}}) = objectImplements
+interfacesFrom _ = []
diff --git a/src/Data/Morpheus/Server/TH/Declare/Introspect.hs b/src/Data/Morpheus/Server/TH/Declare/Introspect.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Morpheus/Server/TH/Declare/Introspect.hs
@@ -0,0 +1,171 @@
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE QuasiQuotes #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE TemplateHaskell #-}
+
+module Data.Morpheus.Server.TH.Declare.Introspect
+  ( deriveObjectRep,
+    instanceIntrospect,
+  )
+where
+
+-- MORPHEUS
+import Data.Morpheus.Internal.TH
+  ( instanceFunD,
+    instanceHeadMultiT,
+    instanceProxyFunD,
+    mkTypeName,
+    nameConT,
+    nameVarT,
+    tyConArgs,
+    typeT,
+  )
+import Data.Morpheus.Server.Deriving.Introspect
+  ( DeriveTypeContent (..),
+    Introspect (..),
+    ProxyRep (..),
+    deriveCustomInputObjectType,
+  )
+import Data.Morpheus.Server.Internal.TH.Types (ServerTypeDefinition (..))
+import Data.Morpheus.Server.Types.GQLType
+  ( GQLType (__typeName, implements),
+    TRUE,
+  )
+import Data.Morpheus.Types.Internal.AST
+  ( ArgumentsDefinition (..),
+    ConsD (..),
+    FieldContent (..),
+    FieldDefinition (..),
+    IN,
+    OUT,
+    TypeContent (..),
+    TypeDefinition (..),
+    TypeKind (..),
+    TypeName,
+    TypeRef (..),
+    TypeUpdater,
+    insertType,
+    unsafeFromFields,
+  )
+import Data.Morpheus.Types.Internal.Resolving
+  ( resolveUpdates,
+  )
+import Data.Proxy (Proxy (..))
+import Data.Typeable (Typeable)
+import Language.Haskell.TH
+
+cat_ :: TypeQ
+cat_ = varT (mkName "cat")
+
+instanceIntrospect :: Maybe (TypeDefinition cat) -> Q [Dec]
+instanceIntrospect (Just typeDef@TypeDefinition {typeName, typeContent = DataEnum {}}) =
+  pure <$> instanceD (cxt []) iHead [defineIntrospect]
+  where
+    iHead = instanceHeadMultiT ''Introspect cat_ [conT $ mkTypeName typeName]
+    defineIntrospect = instanceProxyFunD ('introspect, body)
+      where
+        body = [|insertType typeDef|]
+instanceIntrospect _ = pure []
+
+-- [(FieldDefinition, TypeUpdater)]
+deriveObjectRep :: ServerTypeDefinition cat -> Q [Dec]
+deriveObjectRep
+  ServerTypeDefinition
+    { tName,
+      tCons = [ConsD {cFields}],
+      tKind
+    } =
+    pure <$> instanceD (cxt constrains) iHead methods
+    where
+      mainTypeName = typeT (mkTypeName tName) typeArgs
+      typeArgs = tyConArgs tKind
+      constrains = map conTypeable typeArgs
+        where
+          conTypeable name = typeT ''Typeable [name]
+      -----------------------------------------------
+      iHead = instanceHeadMultiT ''DeriveTypeContent instCat [conT ''TRUE, mainTypeName]
+      instCat
+        | tKind == KindInputObject =
+          conT ''IN
+        | otherwise = conT ''OUT
+      methods = [instanceFunD 'deriveTypeContent ["_proxy1", "_proxy2"] body]
+        where
+          body
+            | tKind == KindInputObject =
+              [|
+                deriveInputObject
+                  $(buildFields cFields)
+                  $(buildTypes instCat cFields)
+                |]
+            | otherwise =
+              [|
+                deriveOutputObject
+                  $(proxy)
+                  $(buildFields cFields)
+                  $(buildTypes instCat cFields)
+                |]
+          proxy = [|(Proxy :: Proxy $(mainTypeName))|]
+deriveObjectRep _ = pure []
+
+deriveInputObject ::
+  [FieldDefinition IN] ->
+  [TypeUpdater] ->
+  ( TypeContent TRUE IN,
+    [TypeUpdater]
+  )
+deriveInputObject fields typeUpdates =
+  (DataInputObject (unsafeFromFields fields), typeUpdates)
+
+deriveOutputObject ::
+  (GQLType a) =>
+  Proxy a ->
+  [FieldDefinition OUT] ->
+  [TypeUpdater] ->
+  ( TypeContent TRUE OUT,
+    [TypeUpdater]
+  )
+deriveOutputObject proxy fields typeUpdates =
+  ( DataObject
+      (interfaceNames proxy)
+      (unsafeFromFields fields),
+    interfaceTypes proxy : typeUpdates
+  )
+
+interfaceNames :: GQLType a => Proxy a -> [TypeName]
+interfaceNames = map fst . implements
+
+interfaceTypes :: GQLType a => Proxy a -> TypeUpdater
+interfaceTypes = flip resolveUpdates . map snd . implements
+
+buildTypes :: TypeQ -> [FieldDefinition cat] -> ExpQ
+buildTypes cat = listE . concatMap (introspectField cat)
+
+introspectField :: TypeQ -> FieldDefinition cat -> [ExpQ]
+introspectField cat FieldDefinition {fieldType, fieldContent} =
+  [|introspect $(proxyRepT cat fieldType)|] : inputTypes fieldContent
+  where
+    inputTypes :: Maybe (FieldContent TRUE cat) -> [ExpQ]
+    inputTypes (Just (FieldArgs ArgumentsDefinition {argumentsTypename = Just argsTypeName}))
+      | argsTypeName /= "()" = [[|deriveCustomInputObjectType (argsTypeName, $(proxyT tAlias))|]]
+      where
+        tAlias = TypeRef {typeConName = argsTypeName, typeWrappers = [], typeArgs = Nothing}
+    inputTypes _ = []
+
+proxyRepT :: TypeQ -> TypeRef -> Q Exp
+proxyRepT cat TypeRef {typeConName, typeArgs} = [|(ProxyRep :: ProxyRep $(cat) $(genSig typeArgs))|]
+  where
+    genSig (Just m) = appT (nameConT typeConName) (nameVarT m)
+    genSig _ = nameConT typeConName
+
+proxyT :: TypeRef -> Q Exp
+proxyT TypeRef {typeConName, typeArgs} = [|(Proxy :: Proxy $(genSig typeArgs))|]
+  where
+    genSig (Just m) = appT (nameConT typeConName) (nameVarT m)
+    genSig _ = nameConT typeConName
+
+buildFields :: [FieldDefinition cat] -> ExpQ
+buildFields = listE . map buildField
+  where
+    buildField f@FieldDefinition {fieldType} = [|f {fieldType = fieldType {typeConName = __typeName $(proxyT fieldType)}}|]
diff --git a/src/Data/Morpheus/Server/TH/Declare/Type.hs b/src/Data/Morpheus/Server/TH/Declare/Type.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Morpheus/Server/TH/Declare/Type.hs
@@ -0,0 +1,120 @@
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell #-}
+
+module Data.Morpheus.Server.TH.Declare.Type
+  ( declareType,
+  )
+where
+
+import Data.Morpheus.Internal.TH
+  ( declareTypeRef,
+    m',
+    mkFieldName,
+    mkTypeName,
+    nameSpaceField,
+    nameSpaceType,
+    tyConArgs,
+  )
+import Data.Morpheus.Server.Internal.TH.Types (ServerTypeDefinition (..))
+import Data.Morpheus.Types.Internal.AST
+  ( ArgumentsDefinition (..),
+    ConsD (..),
+    FieldContent (..),
+    FieldDefinition (..),
+    FieldName,
+    TRUE,
+    TypeKind (..),
+    TypeName,
+    isOutput,
+    isOutputObject,
+    isSubscription,
+  )
+import GHC.Generics (Generic)
+import Language.Haskell.TH
+
+declareType :: Bool -> ServerTypeDefinition cat -> [Dec]
+declareType _ ServerTypeDefinition {tKind = KindScalar} = []
+declareType namespace ServerTypeDefinition {tName, tCons, tKind, tNamespace} =
+  [ DataD
+      []
+      (mkNamespace tNamespace tName)
+      tVars
+      Nothing
+      cons
+      (derive tKind)
+  ]
+  where
+    tVars = declareTyVar (tyConArgs tKind)
+      where
+        declareTyVar = map (PlainTV . mkTypeName)
+    cons = declareCons namespace tKind (tNamespace, tName) tCons
+
+derive :: TypeKind -> [DerivClause]
+derive tKind = [deriveClasses (''Generic : derivingList)]
+  where
+    derivingList
+      | isOutput tKind = []
+      | otherwise = [''Show]
+
+deriveClasses :: [Name] -> DerivClause
+deriveClasses classNames = DerivClause Nothing (map ConT classNames)
+
+mkNamespace :: [FieldName] -> TypeName -> Name
+mkNamespace tNamespace = mkTypeName . nameSpaceType tNamespace
+
+declareCons ::
+  Bool ->
+  TypeKind ->
+  ([FieldName], TypeName) ->
+  [ConsD cat] ->
+  [Con]
+declareCons namespace tKind (tNamespace, tName) = map consR
+  where
+    consR ConsD {cName, cFields} =
+      RecC
+        (mkNamespace tNamespace cName)
+        (map (declareField namespace tKind tName) cFields)
+
+declareField ::
+  Bool ->
+  TypeKind ->
+  TypeName ->
+  FieldDefinition cat ->
+  (Name, Bang, Type)
+declareField namespace tKind tName field@FieldDefinition {fieldName} =
+  ( fieldTypeName namespace tName fieldName,
+    Bang NoSourceUnpackedness NoSourceStrictness,
+    renderFieldType tKind field
+  )
+
+renderFieldType ::
+  TypeKind ->
+  FieldDefinition cat ->
+  Type
+renderFieldType tKind FieldDefinition {fieldContent, fieldType} =
+  genFieldT
+    (declareTypeRef (isSubscription tKind) fieldType)
+    tKind
+    fieldContent
+
+fieldTypeName :: Bool -> TypeName -> FieldName -> Name
+fieldTypeName namespace tName fieldName
+  | namespace = mkFieldName (nameSpaceField tName fieldName)
+  | otherwise = mkFieldName fieldName
+
+------------------------------------------------
+genFieldT :: Type -> TypeKind -> Maybe (FieldContent TRUE cat) -> Type
+genFieldT result _ (Just (FieldArgs ArgumentsDefinition {argumentsTypename = Just argsTypename})) =
+  AppT
+    (AppT arrowType argType)
+    (AppT m' result)
+  where
+    argType = ConT $ mkTypeName argsTypename
+    arrowType = ConT ''Arrow
+genFieldT result kind _
+  | isOutputObject kind = AppT m' result
+  | otherwise = result
+
+type Arrow = (->)
diff --git a/src/Data/Morpheus/Server/TH/Transform.hs b/src/Data/Morpheus/Server/TH/Transform.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Morpheus/Server/TH/Transform.hs
@@ -0,0 +1,216 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeOperators #-}
+
+module Data.Morpheus.Server.TH.Transform
+  ( toTHDefinitions,
+    TypeDec (..),
+  )
+where
+
+-- MORPHEUS
+import Data.Morpheus.Internal.TH
+  ( infoTyVars,
+    mkTypeName,
+  )
+import Data.Morpheus.Internal.Utils
+  ( capitalTypeName,
+    elems,
+    empty,
+    singleton,
+  )
+import Data.Morpheus.Server.Internal.TH.Types (ServerTypeDefinition (..))
+import Data.Morpheus.Types.Internal.AST
+  ( ANY,
+    ArgumentsDefinition (..),
+    ConsD,
+    FieldContent (..),
+    FieldDefinition (..),
+    FieldName,
+    Fields (..),
+    FieldsDefinition,
+    IN,
+    OUT,
+    TRUE,
+    TypeContent (..),
+    TypeDefinition (..),
+    TypeKind (..),
+    TypeName,
+    TypeRef (..),
+    UnionMember (..),
+    hsTypeName,
+    kindOf,
+    lookupWith,
+    mkCons,
+    mkConsEnum,
+    toFieldName,
+  )
+import Data.Semigroup ((<>))
+import Language.Haskell.TH
+
+m_ :: TypeName
+m_ = "m"
+
+getTypeArgs :: TypeName -> [TypeDefinition ANY] -> Q (Maybe TypeName)
+getTypeArgs "__TypeKind" _ = pure Nothing
+getTypeArgs "Boolean" _ = pure Nothing
+getTypeArgs "String" _ = pure Nothing
+getTypeArgs "Int" _ = pure Nothing
+getTypeArgs "Float" _ = pure Nothing
+getTypeArgs key lib = case typeContent <$> lookupWith typeName key lib of
+  Just x -> pure (kindToTyArgs x)
+  Nothing -> getTyArgs <$> reify (mkTypeName key)
+
+getTyArgs :: Info -> Maybe TypeName
+getTyArgs x
+  | null (infoTyVars x) = Nothing
+  | otherwise = Just m_
+
+kindToTyArgs :: TypeContent TRUE ANY -> Maybe TypeName
+kindToTyArgs DataObject {} = Just m_
+kindToTyArgs DataUnion {} = Just m_
+kindToTyArgs DataInterface {} = Just m_
+kindToTyArgs _ = Nothing
+
+data TypeDec = InputType (ServerTypeDefinition IN) | OutputType (ServerTypeDefinition OUT)
+
+toTHDefinitions :: Bool -> [TypeDefinition ANY] -> Q [TypeDec]
+toTHDefinitions namespace schema = traverse generateType schema
+  where
+    --------------------------------------------
+    generateType :: TypeDefinition ANY -> Q TypeDec
+    generateType
+      typeDef@TypeDefinition
+        { typeName,
+          typeContent
+        } =
+        withType <$> genTypeContent schema toArgsTypeName typeName typeContent
+        where
+          toArgsTypeName :: FieldName -> TypeName
+          toArgsTypeName = mkArgsTypeName namespace typeName
+          tKind = kindOf typeDef
+          typeOriginal = Just typeDef
+          -------------------------
+          withType (ConsIN tCons) =
+            InputType
+              ServerTypeDefinition
+                { tName = hsTypeName typeName,
+                  tNamespace = [],
+                  tCons,
+                  typeArgD = empty,
+                  ..
+                }
+          withType (ConsOUT typeArgD tCons) =
+            OutputType
+              ServerTypeDefinition
+                { tName = hsTypeName typeName,
+                  tNamespace = [],
+                  tCons,
+                  ..
+                }
+
+mkObjectCons :: TypeName -> FieldsDefinition cat -> [ConsD cat]
+mkObjectCons typeName fields = [mkCons typeName fields]
+
+mkArgsTypeName :: Bool -> TypeName -> FieldName -> TypeName
+mkArgsTypeName namespace typeName fieldName
+  | namespace = hsTypeName typeName <> argTName
+  | otherwise = argTName
+  where
+    argTName = capitalTypeName (fieldName <> "Args")
+
+mkObjectField :: [TypeDefinition ANY] -> (FieldName -> TypeName) -> FieldDefinition OUT -> Q (FieldDefinition OUT)
+mkObjectField schema genArgsTypeName FieldDefinition {fieldName, fieldContent = cont, fieldType = typeRef@TypeRef {typeConName}, ..} =
+  do
+    typeArgs <- getTypeArgs typeConName schema
+    pure
+      FieldDefinition
+        { fieldName,
+          fieldType = typeRef {typeConName = hsTypeName typeConName, typeArgs},
+          fieldContent = cont >>= fieldCont,
+          ..
+        }
+  where
+    fieldCont :: FieldContent TRUE OUT -> Maybe (FieldContent TRUE OUT)
+    fieldCont (FieldArgs ArgumentsDefinition {arguments})
+      | not (null arguments) =
+        Just $ FieldArgs $
+          ArgumentsDefinition
+            { argumentsTypename = Just $ genArgsTypeName fieldName,
+              arguments = arguments
+            }
+    fieldCont _ = Nothing
+
+data BuildPlan
+  = ConsIN [ConsD IN]
+  | ConsOUT [ServerTypeDefinition IN] [ConsD OUT]
+
+genTypeContent ::
+  [TypeDefinition ANY] ->
+  (FieldName -> TypeName) ->
+  TypeName ->
+  TypeContent TRUE ANY ->
+  Q BuildPlan
+genTypeContent _ _ _ DataScalar {} = pure (ConsIN [])
+genTypeContent _ _ _ (DataEnum tags) = pure $ ConsIN (map mkConsEnum tags)
+genTypeContent _ _ typeName (DataInputObject fields) =
+  pure $ ConsIN (mkObjectCons typeName fields)
+genTypeContent _ _ _ DataInputUnion {} = fail "Input Unions not Supported"
+genTypeContent schema toArgsTyName typeName DataInterface {interfaceFields} = do
+  typeArgD <- genArgumentTypes toArgsTyName interfaceFields
+  objCons <- mkObjectCons typeName <$> traverse (mkObjectField schema toArgsTyName) interfaceFields
+  pure $ ConsOUT typeArgD objCons
+genTypeContent schema toArgsTyName typeName DataObject {objectFields} = do
+  typeArgD <- genArgumentTypes toArgsTyName objectFields
+  objCons <-
+    mkObjectCons typeName
+      <$> traverse (mkObjectField schema toArgsTyName) objectFields
+  pure $ ConsOUT typeArgD objCons
+genTypeContent _ _ typeName (DataUnion members) =
+  pure $ ConsOUT [] (map unionCon members)
+  where
+    unionCon UnionMember {memberName} =
+      mkCons
+        cName
+        ( singleton
+            FieldDefinition
+              { fieldName = "un" <> toFieldName cName,
+                fieldType =
+                  TypeRef
+                    { typeConName = utName,
+                      typeArgs = Just m_,
+                      typeWrappers = []
+                    },
+                fieldDescription = Nothing,
+                fieldDirectives = empty,
+                fieldContent = Nothing
+              }
+        )
+      where
+        cName = hsTypeName typeName <> utName
+        utName = hsTypeName memberName
+
+genArgumentTypes :: (FieldName -> TypeName) -> FieldsDefinition OUT -> Q [ServerTypeDefinition IN]
+genArgumentTypes genArgsTypeName fields =
+  concat <$> traverse (genArgumentType genArgsTypeName) (elems fields)
+
+genArgumentType :: (FieldName -> TypeName) -> FieldDefinition OUT -> Q [ServerTypeDefinition IN]
+genArgumentType namespaceWith FieldDefinition {fieldName, fieldContent = Just (FieldArgs ArgumentsDefinition {arguments})}
+  | not (null arguments) =
+    pure
+      [ ServerTypeDefinition
+          { tName,
+            tNamespace = empty,
+            tCons = [mkCons tName (Fields arguments)],
+            tKind = KindInputObject,
+            typeArgD = [],
+            typeOriginal = Nothing
+          }
+      ]
+  where
+    tName = hsTypeName (namespaceWith fieldName)
+genArgumentType _ _ = pure []
diff --git a/src/Data/Morpheus/Server/Types/GQLScalar.hs b/src/Data/Morpheus/Server/Types/GQLScalar.hs
deleted file mode 100644
--- a/src/Data/Morpheus/Server/Types/GQLScalar.hs
+++ /dev/null
@@ -1,72 +0,0 @@
-{-# LANGUAGE ConstrainedClassMethods #-}
-{-# LANGUAGE GADTs #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-
-module Data.Morpheus.Server.Types.GQLScalar
-  ( GQLScalar (..),
-    toScalar,
-  )
-where
-
-import Data.Morpheus.Types.Internal.AST
-  ( ScalarDefinition (..),
-    ScalarValue (..),
-    ValidValue,
-    Value (..),
-  )
-import Data.Proxy (Proxy (..))
-import Data.Text (Text)
-
-toScalar :: ValidValue -> Either Text ScalarValue
-toScalar (Scalar x) = pure x
-toScalar _ = Left ""
-
--- | GraphQL Scalar
---
--- 'parseValue' and 'serialize' should be provided for every instances manually
-class GQLScalar a where
-  -- | value parsing and validating
-  --
-  -- for exhaustive pattern matching  should be handled all scalar types : 'Int', 'Float', 'String', 'Boolean'
-  --
-  -- invalid values can be reported with 'Left' constructor :
-  --
-  -- @
-  --   parseValue String _ = Left "" -- without error message
-  --   -- or
-  --   parseValue String _ = Left "Error Message"
-  -- @
-  parseValue :: ScalarValue -> Either Text a
-
-  -- | serialization of haskell type into scalar value
-  serialize :: a -> ScalarValue
-
-  scalarValidator :: Proxy a -> ScalarDefinition
-  scalarValidator _ = ScalarDefinition {validateValue = validator}
-    where
-      validator value = do
-        scalarValue' <- toScalar value
-        (_ :: a) <- parseValue scalarValue'
-        return value
-
-instance GQLScalar Text where
-  parseValue (String x) = pure x
-  parseValue _ = Left ""
-  serialize = String
-
-instance GQLScalar Bool where
-  parseValue (Boolean x) = pure x
-  parseValue _ = Left ""
-  serialize = Boolean
-
-instance GQLScalar Int where
-  parseValue (Int x) = pure x
-  parseValue _ = Left ""
-  serialize = Int
-
-instance GQLScalar Float where
-  parseValue (Float x) = pure x
-  parseValue (Int x) = pure $ fromInteger $ toInteger x
-  parseValue _ = Left ""
-  serialize = Float
diff --git a/src/Data/Morpheus/Server/Types/GQLType.hs b/src/Data/Morpheus/Server/Types/GQLType.hs
--- a/src/Data/Morpheus/Server/Types/GQLType.hs
+++ b/src/Data/Morpheus/Server/Types/GQLType.hs
@@ -24,6 +24,7 @@
     Pair,
     Undefined (..),
   )
+import Data.Morpheus.Types.ID (ID)
 import Data.Morpheus.Types.Internal.AST
   ( DataFingerprint (..),
     QUERY,
@@ -212,3 +213,7 @@
   type KIND (a -> b) = WRAPPER
   __typeName _ = __typeName (Proxy @b)
   __typeFingerprint _ = __typeFingerprint (Proxy @b)
+
+instance GQLType ID where
+  type KIND ID = SCALAR
+  __typeFingerprint _ = internalFingerprint "ID" []
diff --git a/src/Data/Morpheus/Server/Types/ID.hs b/src/Data/Morpheus/Server/Types/ID.hs
deleted file mode 100644
--- a/src/Data/Morpheus/Server/Types/ID.hs
+++ /dev/null
@@ -1,46 +0,0 @@
-{-# LANGUAGE DeriveGeneric #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE TypeFamilies #-}
-
-module Data.Morpheus.Server.Types.ID
-  ( ID (..),
-  )
-where
-
-import qualified Data.Aeson as A
-import Data.Morpheus.Kind (SCALAR)
-import Data.Morpheus.Server.Types.GQLScalar (GQLScalar (..))
-import Data.Morpheus.Server.Types.GQLType (GQLType (..))
-import Data.Morpheus.Types.Internal.AST
-  ( ScalarValue (..),
-    internalFingerprint,
-  )
-import Data.Text
-  ( Text,
-    pack,
-  )
-import GHC.Generics (Generic)
-
--- | default GraphQL type,
--- parses only 'String' and 'Int' values,
--- serialized always as 'String'
-newtype ID = ID
-  { unpackID :: Text
-  }
-  deriving (Show, Generic)
-
-instance GQLType ID where
-  type KIND ID = SCALAR
-  __typeFingerprint _ = internalFingerprint "ID" []
-
-instance A.ToJSON ID where
-  toJSON = A.toJSON . unpackID
-
-instance A.FromJSON ID where
-  parseJSON = fmap ID . A.parseJSON
-
-instance GQLScalar ID where
-  parseValue (Int x) = return (ID $ pack $ show x)
-  parseValue (String x) = return (ID x)
-  parseValue _ = Left ""
-  serialize (ID x) = String x
diff --git a/src/Data/Morpheus/Types.hs b/src/Data/Morpheus/Types.hs
--- a/src/Data/Morpheus/Types.hs
+++ b/src/Data/Morpheus/Types.hs
@@ -16,7 +16,7 @@
     GQLResponse (..),
     ID (..),
     ScalarValue (..),
-    GQLRootResolver (..),
+    RootResolver (..),
     constRes,
     constMutRes,
     Undefined (..),
@@ -62,16 +62,16 @@
 import Data.Either (either)
 -- MORPHEUS
 
-import Data.Morpheus.Server.Deriving.Introspect (Introspect (..))
-import Data.Morpheus.Server.Types.GQLScalar
+import Data.Morpheus.Server.Deriving.Introspect (Introspect (..), introspectOUT)
+import Data.Morpheus.Server.Types.GQLType (GQLType (..))
+import Data.Morpheus.Server.Types.Types (Undefined (..))
+import Data.Morpheus.Types.GQLScalar
   ( GQLScalar
       ( parseValue,
         serialize
       ),
   )
-import Data.Morpheus.Server.Types.GQLType (GQLType (..))
-import Data.Morpheus.Server.Types.ID (ID (..))
-import Data.Morpheus.Server.Types.Types (Undefined (..))
+import Data.Morpheus.Types.ID (ID (..))
 import Data.Morpheus.Types.IO
   ( GQLRequest (..),
     GQLResponse (..),
@@ -79,6 +79,7 @@
 import Data.Morpheus.Types.Internal.AST
   ( MUTATION,
     Message,
+    OUT,
     QUERY,
     SUBSCRIPTION,
     ScalarValue (..),
@@ -203,11 +204,11 @@
 -- | GraphQL Root resolver, also the interpreter generates a GQL schema from it.
 --  'queryResolver' is required, 'mutationResolver' and 'subscriptionResolver' are optional,
 --  if your schema does not supports __mutation__ or __subscription__ , you can use __()__ for it.
-data GQLRootResolver (m :: * -> *) event (query :: (* -> *) -> *) (mut :: (* -> *) -> *) (sub :: (* -> *) -> *) = GQLRootResolver
+data RootResolver (m :: * -> *) event (query :: (* -> *) -> *) (mut :: (* -> *) -> *) (sub :: (* -> *) -> *) = RootResolver
   { queryResolver :: query (Resolver QUERY event m),
     mutationResolver :: mut (Resolver MUTATION event m),
     subscriptionResolver :: sub (Resolver SUBSCRIPTION event m)
   }
 
-interface :: (GQLType a, Introspect a) => Proxy a -> (TypeName, TypeUpdater)
-interface x = (__typeName x, introspect x)
+interface :: (GQLType a, Introspect OUT a) => Proxy a -> (TypeName, TypeUpdater)
+interface x = (__typeName x, introspectOUT x)
diff --git a/test/Feature/Holistic/API.hs b/test/Feature/Holistic/API.hs
--- a/test/Feature/Holistic/API.hs
+++ b/test/Feature/Holistic/API.hs
@@ -23,10 +23,10 @@
   ( Event,
     GQLRequest,
     GQLResponse,
-    GQLRootResolver (..),
     GQLScalar (..),
     GQLType (..),
     ID (..),
+    RootResolver (..),
     ScalarValue (..),
     liftEither,
     subscribe,
@@ -58,9 +58,9 @@
 alwaysFail :: IO (Either String a)
 alwaysFail = pure $ Left "fail with Either"
 
-rootResolver :: GQLRootResolver IO EVENT Query Mutation Subscription
+rootResolver :: RootResolver IO EVENT Query Mutation Subscription
 rootResolver =
-  GQLRootResolver
+  RootResolver
     { queryResolver =
         Query
           { user,
diff --git a/test/Feature/Holistic/introspection/schemaTypes/__Type/response.json b/test/Feature/Holistic/introspection/schemaTypes/__Type/response.json
--- a/test/Feature/Holistic/introspection/schemaTypes/__Type/response.json
+++ b/test/Feature/Holistic/introspection/schemaTypes/__Type/response.json
@@ -51,7 +51,7 @@
                 "name": "Boolean",
                 "ofType": null
               },
-              "defaultValue": null
+              "defaultValue": "false"
             }
           ],
           "type": {
@@ -118,7 +118,7 @@
                 "name": "Boolean",
                 "ofType": null
               },
-              "defaultValue": null
+              "defaultValue": "false"
             }
           ],
           "type": {
diff --git a/test/Feature/Holistic/parsing/complex/response.json b/test/Feature/Holistic/parsing/complex/response.json
--- a/test/Feature/Holistic/parsing/complex/response.json
+++ b/test/Feature/Holistic/parsing/complex/response.json
@@ -1,7 +1,7 @@
 {
   "errors": [
     {
-      "message": "Argument \"coordinates\" got invalid value. in field \"longitude\": Expected type \"Int!\" found [null,[[],[{\"uid\":\"1\"}]]].",
+      "message": "Argument \"coordinates\" got invalid value. in field \"longitude\": Expected type \"Int!\" found [null, [[], [{uid: \"1\"}]]].",
       "locations": [{ "line": 8, "column": 23 }]
     },
     {
@@ -9,7 +9,7 @@
       "locations": [{ "line": 11, "column": 23 }]
     },
     {
-      "message": "Argument \"cityID\" got invalid value. Expected type \"TestEnum!\" found \"HH\".",
+      "message": "Argument \"cityID\" got invalid value. Expected type \"TestEnum!\" found HH.",
       "locations": [{ "line": 15, "column": 25 }]
     },
     {
diff --git a/test/Feature/Holistic/selection/directives/default/wrongArgumentType/response.json b/test/Feature/Holistic/selection/directives/default/wrongArgumentType/response.json
--- a/test/Feature/Holistic/selection/directives/default/wrongArgumentType/response.json
+++ b/test/Feature/Holistic/selection/directives/default/wrongArgumentType/response.json
@@ -17,7 +17,7 @@
       "locations": [{ "line": 7, "column": 31 }]
     },
     {
-      "message": "Argument \"if\" got invalid value. Expected type \"Boolean!\" found \"SomeEnum\".",
+      "message": "Argument \"if\" got invalid value. Expected type \"Boolean!\" found SomeEnum.",
       "locations": [{ "line": 8, "column": 29 }]
     },
     {
diff --git a/test/Feature/Input/DefaultValue/API.hs b/test/Feature/Input/DefaultValue/API.hs
new file mode 100644
--- /dev/null
+++ b/test/Feature/Input/DefaultValue/API.hs
@@ -0,0 +1,51 @@
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE DerivingStrategies #-}
+{-# LANGUAGE DuplicateRecordFields #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeFamilies #-}
+
+module Feature.Input.DefaultValue.API
+  ( api,
+    rootResolver,
+  )
+where
+
+import Data.Morpheus (interpreter)
+import Data.Morpheus.Document (importGQLDocument)
+import Data.Morpheus.Types
+  ( GQLRequest,
+    GQLResponse,
+    ID (..),
+    RootResolver (..),
+    Undefined (..),
+  )
+import Data.Text (Text, pack)
+
+importGQLDocument "test/Feature/Input/DefaultValue/schema.gql"
+
+rootResolver :: RootResolver IO () Query Undefined Undefined
+rootResolver =
+  RootResolver
+    { queryResolver = Query {user, testSimple},
+      mutationResolver = Undefined,
+      subscriptionResolver = Undefined
+    }
+  where
+    user :: Applicative m => m (Maybe (User m))
+    user =
+      pure
+        $ Just
+        $ User
+          { inputs = pure . pack . show
+          }
+    testSimple = pure . pack . show
+
+-----------------------------------
+api :: GQLRequest -> IO GQLResponse
+api = interpreter rootResolver
diff --git a/test/Feature/Input/DefaultValue/cases.json b/test/Feature/Input/DefaultValue/cases.json
new file mode 100644
--- /dev/null
+++ b/test/Feature/Input/DefaultValue/cases.json
@@ -0,0 +1,22 @@
+[
+  {
+    "path": "intorspection/input-simple",
+    "description": "test introspection of input Object"
+  },
+  {
+    "path": "intorspection/input-compound",
+    "description": "test introspection of input Object with inputObject as field"
+  },
+  {
+    "path": "intorspection/arguments",
+    "description": "test introspection of argument default values"
+  },
+  {
+    "path": "resolving/simple",
+    "description": "missing fields must be filled with default values"
+  },
+  {
+    "path": "resolving/compound",
+    "description": "missing fields must be filled with default values"
+  }
+]
diff --git a/test/Feature/Input/DefaultValue/intorspection/arguments/query.gql b/test/Feature/Input/DefaultValue/intorspection/arguments/query.gql
new file mode 100644
--- /dev/null
+++ b/test/Feature/Input/DefaultValue/intorspection/arguments/query.gql
@@ -0,0 +1,76 @@
+query Get__Type {
+  type2: __type(name: "User") {
+    ...FullType
+  }
+}
+
+fragment FullType on __Type {
+  kind
+  name
+  fields(includeDeprecated: true) {
+    name
+    args {
+      ...InputValue
+    }
+    type {
+      ...TypeRef
+    }
+    isDeprecated
+    deprecationReason
+  }
+  inputFields {
+    ...InputValue
+  }
+  interfaces {
+    ...TypeRef
+  }
+  enumValues(includeDeprecated: true) {
+    name
+    isDeprecated
+    deprecationReason
+  }
+  possibleTypes {
+    ...TypeRef
+  }
+}
+
+fragment InputValue on __InputValue {
+  name
+  type {
+    ...TypeRef
+  }
+  defaultValue
+}
+
+fragment TypeRef on __Type {
+  kind
+  name
+  ofType {
+    kind
+    name
+    ofType {
+      kind
+      name
+      ofType {
+        kind
+        name
+        ofType {
+          kind
+          name
+          ofType {
+            kind
+            name
+            ofType {
+              kind
+              name
+              ofType {
+                kind
+                name
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/test/Feature/Input/DefaultValue/intorspection/arguments/response.json b/test/Feature/Input/DefaultValue/intorspection/arguments/response.json
new file mode 100644
--- /dev/null
+++ b/test/Feature/Input/DefaultValue/intorspection/arguments/response.json
@@ -0,0 +1,61 @@
+{
+  "data": {
+    "type2": {
+      "kind": "OBJECT",
+      "name": "User",
+      "fields": [
+        {
+          "name": "inputs",
+          "args": [
+            {
+              "name": "inputCompound",
+              "type": {
+                "kind": "NON_NULL",
+                "name": null,
+                "ofType": {
+                  "kind": "INPUT_OBJECT",
+                  "name": "InputCompound",
+                  "ofType": null
+                }
+              },
+              "defaultValue": "{inputField2: \"value from argument inputCompound\", inputField3: [{fieldWithDefault: \"value2 from inputField3\", simpleField: EnumA}, {fieldWithDefault: \"value from fieldWithDefault\", simpleField: EnumA}], inputField4: [{fieldWithDefault: \"value from fieldWithDefault\", simpleField: EnumB}]}"
+            },
+            {
+              "name": "input",
+              "type": {
+                "kind": "INPUT_OBJECT",
+                "name": "InputSimple",
+                "ofType": null
+              },
+              "defaultValue": null
+            },
+            {
+              "name": "comment",
+              "type": {
+                "kind": "SCALAR",
+                "name": "String",
+                "ofType": null
+              },
+              "defaultValue": "\"test string\""
+            }
+          ],
+          "type": {
+            "kind": "NON_NULL",
+            "name": null,
+            "ofType": {
+              "kind": "SCALAR",
+              "name": "String",
+              "ofType": null
+            }
+          },
+          "isDeprecated": false,
+          "deprecationReason": null
+        }
+      ],
+      "inputFields": null,
+      "interfaces": [],
+      "enumValues": null,
+      "possibleTypes": null
+    }
+  }
+}
diff --git a/test/Feature/Input/DefaultValue/intorspection/input-compound/query.gql b/test/Feature/Input/DefaultValue/intorspection/input-compound/query.gql
new file mode 100644
--- /dev/null
+++ b/test/Feature/Input/DefaultValue/intorspection/input-compound/query.gql
@@ -0,0 +1,76 @@
+query Get__Type {
+  type2: __type(name: "InputCompound") {
+    ...FullType
+  }
+}
+
+fragment FullType on __Type {
+  kind
+  name
+  fields(includeDeprecated: true) {
+    name
+    args {
+      ...InputValue
+    }
+    type {
+      ...TypeRef
+    }
+    isDeprecated
+    deprecationReason
+  }
+  inputFields {
+    ...InputValue
+  }
+  interfaces {
+    ...TypeRef
+  }
+  enumValues(includeDeprecated: true) {
+    name
+    isDeprecated
+    deprecationReason
+  }
+  possibleTypes {
+    ...TypeRef
+  }
+}
+
+fragment InputValue on __InputValue {
+  name
+  type {
+    ...TypeRef
+  }
+  defaultValue
+}
+
+fragment TypeRef on __Type {
+  kind
+  name
+  ofType {
+    kind
+    name
+    ofType {
+      kind
+      name
+      ofType {
+        kind
+        name
+        ofType {
+          kind
+          name
+          ofType {
+            kind
+            name
+            ofType {
+              kind
+              name
+              ofType {
+                kind
+                name
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/test/Feature/Input/DefaultValue/intorspection/input-compound/response.json b/test/Feature/Input/DefaultValue/intorspection/input-compound/response.json
new file mode 100644
--- /dev/null
+++ b/test/Feature/Input/DefaultValue/intorspection/input-compound/response.json
@@ -0,0 +1,61 @@
+{
+  "data": {
+    "type2": {
+      "kind": "INPUT_OBJECT",
+      "name": "InputCompound",
+      "fields": null,
+      "inputFields": [
+        {
+          "name": "inputField2",
+          "type": {
+            "kind": "NON_NULL",
+            "name": null,
+            "ofType": {
+              "kind": "SCALAR",
+              "name": "String",
+              "ofType": null
+            }
+          },
+          "defaultValue": "\"value from inputField2\""
+        },
+        {
+          "name": "inputField3",
+          "type": {
+            "kind": "NON_NULL",
+            "name": null,
+            "ofType": {
+              "kind": "LIST",
+              "name": null,
+              "ofType": {
+                "kind": "INPUT_OBJECT",
+                "name": "InputSimple",
+                "ofType": null
+              }
+            }
+          },
+          "defaultValue": "[{fieldWithDefault: \"value2 from inputField3\", simpleField: EnumA}, {fieldWithDefault: \"value from fieldWithDefault\", simpleField: EnumA}]"
+        },
+        {
+          "name": "inputField4",
+          "type": {
+            "kind": "NON_NULL",
+            "name": null,
+            "ofType": {
+              "kind": "LIST",
+              "name": null,
+              "ofType": {
+                "kind": "INPUT_OBJECT",
+                "name": "InputSimple",
+                "ofType": null
+              }
+            }
+          },
+          "defaultValue": "[{fieldWithDefault: \"value from fieldWithDefault\", simpleField: EnumB}]"
+        }
+      ],
+      "interfaces": null,
+      "enumValues": null,
+      "possibleTypes": null
+    }
+  }
+}
diff --git a/test/Feature/Input/DefaultValue/intorspection/input-simple/query.gql b/test/Feature/Input/DefaultValue/intorspection/input-simple/query.gql
new file mode 100644
--- /dev/null
+++ b/test/Feature/Input/DefaultValue/intorspection/input-simple/query.gql
@@ -0,0 +1,76 @@
+query Get__Type {
+  type2: __type(name: "InputSimple") {
+    ...FullType
+  }
+}
+
+fragment FullType on __Type {
+  kind
+  name
+  fields(includeDeprecated: true) {
+    name
+    args {
+      ...InputValue
+    }
+    type {
+      ...TypeRef
+    }
+    isDeprecated
+    deprecationReason
+  }
+  inputFields {
+    ...InputValue
+  }
+  interfaces {
+    ...TypeRef
+  }
+  enumValues(includeDeprecated: true) {
+    name
+    isDeprecated
+    deprecationReason
+  }
+  possibleTypes {
+    ...TypeRef
+  }
+}
+
+fragment InputValue on __InputValue {
+  name
+  type {
+    ...TypeRef
+  }
+  defaultValue
+}
+
+fragment TypeRef on __Type {
+  kind
+  name
+  ofType {
+    kind
+    name
+    ofType {
+      kind
+      name
+      ofType {
+        kind
+        name
+        ofType {
+          kind
+          name
+          ofType {
+            kind
+            name
+            ofType {
+              kind
+              name
+              ofType {
+                kind
+                name
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/test/Feature/Input/DefaultValue/intorspection/input-simple/response.json b/test/Feature/Input/DefaultValue/intorspection/input-simple/response.json
new file mode 100644
--- /dev/null
+++ b/test/Feature/Input/DefaultValue/intorspection/input-simple/response.json
@@ -0,0 +1,36 @@
+{
+  "data": {
+    "type2": {
+      "kind": "INPUT_OBJECT",
+      "name": "InputSimple",
+      "fields": null,
+      "inputFields": [
+        {
+          "name": "fieldWithDefault",
+          "type": {
+            "kind": "NON_NULL",
+            "name": null,
+            "ofType": {
+              "kind": "SCALAR",
+              "name": "ID",
+              "ofType": null
+            }
+          },
+          "defaultValue": "\"value from fieldWithDefault\""
+        },
+        {
+          "name": "simpleField",
+          "type": {
+            "kind": "ENUM",
+            "name": "TestEnum",
+            "ofType": null
+          },
+          "defaultValue": null
+        }
+      ],
+      "interfaces": null,
+      "enumValues": null,
+      "possibleTypes": null
+    }
+  }
+}
diff --git a/test/Feature/Input/DefaultValue/resolving/compound/query.gql b/test/Feature/Input/DefaultValue/resolving/compound/query.gql
new file mode 100644
--- /dev/null
+++ b/test/Feature/Input/DefaultValue/resolving/compound/query.gql
@@ -0,0 +1,5 @@
+query Compound {
+  user {
+    inputs(input: { simpleField: EnumA })
+  }
+}
diff --git a/test/Feature/Input/DefaultValue/resolving/compound/response.json b/test/Feature/Input/DefaultValue/resolving/compound/response.json
new file mode 100644
--- /dev/null
+++ b/test/Feature/Input/DefaultValue/resolving/compound/response.json
@@ -0,0 +1,7 @@
+{
+  "data": {
+    "user": {
+      "inputs": "InputsArgs {inputCompound = InputCompound {inputField2 = \"value from argument inputCompound\", inputField3 = [Just (InputSimple {fieldWithDefault = ID {unpackID = \"value2 from inputField3\"}, simpleField = Just EnumA}),Just (InputSimple {fieldWithDefault = ID {unpackID = \"value from fieldWithDefault\"}, simpleField = Just EnumA})], inputField4 = [Just (InputSimple {fieldWithDefault = ID {unpackID = \"value from fieldWithDefault\"}, simpleField = Just EnumB})]}, input = Just (InputSimple {fieldWithDefault = ID {unpackID = \"value from fieldWithDefault\"}, simpleField = Just EnumA}), comment = Just \"test string\"}"
+    }
+  }
+}
diff --git a/test/Feature/Input/DefaultValue/resolving/simple/query.gql b/test/Feature/Input/DefaultValue/resolving/simple/query.gql
new file mode 100644
--- /dev/null
+++ b/test/Feature/Input/DefaultValue/resolving/simple/query.gql
@@ -0,0 +1,3 @@
+query Simple {
+  testSimple(i1: { simpleField: EnumA })
+}
diff --git a/test/Feature/Input/DefaultValue/resolving/simple/response.json b/test/Feature/Input/DefaultValue/resolving/simple/response.json
new file mode 100644
--- /dev/null
+++ b/test/Feature/Input/DefaultValue/resolving/simple/response.json
@@ -0,0 +1,5 @@
+{
+  "data": {
+    "testSimple": "TestSimpleArgs {i1 = Just (InputSimple {fieldWithDefault = ID {unpackID = \"value from fieldWithDefault\"}, simpleField = Just EnumA}), i2 = Just \"test string\"}"
+  }
+}
diff --git a/test/Feature/Input/DefaultValue/schema.gql b/test/Feature/Input/DefaultValue/schema.gql
new file mode 100644
--- /dev/null
+++ b/test/Feature/Input/DefaultValue/schema.gql
@@ -0,0 +1,34 @@
+enum TestEnum {
+  EnumA
+  EnumB
+  EnumC
+}
+
+input InputSimple {
+  fieldWithDefault: ID! = "value from fieldWithDefault"
+  simpleField: TestEnum
+}
+
+input InputCompound {
+  inputField2: String! = "value from inputField2"
+  inputField3: [InputSimple]! = [
+    { fieldWithDefault: "value2 from inputField3", simpleField: EnumA }
+    { simpleField: EnumA }
+  ]
+  inputField4: [InputSimple]! = [{ simpleField: EnumB }]
+}
+
+type User {
+  inputs(
+    inputCompound: InputCompound! = {
+      inputField2: "value from argument inputCompound"
+    }
+    input: InputSimple
+    comment: String = "test string"
+  ): String!
+}
+
+type Query {
+  user: User
+  testSimple(i1: InputSimple, i2: String = "test string"): String!
+}
diff --git a/test/Feature/Input/Enum/API.hs b/test/Feature/Input/Enum/API.hs
--- a/test/Feature/Input/Enum/API.hs
+++ b/test/Feature/Input/Enum/API.hs
@@ -11,7 +11,7 @@
 
 import Data.Morpheus (interpreter)
 import Data.Morpheus.Kind (ENUM)
-import Data.Morpheus.Types (GQLRequest, GQLResponse, GQLRootResolver (..), GQLType (..), Undefined (..))
+import Data.Morpheus.Types (GQLRequest, GQLResponse, GQLType (..), RootResolver (..), Undefined (..))
 import GHC.Generics (Generic)
 
 data TwoCon
@@ -62,9 +62,9 @@
   }
   deriving (Generic, GQLType)
 
-rootResolver :: GQLRootResolver IO () Query Undefined Undefined
+rootResolver :: RootResolver IO () Query Undefined Undefined
 rootResolver =
-  GQLRootResolver
+  RootResolver
     { queryResolver = Query {test = testRes, test2 = testRes, test3 = testRes},
       mutationResolver = Undefined,
       subscriptionResolver = Undefined
diff --git a/test/Feature/Input/Enum/cases.json b/test/Feature/Input/Enum/cases.json
--- a/test/Feature/Input/Enum/cases.json
+++ b/test/Feature/Input/Enum/cases.json
@@ -36,7 +36,23 @@
     "description": "decode string to correct Haskell Enum Representation"
   },
   {
-    "path":"decodeInvalidValue",
-    "description":"fail on invalid enum value"
+    "path": "decodeInvalidValue",
+    "description": "fail on invalid enum value"
+  },
+  {
+    "path": "invalidStringInput",
+    "description": "fail on String inputs for Enum Values"
+  },
+  {
+    "path": "invalidStringDefaultValue",
+    "description": "fail on String inputs for Enum Values"
+  },
+  {
+    "path": "validEnumFromJSONVariable",
+    "description": "accept strings as enum if it is received from json variable"
+  },
+  {
+    "path": "invalidEnumFromJSONVariable",
+    "description": "reject invalid strings as enum from json variable"
   }
 ]
diff --git a/test/Feature/Input/Enum/decodeInvalidValue/response.json b/test/Feature/Input/Enum/decodeInvalidValue/response.json
--- a/test/Feature/Input/Enum/decodeInvalidValue/response.json
+++ b/test/Feature/Input/Enum/decodeInvalidValue/response.json
@@ -1,7 +1,7 @@
 {
   "errors": [
     {
-      "message": "Argument \"level\" got invalid value. Expected type \"TwoCon!\" found \"LK\".",
+      "message": "Argument \"level\" got invalid value. Expected type \"TwoCon!\" found LK.",
       "locations": [
         {
           "line": 2,
diff --git a/test/Feature/Input/Enum/invalidEnumFromJSONVariable/query.gql b/test/Feature/Input/Enum/invalidEnumFromJSONVariable/query.gql
new file mode 100644
--- /dev/null
+++ b/test/Feature/Input/Enum/invalidEnumFromJSONVariable/query.gql
@@ -0,0 +1,3 @@
+query ValidDecoding($x: TwoCon!) {
+  test2(level: $x)
+}
diff --git a/test/Feature/Input/Enum/invalidEnumFromJSONVariable/response.json b/test/Feature/Input/Enum/invalidEnumFromJSONVariable/response.json
new file mode 100644
--- /dev/null
+++ b/test/Feature/Input/Enum/invalidEnumFromJSONVariable/response.json
@@ -0,0 +1,8 @@
+{
+  "errors": [
+    {
+      "message": "Variable \"$x\" got invalid value. Expected type \"TwoCon!\" found \"BLA\".",
+      "locations": [{ "line": 1, "column": 21 }]
+    }
+  ]
+}
diff --git a/test/Feature/Input/Enum/invalidEnumFromJSONVariable/variables.json b/test/Feature/Input/Enum/invalidEnumFromJSONVariable/variables.json
new file mode 100644
--- /dev/null
+++ b/test/Feature/Input/Enum/invalidEnumFromJSONVariable/variables.json
@@ -0,0 +1,1 @@
+{ "x": "BLA" }
diff --git a/test/Feature/Input/Enum/invalidStringDefaultValue/query.gql b/test/Feature/Input/Enum/invalidStringDefaultValue/query.gql
new file mode 100644
--- /dev/null
+++ b/test/Feature/Input/Enum/invalidStringDefaultValue/query.gql
@@ -0,0 +1,3 @@
+query ValidDecoding($x: TwoCon! = "LA") {
+  test2(level: $x)
+}
diff --git a/test/Feature/Input/Enum/invalidStringDefaultValue/response.json b/test/Feature/Input/Enum/invalidStringDefaultValue/response.json
new file mode 100644
--- /dev/null
+++ b/test/Feature/Input/Enum/invalidStringDefaultValue/response.json
@@ -0,0 +1,8 @@
+{
+  "errors": [
+    {
+      "message": "Variable \"$x\" got invalid value. Expected type \"TwoCon!\" found \"LA\".",
+      "locations": [{ "line": 1, "column": 21 }]
+    }
+  ]
+}
diff --git a/test/Feature/Input/Enum/invalidStringInput/query.gql b/test/Feature/Input/Enum/invalidStringInput/query.gql
new file mode 100644
--- /dev/null
+++ b/test/Feature/Input/Enum/invalidStringInput/query.gql
@@ -0,0 +1,3 @@
+query ValidDecoding {
+  test2(level: "LA")
+}
diff --git a/test/Feature/Input/Enum/invalidStringInput/response.json b/test/Feature/Input/Enum/invalidStringInput/response.json
new file mode 100644
--- /dev/null
+++ b/test/Feature/Input/Enum/invalidStringInput/response.json
@@ -0,0 +1,8 @@
+{
+  "errors": [
+    {
+      "message": "Argument \"level\" got invalid value. Expected type \"TwoCon!\" found \"LA\".",
+      "locations": [{ "line": 2, "column": 9 }]
+    }
+  ]
+}
diff --git a/test/Feature/Input/Enum/validEnumFromJSONVariable/query.gql b/test/Feature/Input/Enum/validEnumFromJSONVariable/query.gql
new file mode 100644
--- /dev/null
+++ b/test/Feature/Input/Enum/validEnumFromJSONVariable/query.gql
@@ -0,0 +1,3 @@
+query ValidDecoding($x: TwoCon!) {
+  test2(level: $x)
+}
diff --git a/test/Feature/Input/Enum/validEnumFromJSONVariable/response.json b/test/Feature/Input/Enum/validEnumFromJSONVariable/response.json
new file mode 100644
--- /dev/null
+++ b/test/Feature/Input/Enum/validEnumFromJSONVariable/response.json
@@ -0,0 +1,5 @@
+{
+  "data": {
+    "test2": "LA"
+  }
+}
diff --git a/test/Feature/Input/Enum/validEnumFromJSONVariable/variables.json b/test/Feature/Input/Enum/validEnumFromJSONVariable/variables.json
new file mode 100644
--- /dev/null
+++ b/test/Feature/Input/Enum/validEnumFromJSONVariable/variables.json
@@ -0,0 +1,1 @@
+{ "x": "LA" }
diff --git a/test/Feature/Input/Object/API.hs b/test/Feature/Input/Object/API.hs
--- a/test/Feature/Input/Object/API.hs
+++ b/test/Feature/Input/Object/API.hs
@@ -14,8 +14,8 @@
 import Data.Morpheus.Types
   ( GQLRequest,
     GQLResponse,
-    GQLRootResolver (..),
     GQLType (..),
+    RootResolver (..),
     Undefined (..),
   )
 import Data.Text
@@ -50,9 +50,9 @@
   }
   deriving (Generic, GQLType)
 
-rootResolver :: GQLRootResolver IO () Query Undefined Undefined
+rootResolver :: RootResolver IO () Query Undefined Undefined
 rootResolver =
-  GQLRootResolver
+  RootResolver
     { queryResolver = Query {input = testRes},
       mutationResolver = Undefined,
       subscriptionResolver = Undefined
diff --git a/test/Feature/Input/Scalar/API.hs b/test/Feature/Input/Scalar/API.hs
--- a/test/Feature/Input/Scalar/API.hs
+++ b/test/Feature/Input/Scalar/API.hs
@@ -13,8 +13,8 @@
 import Data.Morpheus.Types
   ( GQLRequest,
     GQLResponse,
-    GQLRootResolver (..),
     GQLType,
+    RootResolver (..),
     Undefined (..),
   )
 import GHC.Generics (Generic)
@@ -36,9 +36,9 @@
   }
   deriving (Generic, GQLType)
 
-rootResolver :: GQLRootResolver IO () Query Undefined Undefined
+rootResolver :: RootResolver IO () Query Undefined Undefined
 rootResolver =
-  GQLRootResolver
+  RootResolver
     { queryResolver = Query {testFloat = testRes, testInt = testRes},
       mutationResolver = Undefined,
       subscriptionResolver = Undefined
diff --git a/test/Feature/InputType/API.hs b/test/Feature/InputType/API.hs
--- a/test/Feature/InputType/API.hs
+++ b/test/Feature/InputType/API.hs
@@ -13,9 +13,9 @@
 import Data.Morpheus.Types
   ( GQLRequest,
     GQLResponse,
-    GQLRootResolver (..),
     GQLType (..),
     ResolverQ,
+    RootResolver (..),
     Undefined (..),
   )
 import Data.Text (Text)
@@ -44,9 +44,9 @@
   }
   deriving (Generic, GQLType)
 
-rootResolver :: GQLRootResolver IO () Query Undefined Undefined
+rootResolver :: RootResolver IO () Query Undefined Undefined
 rootResolver =
-  GQLRootResolver
+  RootResolver
     { queryResolver =
         Query
           { q1 =
diff --git a/test/Feature/InputType/variables/invalidValue/invalidDefaultValue/response.json b/test/Feature/InputType/variables/invalidValue/invalidDefaultValue/response.json
--- a/test/Feature/InputType/variables/invalidValue/invalidDefaultValue/response.json
+++ b/test/Feature/InputType/variables/invalidValue/invalidDefaultValue/response.json
@@ -1,7 +1,7 @@
 {
   "errors": [
     {
-      "message": "Variable \"$v1\" got invalid value. Expected type \"[[[Int!]!]]!\" found {\"id\":\"12\"}.",
+      "message": "Variable \"$v1\" got invalid value. Expected type \"[[[Int!]!]]!\" found {id: \"12\"}.",
       "locations": [
         {
           "line": 1,
diff --git a/test/Feature/Schema/API.hs b/test/Feature/Schema/API.hs
--- a/test/Feature/Schema/API.hs
+++ b/test/Feature/Schema/API.hs
@@ -10,7 +10,7 @@
 where
 
 import Data.Morpheus (interpreter)
-import Data.Morpheus.Types (GQLRequest, GQLResponse, GQLRootResolver (..), GQLType (..), Undefined (..))
+import Data.Morpheus.Types (GQLRequest, GQLResponse, GQLType (..), RootResolver (..), Undefined (..))
 import Data.Text (Text)
 import qualified Feature.Schema.A2 as A2 (A (..))
 import GHC.Generics (Generic)
@@ -27,9 +27,9 @@
   }
   deriving (Generic, GQLType)
 
-rootResolver :: GQLRootResolver IO () Query Undefined Undefined
+rootResolver :: RootResolver IO () Query Undefined Undefined
 rootResolver =
-  GQLRootResolver
+  RootResolver
     { queryResolver = Query {a1 = A "" 0, a2 = A2.A 0},
       mutationResolver = Undefined,
       subscriptionResolver = Undefined
diff --git a/test/Feature/TypeInference/API.hs b/test/Feature/TypeInference/API.hs
--- a/test/Feature/TypeInference/API.hs
+++ b/test/Feature/TypeInference/API.hs
@@ -16,8 +16,8 @@
 import Data.Morpheus.Types
   ( GQLRequest,
     GQLResponse,
-    GQLRootResolver (..),
     GQLType (..),
+    RootResolver (..),
     Undefined (..),
   )
 import Data.Text
@@ -84,9 +84,9 @@
   }
   deriving (Generic, GQLType)
 
-rootResolver :: GQLRootResolver IO () Query Undefined Undefined
+rootResolver :: RootResolver IO () Query Undefined Undefined
 rootResolver =
-  GQLRootResolver
+  RootResolver
     { queryResolver = Query {deity = deityRes, character, showMonster},
       mutationResolver = Undefined,
       subscriptionResolver = Undefined
diff --git a/test/Feature/UnionType/API.hs b/test/Feature/UnionType/API.hs
--- a/test/Feature/UnionType/API.hs
+++ b/test/Feature/UnionType/API.hs
@@ -13,9 +13,9 @@
 import Data.Morpheus.Types
   ( GQLRequest,
     GQLResponse,
-    GQLRootResolver (..),
     GQLType (..),
     ResolverQ,
+    RootResolver (..),
     Undefined (..),
   )
 import Data.Text (Text)
@@ -54,9 +54,9 @@
 resolveUnion _ =
   return [SumA A {aText = "at", aInt = 1}, SumB B {bText = "bt", bInt = 2}]
 
-rootResolver :: GQLRootResolver IO () Query Undefined Undefined
+rootResolver :: RootResolver IO () Query Undefined Undefined
 rootResolver =
-  GQLRootResolver
+  RootResolver
     { queryResolver =
         Query
           { union = resolveUnion,
diff --git a/test/Feature/WrappedTypeName/API.hs b/test/Feature/WrappedTypeName/API.hs
--- a/test/Feature/WrappedTypeName/API.hs
+++ b/test/Feature/WrappedTypeName/API.hs
@@ -15,8 +15,8 @@
     Event,
     GQLRequest,
     GQLResponse,
-    GQLRootResolver (..),
     GQLType (..),
+    RootResolver (..),
     constRes,
     subscribe,
   )
@@ -66,9 +66,9 @@
   }
   deriving (Generic, GQLType)
 
-rootResolver :: GQLRootResolver IO EVENT Query Mutation Subscription
+rootResolver :: RootResolver IO EVENT Query Mutation Subscription
 rootResolver =
-  GQLRootResolver
+  RootResolver
     { queryResolver = Query {a1 = WA {aText = const $ pure "test1", aInt = 0}, a2 = Nothing, a3 = Nothing},
       mutationResolver = Mutation {mut1 = Nothing, mut2 = Nothing, mut3 = Nothing},
       subscriptionResolver =
diff --git a/test/Rendering/Schema.hs b/test/Rendering/Schema.hs
--- a/test/Rendering/Schema.hs
+++ b/test/Rendering/Schema.hs
@@ -18,10 +18,10 @@
 import Data.Morpheus.Document (importGQLDocumentWithNamespace)
 import Data.Morpheus.Kind (SCALAR)
 import Data.Morpheus.Types
-  ( GQLRootResolver (..),
-    GQLScalar (..),
+  ( GQLScalar (..),
     GQLType (..),
     ID (..),
+    RootResolver (..),
     ScalarValue (..),
     Undefined (..),
   )
@@ -42,5 +42,5 @@
 
 importGQLDocumentWithNamespace "test/Rendering/schema.gql"
 
-schemaProxy :: Proxy (GQLRootResolver IO () Query Undefined Undefined)
-schemaProxy = Proxy @(GQLRootResolver IO () Query Undefined Undefined)
+schemaProxy :: Proxy (RootResolver IO () Query Undefined Undefined)
+schemaProxy = Proxy @(RootResolver IO () Query Undefined Undefined)
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -8,6 +8,9 @@
 import qualified Feature.Holistic.API as Holistic
   ( api,
   )
+import qualified Feature.Input.DefaultValue.API as DefaultValue
+  ( api,
+  )
 import qualified Feature.Input.Enum.API as InputEnum
   ( api,
   )
@@ -50,6 +53,7 @@
   inputEnum <- testFeature InputEnum.api "Feature/Input/Enum"
   inputScalar <- testFeature InputScalar.api "Feature/Input/Scalar"
   inputObject <- testFeature InputObject.api "Feature/Input/Object"
+  defaultValue <- testFeature DefaultValue.api "Feature/Input/DefaultValue"
   inference <- testFeature Inference.api "Feature/TypeInference"
   subscription <- testSubsriptions
   defaultMain
@@ -65,6 +69,7 @@
           inputObject,
           testSchemaRendering,
           inference,
-          subscription
+          subscription,
+          defaultValue
         ]
     )
diff --git a/test/Subscription/API.hs b/test/Subscription/API.hs
--- a/test/Subscription/API.hs
+++ b/test/Subscription/API.hs
@@ -16,8 +16,8 @@
 import Data.Morpheus.Document (importGQLDocument)
 import Data.Morpheus.Types
   ( Event (..),
-    GQLRootResolver (..),
     Input,
+    RootResolver (..),
     Stream,
     subscribe,
   )
@@ -49,9 +49,9 @@
         age = pure age
       }
 
-rootResolver :: GQLRootResolver (SubM EVENT) EVENT Query Mutation Subscription
+rootResolver :: RootResolver (SubM EVENT) EVENT Query Mutation Subscription
 rootResolver =
-  GQLRootResolver
+  RootResolver
     { queryResolver =
         Query
           { queryField = pure ""
