graphql-tools and Apollo GraphQL aren’t really competing products; they’re more like building blocks where Apollo GraphQL uses graphql-tools under the hood.

Let’s see graphql-tools in action, building a simple schema from scratch. Imagine you have a few types defined in your GraphQL schema language (SDL):

type Book {
  title: String!
  author: String!
  year: Int
}

type Query {
  books: [Book!]!
  bookByTitle(title: String!): Book
}

With graphql-tools, you can take this SDL and add "resolvers" – the functions that actually fetch the data for each field.

import { makeExecutableSchema } from 'graphql-tools';

const typeDefs = `
  type Book {
    title: String!
    author: String!
    year: Int
  }

  type Query {
    books: [Book!]!
    bookByTitle(title: String!): Book
  }
`;

const booksData = [
  { title: "The Hitchhiker's Guide to the Galaxy", author: "Douglas Adams", year: 1979 },
  { title: "Pride and Prejudice", author: "Jane Austen", year: 1813 },
  { title: "1984", author: "George Orwell", year: 1949 },
];

const resolvers = {
  Query: {
    books: () => booksData,
    bookByTitle: (_, { title }) => booksData.find(book => book.title === title),
  },
};

const schema = makeExecutableSchema({ typeDefs, resolvers });

export default schema;

This schema object is now a fully functional GraphQL schema that can be served by a GraphQL server. graphql-tools provides the core functionality to stitch together your schema definition and your data-fetching logic.

Apollo GraphQL, on the other hand, is a comprehensive platform for building and managing GraphQL APIs. Think of it as a set of tools that uses graphql-tools (and the underlying graphql-js library) but adds much more.

Here’s what Apollo brings to the table:

  • Server: apollo-server is a popular, batteries-included GraphQL server that works with various Node.js frameworks (Express, Koa, Hapi, etc.) or as a standalone server. It simplifies setting up an endpoint.
  • Client: apollo-client is a powerful GraphQL client for the frontend (React, Vue, Angular, etc.) that manages caching, state management, and network requests.
  • Gateway: apollo-gateway allows you to build a single GraphQL API from multiple microservices (a "supergraph").
  • DevTools: Apollo Studio provides a hosted platform for managing your GraphQL schema, monitoring performance, and exploring your API.

When you use apollo-server, you’re often still defining your typeDefs and resolvers much like in the graphql-tools example. Apollo Server then takes these and uses graphql-tools internally to create the executable schema.

import { ApolloServer } from 'apollo-server';
import { makeExecutableSchema } from 'graphql-tools'; // Apollo Server uses this!

// ... (typeDefs and resolvers from the previous example) ...

const schema = makeExecutableSchema({ typeDefs, resolvers });

const server = new ApolloServer({ schema });

server.listen().then(({ url }) => {
  console.log(`🚀 Server ready at ${url}`);
});

The core difference is the scope: graphql-tools is a library for schema construction, while Apollo GraphQL is a full-stack ecosystem for GraphQL development. You can use graphql-tools on its own to build your schema and then integrate it with any GraphQL server. However, Apollo provides a more opinionated and integrated experience, especially if you’re building a complex application or want features like managed caching and a unified API gateway.

The one thing most people miss is that graphql-tools itself is quite low-level. It gives you the power to define your schema and resolvers, but it doesn’t prescribe how you should serve it, how you should handle authentication, or how you should manage client-side state. Apollo, by providing apollo-server and apollo-client, offers these higher-level abstractions and integrations, making it easier to get a full GraphQL application up and running quickly.

The next step after understanding this distinction is often exploring how to integrate Apollo Client with a frontend framework to consume the Apollo Server API.

Want structured learning?

Take the full Graphql-tools course →