Skip to content
Youngho Chaa cha cha

Set up a GraphQL server in express

graphql1 min 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.

© 2024 by Youngho Chaa cha cha. All rights reserved.
Theme by LekoArts