Skip to content
Toolkit for generating complex GraphQL Schemas on Node.js
Branch: master
Clone or download
Type Name Latest commit message Commit time
Failed to load latest commit information.
docs docs: Activating Open Collective 🍻(#118) May 16, 2018
examples docs(example) add basic example use of graphql compose (#98) Oct 23, 2017
flow-typed/npm chore(deps): update dependencies Feb 1, 2018
src fix(typings): fix ComposeOutputType it has TReturn generic instead of… Mar 17, 2019
.flowconfig feat: add mjs build (es6 modules) Jun 26, 2018
.markdownlint.json refactor: small fixes after checking with mongoose, pagination, conne… Mar 15, 2019
.npmignore chore(typescript): move type defs from types/ to src/ Sep 15, 2017
.prettierignore docs: Activating Open Collective 🍻(#118) May 16, 2018
.travis.yml chore: update flow-bin and using node 10 on travis Sep 5, 2018
AUTHORS Initial commit Jun 7, 2016 docs(Changelog): See in the GitHub releases tab Jan 25, 2017 docs(README): remove graphql-recompose Aug 20, 2018
yarn.lock fix: errors from flow 0.95.1 Mar 15, 2019


codecov coverage Travis npm Commitizen friendly TypeScript compatible FlowType compatible Backers on Open Collective Sponsors on Open Collective

GraphQL – is a query language for APIs. graphql-js is the reference implementation of GraphQL for nodejs which introduce GraphQL type system for describing schema (definition over configuration) and executes queries on the server side. express-graphql is a HTTP server which gets request data, passes it to graphql-js and returned result passes to response.

graphql-compose – the imperative tool which worked on top of graphql-js. It provides some methods for creating types and GraphQL Models (so I call types with a list of common resolvers) for further building of complex relations in your schema.

  • provides methods for editing GraphQL output/input types (add/remove fields/args/interfaces)
  • introduces Resolvers – the named graphql fieldConfigs, which can be used for finding, updating, removing records
  • provides an easy way for creating relations between types via Resolvers
  • provides converter from OutputType to InputType
  • provides projection parser from AST
  • provides GraphQL schema language for defining simple types
  • adds additional types Date, Json

graphql-compose-[plugin] – is a declarative generators/plugins that build on top of graphql-compose, which take some ORMs, schema definitions and creates GraphQL Models from them or modify existed GraphQL Types.

Type generator plugins:

Utility plugins:


Live Demos



import { TypeComposer} from 'graphql-compose';
import { CountryTC } from './country';

export const CityTC = TypeComposer.create(`
  type City {
    code: String!
    name: String!
    population: Number
    countryCode: String
    tz: String

// Define some additional fields
  ucName: { // standard GraphQL like field definition
    type: GraphQLString,
    resolve: (source) =>,
  currentLocalTime: { // extended GraphQL Compose field definition
    type: 'Date',
    resolve: (source) => moment().tz(,
    projection: { tz: true }, // load `tz` from database, when requested only `localTime` field
  counter: 'Int', // shortening for only type definition for field
  complex: `type ComplexType {
    subField1: String
    subField2: Float
    subField3: Boolean
    subField4: ID
    subField5: JSON
    subField6: Date
  list0: {
    type: '[String]',
    description: 'Array of strings',
  list1: '[String]',
  list2: ['String'],
  list3: [new GraphQLOutputType(...)],
  list4: [`type Complex2Type { f1: Float, f2: Int }`],

// Add resolver method
  kind: 'query',
  name: 'findMany',
  args: {
    filter: `input CityFilterInput {
      code: String!
    limit: {
      type: 'Int',
      defaultValue: 20,
    skip: 'Int',
    // ... other args if needed
  type: [CityTC], // array of cities
  resolve: async ({ args, context }) => {
    return context.someCityDB

// Add relation between City and Country by `countryCode` field.
CityTC.addRelation( // GraphQL relation definition
    resolver: () => CountryTC.getResolver('findOne'),
    prepareArgs: {
      filter: source => ({ code: `${source.countryCode}` }),
    projection: { countryCode: true },

// Remove `tz` field from schema

// Add description to field
CityTC.extendField('name', {
  description: 'City name',


import { schemaComposer } from 'graphql-compose';
import { CityTC } from './city';
import { CountryTC } from './country';

  cities: CityTC.getResolver('findMany'),
  country: CountryTC.getResolver('findOne'),
  currentTime: {
    type: 'Date',
    resolve: () =>,

  createCity: CityTC.getResolver('createOne'),
  updateCity: CityTC.getResolver('updateById'),
    removeCity: CityTC.getResolver('removeById'),

function adminAccess(resolvers) {
  Object.keys(resolvers).forEach(k => {
    resolvers[k] = resolvers[k].wrapResolve(next => rp => {
      // rp = resolveParams = { source, args, context, info }
      if (!rp.context.isAdmin) {
        throw new Error('You should be admin, to have access to this action.');
      return next(rp);
  return resolvers;

export default schemaComposer.buildSchema();


This project exists thanks to all the people who contribute.


Thank you to all our backers! 🙏 [Become a backer]


Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]



You can’t perform that action at this time.