graphql-compose

raw JSON →
9.1.0 verified Sat Apr 25 auth: no javascript

Programmatic GraphQL schema builder with a type registry for constructing and editing output/input types, fields, arguments, and interfaces. v9.1.0 (stable) supports GraphQL v14–16, ships TypeScript definitions, and is ESM-only. Key differentiators vs graphql-tools: Resolver abstraction for CRUD operations, built-in projection parser from AST, OutputType-to-InputType converter, and plugin ecosystem (mongoose, JSON, Elasticsearch). Releases ~monthly; recent fixes address security (removed object-path) and TypeScript compatibility.

error TypeError: Cannot read properties of undefined (reading 'getType')
cause Resolver referenced a type that hasn't been added to the schemaComposer yet.
fix
Ensure the type is created (e.g., schemaComposer.createObjectTC) before referencing it in resolver type field.
error Error: Schema must contain uniquely named types but contains multiple types named "Query".
cause Accidentally created duplicate root types via schemaComposer.Query.addFields() and schemaComposer.createObjectTC({ name: 'Query'}).
fix
Do not create an object type composer with same name as root types. Use schemaComposer.Query directly.
error GraphQLError: Field "user" must not have a selection since type "User" has no subfields.
cause Resolver type is set to UserTC but resolver does not return object; or query selects subfields but schema built incorrectly.
fix
Verify resolver returns an object matching UserTC fields and that schemaComposer.buildSchema() is called after adding resolvers.
error Module not found: Can't resolve 'graphql' in ...
cause Missing graphql peer dependency.
fix
npm install graphql@^14.2.0 || ^15.0.0 || ^16.0.0
breaking v9 dropped support for GraphQL v13 and older; peer dependency now requires graphql@^14.2.0 || ^15.0.0 || ^16.0.0
fix Upgrade graphql to v14, v15, or v16. If locked to v13, stay on graphql-compose v8.
breaking v9 is ESM-only; CommonJS require() will fail.
fix Use import statements or dynamic import(). If CJS required, stick with v8.
deprecated Removed object-path dependency due to security alerts; use native lodash.get or optional chaining.
fix If using deep path access, migrate to ES2020 optional chaining or lodash.get.
gotcha schemaComposer is a singleton; importing it multiple times yields the same instance. Do not create new instances with new SchemaComposer() unless you intend separate registries.
fix Use import { schemaComposer } for shared app schema; use new SchemaComposer() for isolated test contexts.
deprecated ObjectTypeComposer.setField() mutates the type in-place; future versions may prefer immutable patterns.
fix Consider using addFields or removeField methods; check for deprecation warnings in v10.
npm install graphql-compose
yarn add graphql-compose
pnpm add graphql-compose

Creates an object type composer for User, adds a resolver, attaches to Query root, builds schema.

import { schemaComposer, ObjectTypeComposer, Resolver } from 'graphql-compose';
import { GraphQLSchema, GraphQLObjectType, GraphQLString } from 'graphql';

const UserTC = schemaComposer.createObjectTC({
  name: 'User',
  fields: {
    id: 'ID!',
    name: 'String!',
  },
});

UserTC.addResolver({
  name: 'findById',
  type: UserTC,
  args: { id: 'ID!' },
  resolve: async ({ args }) => {
    // pretend to fetch from DB
    return { id: args.id, name: 'John' };
  },
});

schemaComposer.Query.addFields({
  user: UserTC.getResolver('findById'),
});

const schema = schemaComposer.buildSchema();
console.log(schema);
// schema ready to be used with express-graphql or other server