Add a Package-Based Project in an Integrated Repository

An integrated repo offers a lot of features at the cost of some flexibility, but sometimes you want to take back control of your build system or dependency management for a single project in the repo. This recipe shows you how to do that.

A package-based project in an integrated repository is a project that has at least one of these characteristics:

  1. Maintains its own dependencies with a separate package.json file
  2. Defines tasks in a package.json file that don't use Nx executors

For this example, we'll implement all three, but you can also have a project that has only one of these characteristics and falls back to an integrated style for the others.

Create Your Project

Because this is a package-based project, we won't use Nx to generate the project. We can create the project in whatever way is typical for the framework you're trying to add. This could mean using the framework's own CLI or manually adding files yourself.

For Nx to be aware of your project, it needs:

  1. npm, yarn or pnpm workspaces set up in the root package.json file
  2. A package.json file in the project folder with a name specified
  3. Some scripts defined in the project's package.json file for Nx to run

Setup NPM/Yarn/PNPM Workspaces

If you choose to have this project define its dependencies separately from the root package.json file, simply define those dependencies and devDependencies in the project's package.json file.

With npm/yarn/pnpm workspaces set up, you can run the install command at the root of the repository and every project will have its dependencies installed.

When you manage dependencies this way, you can still hoist dependencies to the root-level package.json file, but you have to make the explicit decision for each dependency.

There are difficulties with code sharing when you maintain separate dependencies. See the Dependency Management Strategies guide for more information.

Run Tasks Without the Use of an Nx Plugin

Any task you define in the scripts section of the project's package.json can be executed by Nx. These scripts can be cached and orchestrated in the same way a target defined in project.json is. If you want to define some tasks in project.json and some tasks in package.json, Nx will read both and merge the configurations.

A typical set up where the test task depends on the build task could look like this:

package.json
1{ 2 "scripts": { 3 "build": "tsc", 4 "test": "jest" 5 }, 6 "nx": { 7 "targets": { 8 "test": { 9 "dependsOn": ["build"] 10 } 11 } 12 } 13} 14

Updating Dependencies

Because this is a package-based project, you'll be managing your own updates for this project. In addition, you'll need to be careful when running the nx migrate command on the rest of the repo. There may be times where a migration changes code in this package-based project when it shouldn't. You'll need to manually revert those changes before committing.

Summary

An integrated Nx repo does not lock you into only using Nx plugins for all of your projects. You can always opt-out of using certain features and take on the responsibility of managing that functionality yourself.