2HAASStart a project
All posts

Tool Reviews

Monorepo dependencies with pnpm and npm workspaces

Workspaces let a frontend, an API and shared packages live in one repository with one install. How pnpm and npm workspaces work, and when each one fits.

The 2HAAS team2 min read

A frontend, a backend and a shared utility library usually start as three repositories. Soon the shared library is copied by hand, the two apps run different versions of it, and each has its own node_modules with the same packages downloaded twice.

Workspaces solve this by putting the projects in one repository with one install.

How workspaces work

You list the folders that contain packages, and the package manager links them together.

With npm, in the root package.json:

{
  "private": true,
  "workspaces": ["apps/*", "packages/*"]
}

With pnpm, in pnpm-workspace.yaml:

packages:
  - "apps/*"
  - "packages/*"

An app then depends on the shared package by name:

{
  "dependencies": {
    "@acme/utils": "workspace:*"
  }
}

That workspace:* form is pnpm's. It guarantees the local package is used, never a copy from the registry. Change the utility library and both apps see it at once.

Running commands

# pnpm
pnpm install
pnpm --filter web dev
pnpm -r build

# npm
npm install
npm run dev --workspace=web
npm run build --workspaces

What pnpm does differently

One copy on disk. pnpm keeps every package version once in a global store and links it into each project. Ten projects that use the same React version share one copy, so installs are fast and disk use stays low.

Strict by default. With npm, a package can import something it never declared, because a dependency of a dependency happens to be installed next to it. This works until the day it does not. pnpm's layout makes such an import fail immediately, so the missing entry in package.json is found during development.

Filtering that understands the graph. pnpm --filter web... build builds the web app and everything it depends on, in the right order.

The two side by side

npm workspaces pnpm
Setup Built into npm One extra tool to install
Disk use Packages copied per repository One shared store
Undeclared imports Can work by accident Fail right away
Running a subset --workspace --filter, aware of dependencies

Which one to choose

For two or three packages and a team that wants nothing new to learn, npm workspaces are enough. Beyond that, we reach for pnpm: the strictness prevents a class of bugs, and install times stay short as the repository grows.

Whichever you pick, a workspace does not remove the need for upkeep. Keep the routine from dependency hygiene, and run the audit at the root so it covers every package.

Keep reading

  1. Tech Tips2 min read

    Dependency hygiene: audit, update and prune npm packages

    Outdated and unused packages are a security risk and a tax on every install. A short routine with npm audit, npm outdated and a cleanup tool keeps a project healthy.

  2. Tool Reviews2 min read

    Dev Containers: one environment for the whole team

    New developers lose days to setup, and 'works on my machine' never dies. A devcontainer.json file gives everyone the same tools, versions and services.

  3. Tool Reviews2 min read

    Why Vite is fast: native ES modules in development

    Vite starts a dev server in moments because it does not bundle your app first. How native ES modules, pre-bundled dependencies and hot module replacement make that work.

Tell us what’s in the way.

A few lines is enough. You get a candid yes, a candid no, or a sharper question.

  • Working software in week four
  • A reply in one business day
  • Handover is the deliverable

Prefer email? [email protected]

The problem, who it is for, and what is in the way right now.

One business day to a real reply. No sales sequence, no call required.