← Back to graphql/graphql-js

How to Deploy & Use graphql/graphql-js

GraphQL.js Deployment and Usage Guide

This guide provides comprehensive instructions for deploying and using GraphQL.js, the JavaScript reference implementation for GraphQL.

1. Prerequisites

Before you begin, ensure you have the following installed:

  • Node.js: Version 14 or higher is recommended. You can download it from nodejs.org.
  • npm or Yarn: These are package managers for JavaScript. npm is bundled with Node.js. Yarn can be installed globally via npm install -g yarn.

2. Installation

GraphQL.js is available as an npm package.

  1. Create a new project directory (optional):

    mkdir my-graphql-app
    cd my-graphql-app
    
  2. Initialize a new Node.js project (if not already done):

    npm init -y
    

    or

    yarn init -y
    
  3. Install GraphQL.js:

    Using npm:

    npm install --save graphql
    

    Using Yarn:

    yarn add graphql
    

Bleeding Edge / Experimental Features

  • Latest unreleased version (from npm branch):

    npm install graphql@git://github.com/graphql/graphql-js.git#npm
    
  • Experimental release with @defer and @stream directives: Modify your package.json to use the experimental version:

    {
      "dependencies": {
        "graphql": "experimental-stream-defer"
      }
    }
    

    Then run:

    npm install
    # or
    yarn install
    

3. Configuration

GraphQL.js primarily relies on programmatic configuration within your JavaScript/TypeScript code to define schemas and resolvers.

  • Schema Definition: Your GraphQL schema is defined using GraphQLSchema, GraphQLObjectType, GraphQLString, etc., directly in your application code. There are no external configuration files for the schema itself.

    Example:

    import {
      graphql,
      GraphQLSchema,
      GraphQLObjectType,
      GraphQLString,
    } from 'graphql';
    
    var schema = new GraphQLSchema({
      query: new GraphQLObjectType({
        name: 'RootQueryType',
        fields: {
          hello: {
            type: GraphQLString,
            resolve() {
              return 'world';
            },
          },
        },
      }),
    });
    
  • Environment Variables:

    • NODE_ENV: For production deployments, it is crucial to set NODE_ENV=production. This disables development-specific checks that can impact performance.

      Example (Linux/macOS):

      NODE_ENV=production node your-app.js
      

      Example (Windows CMD):

      set NODE_ENV=production && node your-app.js
      

      Example (Windows PowerShell):

      $env:NODE_ENV="production"; node your-app.js
      

4. Build & Run

GraphQL.js is a library, not a standalone application. You integrate it into your Node.js or browser-based application.

Local Development

  1. Create an application file (e.g., app.js):

    import {
      graphql,
      GraphQLSchema,
      GraphQLObjectType,
      GraphQLString,
    } from 'graphql';
    
    // Define your schema
    const schema = new GraphQLSchema({
      query: new GraphQLObjectType({
        name: 'RootQueryType',
        fields: {
          hello: {
            type: GraphQLString,
            resolve() {
              return 'world';
            },
          },
          greeting: {
            type: GraphQLString,
            args: {
              name: { type: GraphQLString }
            },
            resolve(parent, { name }) {
              return `Hello, ${name || 'Guest'}!`;
            },
          },
        },
      }),
    });
    
    // Example query execution
    async function runQuery(source) {
      console.log(`Executing query: "${source}"`);
      const result = await graphql({ schema, source });
      console.log(JSON.stringify(result, null, 2));
    }
    
    // Run some queries
    runQuery('{ hello }');
    runQuery('{ greeting(name: "Alice") }');
    runQuery('{ BoyHowdy }'); // This will result in an error
    
  2. Run your application:

    node app.js
    

    You should see output similar to this:

    Executing query: "{ hello }"
    {
      "data": {
        "hello": "world"
      }
    }
    Executing query: "{ greeting(name: "Alice") }"
    {
      "data": {
        "greeting": "Hello, Alice!"
      }
    }
    Executing query: "{ BoyHowdy }"
    {
      "errors": [
        {
          "message": "Cannot query field BoyHowdy on RootQueryType",
          "locations": [
            {
              "line": 1,
              "column": 3
            }
          ]
        }
      ]
    }
    

Production Build

For production, ensure NODE_ENV is set to production. If you are using a bundler like Webpack or Rollup for a browser-based application, ensure your build configuration handles .mjs files correctly, as GraphQL.js is distributed with both CommonJS and ESModule files.

Example webpack.config.js snippet (if you encounter issues with .mjs files):

