Applications and libraries¶
An Nx monorepo organises code into two categories: applications and libraries. Understanding the difference is key to working effectively in any Nx workspace.
Applications¶
Applications are deployable programs that users or systems interact with directly. They live in the apps/ directory and are the entry points of the system - a web app a user visits, a documentation site, or a test suite that runs against a live environment.
Applications should contain as little logic as possible. Their role is to compose libraries together and provide configuration (routing, environment variables, deployment settings). The goal is to keep applications thin so that the reusable logic lives in libraries where it can be shared and tested independently.
Libraries¶
Libraries are reusable packages of code that applications (and other libraries) depend on. They live in the libs/ directory and contain the actual business logic, components, utilities, and types that power the applications.
Libraries cannot run on their own - they are consumed by applications or other libraries. This separation means code can be shared across multiple applications without duplication, and each library can be built, tested, and linted in isolation.
Key differences¶
| Applications | Libraries | |
|---|---|---|
| Location | apps/ |
libs/ |
| Purpose | Deployable entry points | Reusable, shared code |
| Contains | Routing, configuration, composition | Components, utilities, business logic |
| Runs independently | Yes | No - consumed by apps or other libs |
| Typical count | Few | Many |
A typical Nx workspace has more libraries than applications. This keeps each piece of code focused, testable, and reusable.
Why the separation matters¶
Splitting code into applications and libraries gives you several advantages:
- Independent testing: each library can be tested in isolation without starting the full application.
- Computation caching: Nx caches build, test, and lint results per project. Smaller, focused libraries mean more cache hits and faster pipelines.
- Architectural boundaries: Nx can enforce module boundary rules that control which libraries each project is allowed to import from, preventing accidental coupling.
- Parallel execution: independent libraries can be built, tested, and linted in parallel across available CPU cores.
- Code sharing: libraries can be consumed by multiple applications without duplication.