Skip to content

Npm Workspace

Directory Structure

.
├── apps
│   └── src
│       ├── dist
│       │   ├── index.d.ts
│       │   └── index.js
│       ├── index.ts
│       ├── package.json
│       └── tsconfig.json
├── biome.json
├── Makefile
├── node_modules
│   └──  *
├── package.json
├── package-lock.json
└── packages
    ├── fizzbuzz
    │   ├── dist
    │   │   ├── index.d.ts
    │   │   └── index.js
    │   ├── index.ts
    │   ├── package.json
    │   └── tsconfig.json
    └── tsconfig
        ├── package.json
        └── packages
            └── tsconfig.json

package.json

package.json
json
{
  "name": "npm-workspace-test",
  "private": true,
  "scripts": {
    "fmt": "npx @biomejs/biome format --write ./"
  },
  "workspaces": ["apps/*", "packages/*"],
  "devDependencies": {
    "@biomejs/biome": "^1.9.4",
    "tsx": "^4.19.1"
  }
}

apps

ts
import { fizzBuzz } from '@packages/fizzbuzz'

console.log('npm workspace')
console.log(fizzBuzz(100))

package.json

json
{
  "name": "@apps/src",
  "version": "1.0.0",
  "private": true,
  "type": "module",
  "exports": "./dist/index.js",
  "scripts": {
    "build": "tsc"
  },
  "dependencies": {
    "@packages/fizzbuzz": "^1.0.0"
  },
  "devDependencies": {
    "@types/node": "^22.7.9",
    "typescript": "^5.6.3"
  }
}

packages

ts
export const fizzBuzz = (number: number): string => {
  if (number % 15 === 0) return 'FizzBuzz'
  if (number % 3 === 0) return 'Fizz'
  if (number % 5 === 0) return 'Buzz'
  return number.toString()
}

package.json

json
{
  "name": "@packages/fizzbuzz",
  "version": "1.0.0",
  "private": true,
  "type": "module",
  "exports": "./dist/index.js",
  "scripts": {
    "build": "tsc"
  },
  "devDependencies": {
    "@packages/tsconfig": "^1.0.0",
    "@types/node": "^22.7.9",
    "typescript": "^5.6.3"
  }
}

tsconfig

json
{
  "compilerOptions": {
    "target": "es2016",
    "module": "NodeNext",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true,
    "declaration": true
  }
}

package.json

json
{
  "name": "@packages/tsconfig",
  "version": "1.0.0",
  "private": true
}

Execution

sh
npm install
npm run build -w packages/fizzbuzz
npm run build -w apps/src
npx tsx watch apps/src/index.ts
Hello World!
Buzz