Skip to content

Like a lot of decisions in programming, deciding to make a new Nx project or not is all about trade-offs. Each organization will decide on their own conventions, but here are some trade-offs to bear in mind as you have the conversation.

Developers new to Nx can be initially hesitant to move their logic into separate projects, because they assume it implies that those projects need to be general purpose and shareable across applications. This is a common misconception: moving code into projects can be done from a pure code organization perspective.

Ease of re-use might emerge as a positive side effect of refactoring code into projects by applying an "API thinking" approach. It is not the main driver though.

In fact when organizing projects you should think about your business domains, as covered in folder structure.

There are three main benefits to breaking your code up into more projects.

The more granular your projects are, the more effective nx affected and the Nx computation cache will be. For example, if projectA contains 10 tests, but only 5 of them were affected by a particular code change, all 10 tests will be run by nx affected -t test. If you can predict which 5 tests are usually run together, you can split all the related code into a separate project to allow the two groups of 5 tests to be executed independently.

The nx graph command generates a graph of how apps and projects depend on each other. If most of your code lives in a few giant projects, this visualization doesn't provide much value.

You can enforce constraints on how different types of projects depend on each other using tags. Following pre-determined conventions on what kind of code can go in different types of projects allows your tagging system to enforce good architectural patterns.

Also, each project defines its own API, which allows for encapsulating logic that other parts of the codebase can not access. You can even use a CODEOWNERS file to assign ownership of a certain project to a user or team.

Limiting the number of projects by keeping code in an existing project also has benefits.

Related code should be close together. If a developer can accomplish a task without moving between multiple different folders, it helps them work faster and make fewer mistakes. Every new project adds some folders and configuration files that are not directly contributing to business value. Nx helps reduce the cost of adding a new project, but it isn't zero.

Especially for rapidly evolving code, the standard architectural constraints may just get in the way of experimentation and exploration. It may be worthwhile to develop for a while in a single project in order to allow a real architecture to emerge and then refactoring into multiple projects once the pace of change has slowed down.

There is no correct number of projects, but these signals tend to settle the conversation:

  • Split when tests slow you down. A project whose test suite dominates CI, while most changes only touch a slice of it, is the clearest split candidate: affected detection and caching immediately stop re-running the unaffected slice.
  • Split along ownership. When two teams keep editing the same project, boundaries and review assignments blur. One project per owning team keeps CODEOWNERS and module boundary tags honest.
  • Don't split what always changes together. If two projects appear in nearly every commit together, the boundary costs navigation and configuration without buying any caching or ownership benefit.
  • Type checking scales with project boundaries. Each project type-checks against its dependencies' declaration files rather than their full sources, so granular projects keep editor feedback and typecheck tasks fast as the codebase grows. See TypeScript project linking for how project references make this work.

Last updated: