Skip to content

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.