Hello Nexus Schema User!

This guide is for you if you use @nexus/schema on a project and are curious about if you should upgrade to the framework and/or how.

Nexus is built on top of @nexus/schema adding many opinions and features. If you haven't you should check out the tutorial and read the introduction.

Differences between Nexus and Nexus Schema

Here's a quick rundown of the differences:

JavaScript Support
TypeScript Support
@nexus/schema makeSchema Control
GraphQL Schema Builder Pure API
GraphQL Schema Builder Stateful Singleton API
Generate GraphQL SDL
Typesafe GraphQL Schema Resolvers
Nexus Schema Plugins
Zero Config
Project Scaffolding
Development Mode
Integrated Build Step with Bundling
HTTP Server
HTTP Server CORS Support
Subscriptions Server
Bundled Scalars
Type Discovery for Backing Types
Type Discovery for Context API
Module Discovery for Nexus modules
Enhanced Autocomplete via TS LSP for Nexus
System Testing API
Framework Plugins
Bundled Dependencies (why)


These are the steps to migrate from @nexus/schema to nexus:


Remove @nexus/schema and add the latest nexus in its place. Also remove dependency graphql as nexus bundles it.

1npm remove @nexus/schema graphql
2npm add nexus

Project Layout

Not much to do but your source must include a module that imports nexus and/or a module named app. More details in the convention guide. Nexus will give informative feedback if you get this wrong.

Type Defs (aka. schema)

Nexus is based upon a singleton system. Import the schema component to get access to the nexus building blocks you're familiar with. But unlike before you will no longer need to export/import the type defs for passing into makeSchema. All of that is handled for you. To aid in this style of project code the framework has a convention that all graphql modules or child modules of graphql directories get auto-imported. Example:

++--- graphql/user.ts
- import { objectType } from 'nexus'
+ import { schema } from 'nexus'
- export const User = objectType({
+ schema.objectType({
7 name: 'User',
8 ...
-- main.ts
- import { User } from './graphql/user'
- import { makeSchema } from 'nexus'
- const schema = makeSchema({ types: [User] })


Nexus has an API for adding to context.

++ app.ts
+ import { schema } from 'nexus'
+ schema.addToContext(({ req, res }) => {
+ return { ... }
+ })
- // Example
- import { GraphQLServer } from 'graphql-yoga'
- new GraphQLServer({
- context(req) => {
- return { ... }
- }
- })


The server migration is particularly dependent on your setup. Nexus bundles express and express-graphql.

If you are not doing any or much custom server logic you can get away with not dealing with the server at all. Just delete all code, Nexus will handle it for you.

-- app.ts
- import express from 'express'
- import { GraphQLServer } from 'graphql-yoga'
- const server = new GraphQLServer({ schema: ... })
- server.start()

If you do have server logic that needs porting, and it is express based, use server.express:

-- app.ts
+ import { server } from 'nexus'
+ server.express.use(...)

We currently do not support any other server than express.

Developing & Building

You should only be working with the nexus CLI. Below shows the example scripts you might have had previously, versus what you'll now have (suggested).

2 "scripts": {
- "start": "node dist/server",
- "clean": "rm -rf dist",
- "build": "npm -s run clean && npm -s run generate && tsc",
- "generate": "npm -s run generate:prisma && npm -s run generate:nexus",
- "generate:prisma": "prisma generate",
- "generate:nexus": "ts-node --transpile-only src/schema",
- "postinstall": "npm -s run generate",
- "dev": "ts-node-dev --no-notify --respawn --transpileOnly src/server",
+ "dev": "nexus dev",
+ "build": "nexus build",
+ "start": "node .nexus/build"
14 },

Backing Types

With Nexus Schema you manage backing types for your GraphQL objects centrally via makeSchema. Paths you give are to modules that export types. Type names that match your GraphQL object type names are made their respective backing types.

With Nexus Framework backing types are handled as follows:

  1. You export TypeScript types in any module
  2. You configure your object type configs to use any of these exported TypeScript types.

For more detail about backing types and how they work in Nexus Framework, see the backing types section in the schema guide



1// some-module.ts
2export type A = {
3 /* ... */
1// schema.ts
2export const A = objectType({
3 name: 'A',
4 // ...
1// main.ts
2// ...
3const schema = makeSchema({
4 typegenAutoConfig: [
5 {
6 source: path.join(__dirname, 'some-module.ts'),
7 alias: 'SomeModule',
8 },
9 ],
10 // ...
12// ...


1import { schema } from 'nexus'
3export type A = {
4 /* ... */
8 rootTyping: 'A',
9 // ...


By default Nexus Schema has outputs as guaranteed. Nexus Framework has outputs as nullable.

If you rely heavily on the Nexus Schema defaults then please wait for #483 so that you can turn them back on that way in the framework.

If you use the following settings in your app currently then you can migrate seamlessly to Nexus framework, since this config is now the default:

2 nonNullDefaults: {
3 input: false,
4 output: false,
5 },


Nexus ships with its own logger.

1import { log } from 'nexus'
2;-console.log('hello world! %j', { population: 6_000_000 }) +
3 log.info('hello world!', { population: 6_000_000 })


If you were a nexus-prisma user, you will now become a nexus-plugin-prisma user - it's the same thing with a different name. Install the plugin, and enable it in your project.

2 dependencies: {
- "nexus-prisma": "...",
- "@prisma/client": "...",
- "@prisma/cli": "..."
+ "nexus-plugin-prisma": "...",
- import { nexusPrismaPlugin } from 'nexus-prisma'
- makeSchema({
- plugins: [nexusPrismaPlugin()],
+ import { use } from 'nexus'
+ import { prisma } from 'nexus-plugin-prisma'
+ use(prisma())

For now you should still use the Prisma CLI as only $ prisma generate is taken care of for you.

Edit this page on Github