Migrate from Turborepo to Nx

If you have an existing monorepo that uses Turborepo, switching to use Nx is a straight-forward process. After switching, you'll have cleaner CLI output, a better graph view and IDE support with the option to incorporate Nx plugins. All this without increasing the complexity of your configuration files.

For more details, read our comparison of Nx and Turborepo

Initialize Nx

To switch to Nx, run this command:

โฏ

npx nx@latest init

See the Adding Nx to NPM/Yarn/PNPM Workspace guide for details about everything the nx init command does.

Convert turbo.json into Nx Configuration

Most of the settings in your turbo.json file can be converted directly into nx.json equivalents. The key configuration properties of dependsOn, inputs and outputs have a very similar syntax and can probably be copied over directly from the turbo.json tasks into the nx.json targetDefaults.

If you have project-specific tasks defined in the root turbo.json (i.e. myreactapp#build) or in project-level turbo.json files (i.e. /packages/myreactapp/turbo.json), those settings should go in the nx property of the project's package.json (i.e. /packages/myreactapp/package.json).

Specific configuration property conversions are documented below.

Example

Let's say you start with the following turbo.json file:

/turbo.json
1{ 2 "$schema": "https://turbo.build/schema.json", 3 "tasks": { 4 "build": { 5 "dependsOn": ["^build"], 6 "outputs": ["dist/**"] 7 }, 8 "docs#build": { 9 "dependsOn": ["^build"], 10 "outputs": ["www/**"] 11 }, 12 "test": { 13 "dependsOn": ["build"], 14 "outputs": [] 15 }, 16 "e2e": { 17 "dependsOn": ["build"], 18 "outputs": [] 19 } 20 }, 21 "globalDependencies": ["babel.config.json"] 22} 23

Creating the equivalent configuration with Nx yields the following files:

/nx.json
1{ 2 "$schema": "./node_modules/nx/schemas/nx-schema.json", 3 "namedInputs": { 4 "sharedGlobals": ["babel.config.json"], 5 "default": ["{projectRoot}/**/*", "sharedGlobals"] 6 }, 7 "targetDefaults": { 8 "build": { 9 "dependsOn": ["^build"], 10 "inputs": ["default"], 11 "outputs": ["{projectRoot}/dist"], 12 "cache": true 13 }, 14 "test": { 15 "dependsOn": ["build"], 16 "inputs": ["default"], 17 "cache": true 18 }, 19 "e2e": { 20 "dependsOn": ["build"], 21 "inputs": ["default"], 22 "cache": true 23 } 24 }, 25 "nxCloudId": "..." 26} 27
/packages/docs/package.json
1{ 2 "name": "docs", 3 // etc... 4 "nx": { 5 "targets": { 6 "build": { 7 "outputs": ["www/**"] 8 } 9 } 10 } 11} 12

Specific Configuration Property Conversions

For each turbo.json configuration property, the equivalent Nx property is listed.

Global Configuration:
cacheDirSet in cacheDirectory
deamonUse NX_DAEMON=false or set useDaemonProcess: false in nx.json
envModeNx core does not block any environment variables. There are React and Angular build executors that handle environment variables in a customized way.
globalDependenciesadd to the sharedGlobals namedInput
globalEnvadd to the sharedGlobals namedInput as an env input
globalPassThroughEnvN/A. See Defining Environment Variables
remoteCacheSee Nx Replay
uiUse --output-style
Task Configuration:
--------------------------------------------------------------------------------------------------------------------------
extendsN/A. The project configurations will always extend the targetDefaults defined in nx.json.
tasks[task].dependsOnSame syntax.
tasks[task].envDefine env inputs
tasks[task].passThroughEnvN/A. See Defining Environment Variables
tasks[task].outputsSame syntax.
tasks[task].cacheSame syntax
tasks[task].inputsSame syntax.
tasks[task].outputLogsUse the --output-style command line flag
tasks[task].persistentN/A.
tasks[task].interactiveN/A.

Command Equivalents

turbo run test lint buildnx run-many -t test lint build
--cache-dirSet in nx.json under cacheDirectory
--concurrency--parallel
--continueUse --nx-bail with the inverse value
--cpuprofileUse NX_PROFILE=profile.json.
--cwdAvailable when using the run-commands executor
--deamonUse NX_DAEMON=false or set useDaemonProcess: false in nx.json
--dry-runN/A. Nx has --dry-run for nx generate but not for running tasks.
--env-modeNx core does not block any environment variables. There are React and Angular build executors that handle environment variables in a customized way.
--filterUse -p admin-* or -p tag:api-*. Also see nx affected.
--forcenx reset and then run the command again
--framework-inferenceNx knows if you're using a particular framework if you use an executor for that framework.
--global-depsUse inputs in the nx.json or project configuration
--graphSame syntax or nx graph for the entire graph
--heapN/A. --verbose for more logging.
--ignoreUse an .nxignore file (or .gitignore)
--log-orderUse --output-style
--no-cacheUse --skip-nx-cache
--output-logsUse --output-style
--onlyN/A
--parallelN/A
--preflightN/A
--remote-onlyN/A. Can ignore the remote cache with --no-cloud.
--summarizeN/A
--tokenSet the Nx Cloud CI Access Token or as an environment variable (NX_CLOUD_ACCESS_TOKEN)
--teamSee --token for choosing a different Nx Cloud workspace. You can use --runner to choose a different runner defined in the nx.json file.
--traceN/A. --verbose for more logging.
--verbosityUse --verbose
turbo genUse nx generate
turbo loginNo need. Create an Nx Cloud account once to set up Nx Cloud.
turbo linkCreate an Nx Cloud account