module.exports = {
  // ... other webpack config
  resolve: {
    extensions: ['.js', '.json', '.ts', '.mjs'], // Ensure .mjs is included
  },
  module: {
    rules: [
      {
        test: /\.mjs$/,
        include: /node_modules/,
        type: 'javascript/auto',
      },
      // ... other rules
    ],
  },
};

5. Deployment

GraphQL.js is a backend library, typically deployed as part of a Node.js application or bundled into a frontend application.

For Node.js Backend Applications

You can deploy a GraphQL.js-powered Node.js server to various platforms:

  • Heroku:

    1. Ensure your project has a package.json and a start script (e.g., node app.js).
    2. Install the Heroku CLI.
    3. heroku login
    4. heroku create
    5. git push heroku main
    6. Set NODE_ENV config var: heroku config:set NODE_ENV=production
  • Vercel / Netlify (for Serverless Functions): If your GraphQL server is implemented as a serverless function (e.g., using apollo-server-lambda), these platforms are excellent choices.

    1. Ensure your project is a Git repository.
    2. Connect your repository to Vercel/Netlify.
    3. Configure build commands and output directories if necessary (often auto-detected).
    4. Set NODE_ENV=production in environment variables within the platform's dashboard.
  • AWS EC2 / DigitalOcean Droplet / Google Cloud Compute Engine: For more control, deploy your Node.js application directly onto a virtual machine.

    1. Provision a VM instance.
    2. Install Node.js and npm/yarn.
    3. Clone your repository.
    4. npm install or yarn install
    5. Set NODE_ENV=production.
    6. Use a process manager like PM2 (npm install -g pm2) to keep your application running: pm2 start app.js --name "graphql-server"
    7. Configure a reverse proxy (e.g., Nginx or Caddy) to handle incoming requests and SSL.
  • Docker: Containerize your application for consistent deployment across environments.

    1. Create a Dockerfile:
      # Use an official Node.js runtime as a parent image
      FROM node:18-alpine
      
      # Set the working directory
      WORKDIR /usr/src/app
      
      # Copy package.json and package-lock.json first to leverage Docker cache
      COPY package*.json ./
      
      # Install app dependencies
      RUN npm install --production
      
      # Bundle app source
      COPY . .
      
      # Set NODE_ENV to production
      ENV NODE_ENV=production
      
      # Expose the port your app runs on
      EXPOSE 4000
      
      # Define the command to run your app
      CMD [ "node", "app.js" ]
      
    2. Build the Docker image: docker build -t my-graphql-app .
    3. Run the container: docker run -p 4000:4000 my-graphql-app
    4. Deploy the Docker image to a container orchestration service like Kubernetes, AWS ECS, Google Cloud Run, etc.

For Browser-based Applications

If you are using GraphQL.js client-side (e.g., within GraphiQL), it will be bundled with your frontend application using tools like Webpack, Rollup, or Vite, and deployed as static assets to services like Netlify, Vercel, AWS S3 + CloudFront, or GitHub Pages.

6. Troubleshooting

  • Cannot find module 'graphql':

    • Cause: GraphQL.js was not installed or is not in node_modules.
    • Solution: Run npm install graphql or yarn add graphql in your project directory.
  • Schema Definition Errors:

    • Cause: Incorrectly defined types, fields, or resolvers in your GraphQLSchema construction.
    • Solution: Carefully review the GraphQL.js documentation for schema building. Error messages from graphql function calls will often point to the specific issue (e.g., Cannot query field BoyHowdy on RootQueryType). Use assertValidSchema(schema) during development for early validation.
  • NODE_ENV=production performance impact:

    • Cause: Running a production server without NODE_ENV=production.
    • Solution: Always set NODE_ENV=production in your production environment. This disables useful development checks but significantly improves performance.
  • Bundling issues with .mjs files (for browser/webpack users):

    • Cause: Your bundler (e.g., Webpack) might not be configured to correctly process .mjs files from node_modules.
    • Solution: Add .mjs to your bundler's resolve.extensions and potentially add a rule for type: 'javascript/auto' for .mjs files if you encounter parsing errors. (See "Production Build" section for a Webpack example).
  • Unexpected null values or missing data in query results:

    • Cause: Your resolve functions are not returning data correctly, or there's an unhandled error in a resolver.
    • Solution: Add console.log statements within your resolve functions to inspect the data flow. GraphQL errors often appear in the errors array of the query result. Ensure promises returned by resolvers are handled correctly.
  • "Experimental Stream Defer" issues:

    • Cause: Using the experimental version might lead to unexpected behavior or incomplete features as it's a pre-release.
    • Solution: Report issues on the GitHub issue tracker. Be prepared for potential breaking changes if using experimental features in production.