Pnpm Monorepo

How to create a monorepo with pnpm workspaces

Table of Contents

Create a basic monorepo

pnpm-workspace.yaml

packages:
  - 'sites/*'
  - 'packages/*'
  - 'services/*'
  • sites: contains website (homepage, blog, etc.)
  • packages: contains shared packages (sdk, database clients, etc.)
  • services: contains services (api, database, etc.)

Create a shared package

packages/shared/package.json

{
	"name": "shared-package-name",
	"scripts": {
		"dev": "some dev command"
	},
	// ...
	"exports": {
		".": {
			"import": "./index.ts",
			"types": "./index.ts" // or .d.ts
		},
		"./sub-package": {
			"import": "./sub-package/index.ts",
			"types": "./sub-package/index.ts" // or .d.ts
		}
	}
}

Use code from shared package

sites/my-site/package.json

{
	"dependencies": {
		"shared-package-name": "workspace:*" // * always uses the newest version
	}
}
pnpm i
import { someFunction } from 'shared-package-name';
import { someFunction } from 'shared-package-name/sub-package';

Commands

Run command in shared package anywhere in the monorepo

pnpm -F shared-package-name run dev

Recursive scripts

If you want to run the dev command in all packages, you can use the -r flag.

pnpm -r run dev

Update every node package

pnpm -r update -i -L

Delete every node_modules folder

find ./ -name node_modules -type d -exec rm -rf {} +

View installed npm package versions

pnpm -F shared-package-name why your-npm-package-name

Add npm package to shared package

pnpm -F shared-package-name add your-npm-package-name

Or cd into the package and install using pnpm add your-npm-package-name

Packages installed using the -w flag in the root directory are available for every package