Skip to content

Nx helps you organize a Next.js monorepo where apps and shared libraries live side by side. The Next.js plugin for Nx, @nx/next, automatically infers build, dev, and start tasks from your Next.js configuration and provides generators for creating applications and libraries.

You don't need the plugin to use Next.js with Nx. Any project already benefits from caching, task orchestration, and the project graph. The plugin adds automatic task inference, code generators, and simplified configuration.

The @nx/next plugin supports the following package versions.

PackageSupported Versions
next>=15.0.0 <17.0.0

Nx generators install the latest supported versions automatically when scaffolding new projects.

Terminal window
nx add @nx/next

Verify the plugin is setup:

  1. Check for @nx/next listed as a plugin:

    Terminal window
    nx report
  2. Ensure inferred tasks are working:

    Terminal window
    nx show projects --with-target=build
  3. Inspect a specific project configuration:

    Terminal window
    nx show project my-next-app

Start from the Next.js template to scaffold a Next.js app with a shared UI library:

Terminal window
npx create-nx-workspace@latest my-workspace --template nrwl/nextjs-template
Terminal window
nx g @nx/next:app apps/my-app

To start the application in development mode, run nx dev my-app. Read more about the options available for the application generator.

Terminal window
nx g @nx/next:lib libs/my-lib
# For a publishable library
nx g @nx/next:lib libs/my-lib --publishable --importPath=@myorg/my-lib

Read more about the options available for the library generator.

Terminal window
nx dev my-app

Starts the Next.js development server at http://localhost:3000 by default.

Terminal window
nx build my-app

The output goes to the .next folder inside your app's project directory by default. Customize the output directory with distDir in your next.config.js:

apps/my-app/next.config.js
const nextConfig = {
distDir: 'dist',
};
module.exports = nextConfig;
Terminal window
nx start my-app

Serves the production build. Depends on build completing first.

apps/my-app/pages/index.tsx
import { MyComponent } from '@myorg/my-lib';
export default function Index() {
return <MyComponent />;
}

There is no need to build the library prior to using it. When you update your library, the Next.js application automatically picks up the changes.

The @nx/next plugin creates tasks for any project that has a Next.js configuration file. Any of the following files are recognized:

  • next.config.js
  • next.config.cjs
  • next.config.mjs
  • next.config.ts

The configuration directory must also contain a package.json or project.json.

Configure @nx/next/plugin in the plugins array in nx.json:

nx.json
{
"plugins": [
{
"plugin": "@nx/next/plugin",
"options": {
"buildTargetName": "build",
"devTargetName": "dev",
"startTargetName": "start",
"buildDepsTargetName": "build-deps",
"watchDepsTargetName": "watch-deps"
}
}
]
}
OptionDescriptionDefault
buildTargetNameName of the cached next build task.build
devTargetNameName of the continuous next dev task.dev
startTargetNameName of the continuous next start task.start
serveStaticTargetNameDeprecated alias for startTargetName.serve-static
buildDepsTargetNameName of an optional dependency build task.none
watchDepsTargetNameName of an optional dependency watch task.none

The build task is cached, with outputs based on your Next.js configuration, and depends on builds of project dependencies. The start task depends on the build task.

The inferred dev and start targets come with a readyWhen check. With it, a task can wait until the server accepts connections instead of only until it has started. The check runs when the task runs, with the task's environment and options, and waits for the server's port. The port comes from the -p or --port flag, then the PORT environment variable, then 3000. With a -H or --hostname flag, it connects to that host. A port of 0 leaves no fixed port to wait for, so the target counts as ready once it has started. If nothing sets the port and another process holds 3000, next dev moves to the next free port, and this check can pass before the server is up.

A dependent task waits for the check only when its dependsOn entry sets waitFor to ready. A readyWhen on the target in targetDefaults or in the project configuration replaces the inferred check, and null turns it off. For the other checks, see wait for a continuous task to be ready.

Use include/exclude glob patterns in the plugin configuration to scope which projects the plugin applies to:

nx.json
{
"plugins": [
{
"plugin": "@nx/next/plugin",
"include": ["apps/**/*"],
"exclude": ["apps/legacy-app/**/*"],
"options": {
"buildTargetName": "build",
"devTargetName": "dev",
"startTargetName": "start",
"buildDepsTargetName": "build-deps",
"watchDepsTargetName": "watch-deps"
}
}
]
}

To see what tasks Nx inferred for a project:

Terminal window
nx show project my-app

Or open the project details view in Nx Console.

A target defaults plugin filter for these tasks must use the exact identifier @nx/next/plugin.

In CI, Nx runs nx affected to rebuild and retest only the projects a change touches, and caches results to skip repeated work.

For a complete pipeline, see Set up CI.