Claude Code और pnpm workspace से practical monorepo बनाएं
Claude Code और pnpm workspace से छोटा monorepo बनाना सीखें: dependencies, filter, CI और common mistakes।
pnpm workspace code copy करने की आदत रोकता है
मैं Masa हूं, claudecode-lab.com चलाता हूं।
छोटा product भी जल्दी कई हिस्सों में बंट जाता है: public web app, admin app, shared UI, config, email jobs, content scripts और test utilities। असली समस्या folders की संख्या नहीं है। समस्या तब शुरू होती है जब वही button helper, वही API path, वही environment variable name या वही validation schema तीन जगह copy होता है।
pnpm workspace कई packages को एक Git repository में manage करने का तरीका है। Official pnpm Workspace docs बताती है कि workspace monorepo में कई projects को जोड़ता है और root में pnpm-workspace.yaml चाहिए।
Claude Code यहां blind generator से ज्यादा reviewer के रूप में काम आता है। यह देख सकता है कि workspace:* missing है या नहीं, packages/* गलत तरीके से apps/* import कर रहा है या नहीं, CI हर बार पूरा workspace चला रहा है या नहीं, और shared package में business logic घुस रही है या नहीं। Monorepo को simple रखने के लिए यही checks जरूरी हैं।
यह guide pnpm 11.5.0 पर आधारित है। Related reading के लिए Claude Code monorepo management और dependency management guide भी देखें।
Target structure: शुरुआत के लिए चार packages काफी हैं
पहले दिन बड़ा platform repository बनाने की जरूरत नहीं है। दो apps और दो shared packages से boundary साफ रहती है।
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
तीन practical use cases हैं। पहला, packages/ui में common display helpers और छोटे UI primitives रखें जिन्हें web और admin दोनों use करें। दूसरा, packages/config में public URL, feature flag names और constants रखें ताकि apps drift न करें। तीसरा, बाद में packages/contracts जोड़कर API types या Zod schemas frontend और backend में share करें।
packages/common बनाकर सब कुछ उसमें डालना सबसे आम गलती है। Shared code का अर्थ है कि हर caller से उसका मतलब एक जैसा रहे। Claude Code को भी clear instruction दें: “सिर्फ duplicate UI helper extract करो, billing logic app में ही रहे।“
Copy-paste minimum setup
Root में pnpm-workspace.yaml रखें। Official pnpm-workspace.yaml docs बताती है कि packages से directories include होती हैं और exclude pattern भी मिलते हैं।
packages:
- "apps/*"
- "packages/*"
catalog:
typescript: ^5.8.3
Root package.json सिर्फ commands coordinate करे।
{
"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
}
}
.npmrc में local resolution साफ रखें:
link-workspace-packages=false
save-workspace-protocol=rolling
shared-workspace-lockfile=true
strict-peer-dependencies=true
auto-install-peers=false
मुख्य बात workspace:* है। pnpm docs के अनुसार workspace: protocol dependency को local workspace package के अलावा कहीं resolve नहीं करता। इससे internal package के नाम से मिलते-जुलते registry package accidentally install नहीं होते।
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 config को workspace dependency की तरह use करे।
{
"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 side केवल direct dependencies declare करे।
{
"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"));
Run करें:
corepack pnpm install
corepack pnpm --filter @acme/web build
corepack pnpm -r --sort --if-present build
Claude Code को package boundary पहले बताएं
Claude Code की official guide monorepos and large codebases बताती है कि बड़े repo में irrelevant files context भर देती हैं। pnpm workspace में भी यही नियम लागू होता है। Root से काम कर सकते हैं, लेकिन scope साफ होना चाहिए।
Root CLAUDE.md में global rules रखें:
# 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.
Package-specific rules उसी directory में रखें। Claude Code की memory documentation के अनुसार CLAUDE.md persistent instructions देता है, इसलिए इसे छोटा और specific रखें।
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.
"
पहले inspect और फिर edit करने की आदत unnecessary abstraction कम करती है।
filter development और CI को हल्का रखता है
pnpm Filtering command को selected packages तक सीमित करता है।
pnpm --filter @acme/web build
pnpm --filter @acme/web... build
pnpm --filter ...@acme/ui test
pnpm --filter "...[origin/main]" --if-present test
सबसे common mistake ... की direction है। @acme/web... web और उसकी dependencies चुनता है। ...@acme/ui ui और उस पर depend करने वाले apps चुनता है। UI change के बाद सिर्फ @acme/ui... चलाने से web/admin tests छूट सकते हैं।
CI को affected packages तक रख सकते हैं:
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
Common mistakes और fixes
पहली गलती internal package को normal semver की तरह लिखना है।
{
"dependencies": {
"@acme/ui": "^0.1.0"
}
}
Workspace में इसे ऐसे लिखें:
{
"dependencies": {
"@acme/ui": "workspace:*"
}
}
दूसरी गलती shared package में app-specific logic डालना है। packages/ui API call या billing decision न करे। तीसरी गलती circular dependency है। अगर packages/ui apps/web import करता है, design उल्टा हो चुका है।
Claude Code से यह audit कराएं:
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.
"
Publish करना हो तो Changesets जोड़ें:
pnpm add -Dw @changesets/cli
pnpm changeset init
pnpm changeset
pnpm changeset version
pnpm -r publish --access public
pnpm docs versioning के लिए Changesets या Rush जैसे tools की ओर इशारा करती हैं। apps/* packages आम तौर पर private: true रहने चाहिए।
Summary और practical result
pnpm workspace भारी build system नहीं है। यह shared UI, config, types और tests को copied files की जगह explicit dependencies बनाता है। Claude Code तब सबसे उपयोगी है जब वह package graph review करे, minimal change suggest करे और CI failures narrow करे।
Next step के लिए CLAUDE.md best practices और Claude Code testing strategies पढ़ें। Team rollout के लिए Claude Code training देखें।
इस article के examples Windows, Node.js 22, Corepack और pnpm 11.5.0 기준 पर check किए गए। Real projects में workspace:* भूलना और filter direction उल्टा लिखना सबसे आम गलती है। Edit से पहले Claude Code से package graph निकलवाने की habit unnecessary commonization और circular dependencies जल्दी पकड़ती है।
मुफ़्त PDF: Claude Code cheatsheet
Email डालें और commands, review habits तथा safe workflow वाली एक-page PDF पाएँ.
हम आपका data सुरक्षित रखते हैं और spam नहीं भेजते.
लेखक के बारे में
Masa
Claude Code workflow और team adoption पर काम करने वाला engineer.
संबंधित लेख
Claude Code Obsidian to CLAUDE.md workflow: context बार-बार न समझाएं
Obsidian notes को CLAUDE.md operating notes में बदलकर Claude Code sessions को resume करना आसान बनाएं.
Claude Code Revenue CTA Routing: article से PDF, Gumroad और consultation तक
Reader intent के आधार पर free PDF, Gumroad products और consultation तक CTA route करने वाला workflow.
Claude Code टीम हैंडऑफ नियम: review proof, permissions, rollback और revenue path
Claude Code टीम काम के लिए evidence, permission rules, rollback, free PDF, Gumroad और consultation path वाला handoff.