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:
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:
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
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: | |
---|---|
cacheDir | Set in cacheDirectory |
deamon | Use NX_DAEMON=false or set useDaemonProcess: false in nx.json |
envMode | Nx core does not block any environment variables. There are React and Angular build executors that handle environment variables in a customized way. |
globalDependencies | add to the sharedGlobals namedInput |
globalEnv | add to the sharedGlobals namedInput as an env input |
globalPassThroughEnv | N/A. See Defining Environment Variables |
remoteCache | See Nx Replay |
ui | Use --output-style |
Task Configuration: | |
---------------------------- | ---------------------------------------------------------------------------------------------- |
extends | N/A. The project configurations will always extend the targetDefaults defined in nx.json . |
tasks[task].dependsOn | Same syntax. |
tasks[task].env | Define env inputs |
tasks[task].passThroughEnv | N/A. See Defining Environment Variables |
tasks[task].outputs | Same syntax. |
tasks[task].cache | Same syntax |
tasks[task].inputs | Same syntax. |
tasks[task].outputLogs | Use the --output-style command line flag |
tasks[task].persistent | N/A. |
tasks[task].interactive | N/A. |
Command Equivalents
turbo run test lint build | nx run-many -t test lint build |
--cache-dir | Set in nx.json under cacheDirectory |
--concurrency | --parallel |
--continue | Use --nx-bail with the inverse value |
--cpuprofile | Use NX_PROFILE=profile.json . |
--cwd | Available when using the run-commands executor |
--deamon | Use NX_DAEMON=false or set useDaemonProcess: false in nx.json |
--dry-run | N/A. Nx has --dry-run for nx generate but not for running tasks. |
--env-mode | Nx core does not block any environment variables. There are React and Angular build executors that handle environment variables in a customized way. |
--filter | Use -p admin-* or -p tag:api-* . Also see nx affected . |
--force | nx reset and then run the command again |
--framework-inference | Nx knows if you're using a particular framework if you use an executor for that framework. |
--global-deps | Use inputs in the nx.json or project configuration |
--graph | Same syntax or nx graph for the entire graph |
--heap | N/A. --verbose for more logging. |
--ignore | Use an .nxignore file (or .gitignore ) |
--log-order | Use --output-style |
--no-cache | Use --skip-nx-cache |
--output-logs | Use --output-style |
--only | N/A |
--parallel | N/A |
--preflight | N/A |
--remote-only | N/A. Can ignore the remote cache with --no-cloud . |
--summarize | N/A |
--token | Set the Nx Cloud CI Access Token or as an environment variable (NX_CLOUD_ACCESS_TOKEN ) |
--team | See --token for choosing a different Nx Cloud workspace. You can use --runner to choose a different runner defined in the nx.json file. |
--trace | N/A. --verbose for more logging. |
--verbosity | Use --verbose |
turbo gen | Use nx generate |
turbo login | No need. Create an Nx Cloud account once to set up Nx Cloud. |
turbo link | Create an Nx Cloud account |