Adding Nx to your Existing Project

Nx can be added to any type of project, not just monorepos. The main benefit is to get caching abilities for the package scripts. Each project usually has a set of scripts in the package.json:

package.json
1{ 2 ... 3 "scripts": { 4 "build": "next build", 5 "lint": "eslint ./src", 6 "test": "node ./run-tests.js" 7 } 8} 9

You can make these scripts faster by leveraging Nx's caching capabilities. For example:

  • You change some spec files: in that case the build task can be cached and doesn't have to re-run.
  • You update your docs, changing a couple of markdown files: then there's no need to re-run builds, tests, linting on your CI. All you might want to do is trigger the Docusaurus build.

Install Nx on a Non-Monorepo Project

Run the following command:

โฏ

npx nx@latest init

This will set up Nx for you - updating the package.json file and creating a new nx.json file with Nx configuration based on your answers during the set up process. The set up process will suggest installing Nx plugins that might be useful based on your existing repository. The example below is using the @nx/eslint and @nx/next plugins to run ESLint and Next.js tasks with Nx:

nx.json
1{ 2 "plugins": [ 3 { 4 "plugin": "@nx/eslint/plugin", 5 "options": { 6 "targetName": "eslint:lint" 7 } 8 }, 9 { 10 "plugin": "@nx/next/plugin", 11 "options": { 12 "buildTargetName": "next:build", 13 "devTargetName": "dev", 14 "startTargetName": "start" 15 } 16 } 17 ] 18} 19

When Nx updates your package.json scripts, it looks for scripts that can be replaced with an Nx command that has caching automatically enabled. The package.json defined above would be updated to look like this:

package.json
1{ 2 "name": "my-workspace", 3 ... 4 "scripts": { 5- "build": "next build && echo 'Build complete'", 6+ "build": "nx next:build && echo 'Build complete'", 7- "lint": "eslint ./src", 8+ "lint": "nx eslint:lint", 9 "test": "node ./run-tests.js" 10 }, 11+ "nx": {} 12} 13

The @nx/next/plugin plugin adds a next:build target which runs next build and sets up caching correctly. In other words, running nx next:build is the same as running next build with the added benefit of it being cacheable. Hence, Nx replaces next build in the package.json build script to add caching to anywhere running npm run build. Similarly, @nx/eslint/plugin sets up the nx eslint:lint command to run eslint ./src with caching enabled. The test script was not recognized by any Nx plugin, so it was left as is. After Nx has been setup, running npm run build or npm run lint multiple times, will be instant when possible.

You can also run any npm scripts directly through Nx with nx build or nx lint which will run the npm run build and npm run lint scripts respectively. In the later portion of the setup flow, Nx will ask if you would like some of those npm scripts to be cacheable. By making those cacheable, running nx build rather than npm run build will add another layer of cacheability. However, nx build must be run instead of npm run build to take advantage of the cache.

Inferred Tasks

You may have noticed that @nx/next provides dev and start tasks in addition to the next:build task. Those tasks were created by the @nx/next plugin from your existing Next.js configuration. To view all available tasks, open the Project Details view with Nx Console or use the terminal to launch the project details in a browser window.

โฏ

nx show project my-workspace --web

Project Details View

my-workspace

Root: .

Type: Library

Targets

  • eslint:lint

    eslint ./src

    Cacheable
  • next:build

    next build

    Cacheable
  • dev

    next dev

  • start

    next start

The project detail view lists all available tasks, the configuration values for those tasks and where those configuration values are being set.

Configure an Existing Script to Run with Nx

If you want to run one of your existing scripts with Nx, you need to tell Nx about it.

  1. Preface the script with nx exec -- to have npm run test invoke the command with Nx.
  2. Add the script to includedScripts.
  3. Define caching settings.

The nx exec command allows you to keep using npm test or npm run test (or other package manager's alternatives) as you're accustomed to. But still get the benefits of making those operations cacheable. Configuring the test script from the example above to run with Nx would look something like this:

package.json
1{ 2 "name": "my-workspace", 3 ... 4 "scripts": { 5 "build": "nx next:build", 6 "lint": "nx eslint:lint", 7 "test": "nx exec -- node ./run-tests.js" 8 }, 9 ... 10 "nx": { 11 "targets": { 12 "test": { 13 "cache": "true", 14 "inputs": [ 15 "default", 16 "^default" 17 ], 18 "outputs": [] 19 } 20 } 21 } 22} 23

Now if you run npm run test or nx test twice, the results will be retrieved from the cache. The inputs used in this example are as cautious as possible, so you can significantly improve the value of the cache by customizing Nx Inputs for each task.

Learn More