Streamlining Development: Adopting pnpm Workspaces for Monorepos

Introduction

Managing multiple, interconnected projects can often feel like herding cats. Each project might have its own node_modules directory, leading to duplicated dependencies, slower installation times, and a tangled web of local symlinks for inter-package development. For our vive-tu-mente-preview project, designed to preview new features and content, this fragmentation was becoming a noticeable drag on developer productivity.

The Challenge

Before adopting a monorepo structure, our approach involved separate repositories or loosely coupled packages within a single repository. This led to several common frustrations:

  • Redundant Dependencies: Multiple node_modules folders across various packages, consuming significant disk space.
  • Inconsistent Tooling: Difficulty in enforcing consistent linting, testing, and build processes across different but related codebases.
  • Complex Local Development: Testing changes in one package that affected another often required manual linking or complicated setup, slowing down iterative development.

The Solution

To combat these issues, we transitioned to a monorepo architecture managed by pnpm workspaces. pnpm is a fast, disk-space efficient package manager that shines when combined with its workspace feature. It allows us to manage multiple packages within a single repository, sharing a single node_modules structure and benefiting from pnpm's unique approach to dependency installation.

The core of our setup involves a pnpm-workspace.yaml file at the root, defining which subdirectories are part of the workspace:

# pnpm-workspace.yaml
packages:
  - 'apps/*'
  - 'packages/*'
  - 'shared/*'

Within each of these subdirectories (e.g., apps/web-app, packages/ui-library), we maintain standard package.json files for individual packages:

// packages/ui-library/package.json
{
  "name": "@vive-tu-mente/ui-library",
  "version": "1.0.0",
  "main": "src/index.js",
  "dependencies": {
    "react": "^18.2.0",
    "styled-components": "^6.1.1"
  },
  "devDependencies": {
    "eslint": "^8.56.0"
  }
}

This setup allows pnpm to intelligently manage dependencies across all workspace packages, hoisting common ones and creating symlinks for internal package dependencies, leading to significant improvements.

Key Decisions

  1. Choosing pnpm over npm/yarn: pnpm's unique content-addressable store ensures that dependencies are stored only once on disk, saving substantial space. Its strictness also helps prevent common dependency-related bugs.
  2. Logical Grouping: Organizing packages into apps/, packages/, and shared/ directories provides clear separation of concerns and maintainability.
  3. Unified Scripting: Centralizing common scripts (e.g., test, build) at the root level using pnpm -r <command> simplifies command execution across the entire monorepo.

Results

The adoption of pnpm workspaces brought immediate benefits to the vive-tu-mente-preview project:

  • Faster Installs: Dependency installation times were cut by more than half due to pnpm's efficient caching and linking strategy.
  • Reduced Disk Usage: Our node_modules footprint shrank dramatically.
  • Simplified Local Development: Iterating on changes across interdependent packages became seamless, requiring no manual linking.
  • Consistent Environment: Easier to maintain uniform tooling and dependency versions across the entire codebase.

Lessons Learned

Embracing a monorepo with pnpm workspaces can significantly enhance developer experience and operational efficiency, especially for projects with multiple interconnected components. Don't let the initial setup deter you; the long-term gains in consistency, speed, and maintainability are well worth the effort. For any new project anticipating multiple frontends, backends, or shared libraries, considering pnpm workspaces from day one is a highly recommended strategy to future-proof your development workflow.


Generated with Gitvlg.com

Streamlining Development: Adopting pnpm Workspaces for Monorepos
SOFIA DESIREE BARTOLI

SOFIA DESIREE BARTOLI

Author

Share: