npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

merge-remote-graphql-schemas

v0.1.25

Published

Merge GraphQL remote executable schemas using directive hints

Readme

merge-remote-graphql-schemas

This utility merges remote GraphQL schemas into a single unified schema, including merging types. It's good practice to split your schema up by concern, which is easy enough to do within a single GraphQL service using the extend keyword.

For example, given this schema:

type Query {
  book(id: ID!): Book
  review(id: ID!): Review
}

type Review {
  id: ID!
  title: String!
  book: Book!
}

type Book {
  id: ID!
  title: String
  author: String
  reviews: [Review!]!
}

You might want to split it up by Book and Review concerns:

# Book schema
extend type Query {
  book(id: ID!): Book
}

type Book {
  id: ID!
  title: String
  author: String
}
# Review schema
extend type Query {
  review(id: ID!): Review
}

type Review {
  id: ID!
  title: String!
  book: Book!
}

extend type Book {
  reviews: [Review!]!
}

However, it's not as easy to do this across remote GraphQL schemas since you can't extend types that exist in other GraphQL services. Usually, in order to combine remote schemas that interact with each other you would need to write resolvers in your GraphQL gateway that perform the needed mappings. This library does that mapping automatically.

Installation

npm install --save merge-remote-graphql-schemas

Usage

In order to merge types across remote schemas there needs to be a known entry point to query information about those types in each schema. By convention this library assumes for each merged type there is a top level query that is named after the type in lowerCamelCase that accepts an id argument and returns that type. So the Book type needs to have a book(id: ID!): Book query resolver.

If a type doesn't have any cross-schema interactions then it doesn't need to meet this requirement.

Using the example from earlier, your GraphQL servers would expose these schemas:

# Book GraphQL Service
type Query {
  book(id: ID!): Book
}

type Book {
  id: ID!
  title: String
  author: String
}
# Review GraphQL Service
type Query {
  book(id: ID!): Book
  review(id: ID!): Review
}

type Review {
  id: ID!
  title: String!
  book: Book!
}

type Book {
  id: ID!
  reviews: [Review!]!
}

The Review service only needs to know about Books as far as the relationships between Books and Reviews and the Book service doesn't need to know about Reviews at all.

The following example uses ApolloServer to run a GraphQL server. The schema provided to ApolloServer is created by mergeRemoteSchemas from two remote GraphQL services.

const { ApolloServer, makeRemoteExecutableSchema, introspectSchema } = require('apollo-server');
const { HttpLink } = require('apollo-link-http');
const fetch = require('node-fetch');
const { mergeRemoteSchemas } = require('merge-remote-graphql-schemas');

async function createRemoteExecutableSchema(uri) {

  const link = new HttpLink({
    uri,
    fetch,
  });

  const schema = makeRemoteExecutableSchema({
    schema: await introspectSchema(httpLink),
    link,
  });

  return schema;
};

Promise.all(['http://{BOOK_SERVICE}/graphql', 'http://{REVIEW_SERVICE}/graphql'].map(createRemoteExecutableSchema))
  .then((schemas) => {
    const server = new ApolloServer({ schema: mergeRemoteSchemas({ schemas }) }); // Merge the remote schemas together and pass the result to ApolloServer

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

The stitched together schema exposed by this service would be:

type Query {
  book(id: ID!): Book
  review(id: ID!): Review
}

type Review {
  id: ID!
  title: String!
  book: Book!
}

type Book {
  id: ID!
  title: String
  author: String
  reviews: [Review!]!
}