1 minute read


Create and set up a new project with dependencies

Create a new project and install dependencies

mkdir graphql-server-example
cd graphql-server-example

npm init --yes
yarn add @apollo/server graphql

Create a TypeScript file and install TypeScript dependencies

mkdir src
touch src/index.ts
yarn add -D typescript @types/node

touch tsconfig.json
// tsconfig.json
  "compilerOptions": {
    "rootDirs": ["src"],
    "outDir": "dist",
    "lib": ["es2020"],
    "target": "es2020",
    "module": "esnext",
    "moduleResolution": "node",
    "esModuleInterop": true,
    "types": ["node"]

Update the package.json file with the following type and scripts entries

  "type": "module",
  "scripts": {
    "compile": "tsc",
    "start": "yarn compile && node ./dist/index.js",

Define your schema, data set, and a resolver

// index.ts
import { ApolloServer } from '@apollo/server'
import { startStandaloneServer } from '@apollo/server/standalone'
import resolvers from './resolvers.js'
import typeDefs from './typeDefs.js'

const server = new ApolloServer({ typeDefs, resolvers })
const { url } = await startStandaloneServer(server, { listen: { port: 4000 }})
console.log(`🚀 Server ready at ${url}`)
// data.ts
export const groceryItems = [
  { name: 'Milk', done: false },
  { name: 'Eggs', done: true },
  { name: 'Bread', done: false },
// resolvers.ts
import { groceryItems } from "./data.js"

const resolvers = {
  Query: {
    groceryItems: () => groceryItems,

export default resolvers
const typeDefs = `#graphql
  type GroceryItem {
    name: String
    done: Boolean

  type Query {
    groceryItems: [GroceryItem]

export default typeDefs

Adding #graphql to the beginning of a template literal provides GraphQL syntax highlighting in supporting IDEs.

With ESNext module, TypeScript doesn’t resolve the module with partial name. You have to specify .js in the import statement. It’s annoying, though.