Use Cases (Diperbarui: 2/6/2026)

Monorepo praktis dengan Claude Code dan pnpm workspace

Bangun monorepo kecil dengan Claude Code dan pnpm workspace: dependency, filter, CI, dan jebakan umum.

Monorepo praktis dengan Claude Code dan pnpm workspace

pnpm workspace membantu menghentikan kebiasaan copy-paste kode

Saya Masa, pengelola claudecode-lab.com.

Produk kecil pun cepat berubah menjadi beberapa bagian: aplikasi web, panel admin, UI bersama, konfigurasi, job email, script konten, dan utilitas test. Masalah sebenarnya bukan jumlah folder. Masalah muncul ketika helper UI, nama environment variable, API path, atau schema validasi yang sama mulai disalin ke beberapa tempat.

pnpm workspace adalah cara mengelola beberapa package di satu repository Git. Dokumentasi resmi pnpm Workspace menjelaskan bahwa workspace menyatukan beberapa project dalam satu repository dan membutuhkan pnpm-workspace.yaml di root.

Claude Code paling berguna sebagai reviewer. Ia bisa memeriksa apakah workspace:* hilang, apakah packages/* mengimpor dari apps/*, apakah CI menjalankan semua package tanpa perlu, atau apakah shared package mulai diisi business logic. Pemeriksaan kecil seperti ini yang membuat monorepo tetap ringan.

Artikel ini memakai pnpm 11.5.0. Untuk konteks lebih luas, baca juga Claude Code monorepo management dan dependency management guide.


Struktur target: empat package cukup untuk mulai

Jangan mulai dengan repository platform yang terlalu besar. Dua app dan dua shared package sudah memberi batas yang jelas.

flowchart LR
  web["apps/web\n@acme/web"] --> ui["packages/ui\n@acme/ui"]
  web --> config["packages/config\n@acme/config"]
  admin["apps/admin\n@acme/admin"] --> ui
  admin --> config
acme-workspace/
  apps/web/src/main.ts
  apps/web/package.json
  apps/admin/src/main.ts
  apps/admin/package.json
  packages/config/src/index.ts
  packages/config/package.json
  packages/ui/src/index.ts
  packages/ui/package.json
  pnpm-workspace.yaml
  package.json
  .npmrc
  CLAUDE.md

Ada setidaknya tiga use case. Pertama, packages/ui menyimpan helper tampilan dan primitive UI kecil yang dipakai web dan admin. Kedua, packages/config menyimpan URL publik, nama feature flag, dan konstanta agar aplikasi tidak berbeda-beda. Ketiga, nanti kamu bisa menambah packages/contracts untuk berbagi tipe API atau schema Zod antara frontend dan backend.

Jebakan umum adalah membuat packages/common lalu memasukkan semua hal ke sana. Shared code harus punya makna yang sama dari semua consumer. Saat meminta bantuan Claude Code, tulis batasnya: “extract hanya helper UI yang duplikat, business logic billing tetap di app”.


Konfigurasi minimum yang bisa disalin

Mulai dari pnpm-workspace.yaml. Halaman resmi pnpm-workspace.yaml menunjukkan cara include dan exclude directory.

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

catalog:
  typescript: ^5.8.3

package.json root hanya mengoordinasikan command.

{
  "name": "acme-workspace",
  "private": true,
  "packageManager": "pnpm@11.5.0",
  "scripts": {
    "check:web": "pnpm --filter @acme/web build",
    "build": "pnpm -r --sort --if-present build",
    "test": "pnpm -r --if-present test",
    "changed:test": "pnpm --filter \"...[origin/main]\" --if-present test"
  },
  "devDependencies": {
    "typescript": "catalog:"
  }
}

tsconfig.base.json:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "strict": true,
    "skipLibCheck": true,
    "noEmit": true
  }
}

Di .npmrc, buat resolusi local dependency menjadi eksplisit:

link-workspace-packages=false
save-workspace-protocol=rolling
shared-workspace-lockfile=true
strict-peer-dependencies=true
auto-install-peers=false

Bagian pentingnya adalah workspace:*. Dokumentasi pnpm menjelaskan bahwa protocol workspace: tidak akan resolve dependency ke luar workspace local. Ini mencegah package internal tertukar dengan package di registry yang namanya sama.

packages/config/package.json:

{
  "name": "@acme/config",
  "version": "0.1.0",
  "private": true,
  "type": "module",
  "exports": {
    ".": {
      "types": "./src/index.ts",
      "import": "./src/index.ts"
    }
  }
}
export const appConfig = {
  productName: "Acme Workspace",
  supportEmail: "support@example.com",
  publicSiteUrl: "https://example.com"
} as const;

packages/ui memakai config melalui workspace dependency.

{
  "name": "@acme/ui",
  "version": "0.1.0",
  "private": true,
  "type": "module",
  "dependencies": {
    "@acme/config": "workspace:*"
  },
  "exports": {
    ".": {
      "types": "./src/index.ts",
      "import": "./src/index.ts"
    }
  }
}
import { appConfig } from "@acme/config";

export function renderPrimaryButton(label: string): string {
  return `[${appConfig.productName}] ${label}`;
}

App hanya mendeklarasikan dependency yang dipakai langsung.

{
  "name": "@acme/web",
  "version": "0.1.0",
  "private": true,
  "type": "module",
  "scripts": {
    "build": "tsc -p tsconfig.json"
  },
  "dependencies": {
    "@acme/config": "workspace:*",
    "@acme/ui": "workspace:*"
  }
}

apps/web/tsconfig.json:

{
  "extends": "../../tsconfig.base.json",
  "include": ["src"]
}
import { appConfig } from "@acme/config";
import { renderPrimaryButton } from "@acme/ui";

console.log(appConfig.publicSiteUrl);
console.log(renderPrimaryButton("Start trial"));

Jalankan:

corepack pnpm install
corepack pnpm --filter @acme/web build
corepack pnpm -r --sort --if-present build

Ajari Claude Code batas package terlebih dahulu

Claude Code memiliki panduan resmi untuk monorepos and large codebases. Intinya: kurangi file yang tidak relevan dari context. Dalam pnpm workspace, memulai dari root boleh saja, tetapi scope task harus jelas.

CLAUDE.md root cukup berisi aturan global:

# Acme Workspace

This repository is a pnpm workspace.

Packages:
- apps/web: customer-facing TypeScript app
- apps/admin: internal admin app
- packages/ui: shared UI helpers
- packages/config: shared runtime constants

Rules:
- Use pnpm, not npm or yarn.
- Add internal dependencies with workspace:*.
- Run focused commands with pnpm --filter before full workspace commands.
- Do not move business logic into packages/ui.

Aturan lokal taruh di directory package. Dokumentasi memory Claude Code menjelaskan bahwa CLAUDE.md adalah instruksi persisten. Karena itu, isinya harus pendek, spesifik, dan mudah dirawat.

claude -p "
Inspect this pnpm workspace. Do not edit files yet.
List the package graph, scripts, and risky dependency directions.
Then propose the smallest change needed to share UI helpers between apps/web and apps/admin.
"

Prompt ini membuat Claude Code memeriksa dulu sebelum mengedit, sehingga perubahan besar yang tidak perlu lebih mudah dicegah.


filter membuat development dan CI lebih ringan

pnpm Filtering membatasi command ke subset package.

pnpm --filter @acme/web build
pnpm --filter @acme/web... build
pnpm --filter ...@acme/ui test
pnpm --filter "...[origin/main]" --if-present test

Kesalahan paling umum adalah arah .... @acme/web... memilih web dan dependency-nya. ...@acme/ui memilih ui dan package yang bergantung pada ui. Setelah mengubah UI, menjalankan hanya @acme/ui... bisa melewatkan test web/admin.

CI yang fokus bisa seperti ini:

name: workspace-check

on:
  pull_request:

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: pnpm
      - run: corepack enable
      - run: corepack prepare pnpm@11.5.0 --activate
      - run: pnpm install --frozen-lockfile
      - run: pnpm --filter "...[origin/main]" --if-present test
      - run: pnpm --filter "...[origin/main]" --if-present build

Jebakan umum dan cara memperbaikinya

Jebakan pertama adalah dependency internal ditulis seperti semver biasa:

{
  "dependencies": {
    "@acme/ui": "^0.1.0"
  }
}

Di workspace, tulis:

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

Jebakan kedua adalah shared package berisi logic khusus app. packages/ui tidak seharusnya memanggil API atau menentukan plan billing. Jebakan ketiga adalah circular dependency. Jika packages/ui mengimpor dari apps/web, arah desain sudah salah.

Minta Claude Code melakukan audit seperti ini:

claude -p "
Check this workspace for circular dependencies and misplaced imports.
Focus on packages/* importing from apps/*, duplicated config values,
and dependencies that should be workspace:*.
Return findings with file paths and minimal fixes.
"

Jika perlu publish package, tambahkan Changesets:

pnpm add -Dw @changesets/cli
pnpm changeset init
pnpm changeset
pnpm changeset version
pnpm -r publish --access public

Dokumentasi pnpm mengarahkan versioning package workspace ke tools seperti Changesets atau Rush. Package apps/* biasanya tetap private: true.


Ringkasan dan hasil praktik

pnpm workspace bukan build system yang berat. Ia adalah dasar kecil untuk membuat UI, konfigurasi, tipe, dan test bersama menjadi dependency eksplisit, bukan file salinan. Claude Code membantu saat digunakan untuk review package graph, mengusulkan perubahan minimal, dan mempersempit kegagalan CI.

Langkah berikutnya adalah membaca CLAUDE.md best practices dan Claude Code testing strategies. Untuk rollout tim, gunakan halaman Claude Code training.

Contoh di artikel ini dicek dengan Windows, Node.js 22, Corepack, dan pnpm 11.5.0. Di project nyata, kesalahan paling sering adalah lupa workspace:* dan membalik arah filter. Membiasakan Claude Code menampilkan package graph sebelum mengedit membantu menemukan abstraksi yang tidak perlu dan circular dependency lebih awal.

#claude-code #pnpm #workspace #monorepo #typescript #ci
Gratis

PDF gratis: cheatsheet Claude Code

Masukkan email dan unduh satu halaman berisi command, kebiasaan review, dan workflow aman.

Kami menjaga datamu dan tidak mengirim spam.

Masa

Tentang penulis

Masa

Engineer yang berfokus pada workflow Claude Code praktis dan adopsi tim.