Skip to main content 홈 크리에이터 inugamidev ultrathink-oss monorepo-config
monorepo-config Monorepo configuration — shared configs, package publishing, internal packages, versioning strategies, Git optimization (sparse checkout, worktrees, LFS)
설치로 이동 Skills Marketplace 커뮤니티가 만든 AI 스킬을 발견하고 탐색하세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/InugamiDev/ultrathink-oss --skill monorepo-config명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
Zip 다운로드 다운로드 중... 이 저장소의 다른 Skills Unified design foundations — design system architecture, tokens, component specs, visual principles, creative vision, figma integration, plus brand design system loader (66 real brands via DESIGN.md). Absorbs design, design-system, design-systems, design-principles, design-router, creative-vision, figma, design-md.
Render, summarize, and present markdown documents and structured content in multiple output modes
Ultra UI skill - combines Google's DESIGN.md spec (machine-readable design tokens) with the ui-ux-pro-max knowledge base (91 styles, 161 palettes, 73 font pairings, 161 products, 104 UX guidelines, 25 chart types). Generates lint-clean DESIGN.md files, validates token references and WCAG contrast, exports Tailwind/DTCG tokens, and diffs design systems version-over-version.
name monorepo-config description Monorepo configuration — shared configs, package publishing, internal packages, versioning strategies, Git optimization (sparse checkout, worktrees, LFS) layer domain category build-tools triggers ["shared config","internal package","package publishing","monorepo config","workspace config","changesets","git monorepo","sparse checkout","git worktree","shallow clone","large repo","git lfs","monorepo"] inputs ["Monorepo structure and workspace setup needs","Shared configuration requirements across packages","Package publishing and versioning workflows","Internal package dependency management"] outputs ["Workspace configuration files","Shared config packages (ESLint, TypeScript, Tailwind)","Changesets versioning setup","Internal package build and linking strategies"] linksTo ["turborepo","pnpm","nx","git-workflow"] linkedFrom [] preferredNextSkills ["turborepo","pnpm"] fallbackSkills ["monorepo"] riskLevel low memoryReadPolicy selective memoryWritePolicy none sideEffects []
Monorepo Configuration
Purpose
Provide expert guidance on configuring monorepo workspaces with shared configs, internal packages, package publishing pipelines, and versioning strategies. Covers pnpm workspaces, Turborepo integration, shared configuration packages, and Changesets for automated versioning and publishing.
Key Patterns
Workspace Structure
Standard monorepo layout with pnpm workspaces:
monorepo/
package.json # Root package.json
pnpm-workspace.yaml # Workspace definition
turbo.json # Turborepo pipeline config
.changeset/ # Changesets config
config.json
packages/
config-eslint/ # Shared ESLint config
config-typescript/ # Shared TypeScript config
config-tailwind/ # Shared Tailwind config
ui/ # Shared UI component library
utils/ # Shared utilities
apps/
web/ # Next.js web app
api/ # API server
docs/ # Documentation site
pnpm-workspace.yaml:
packages:
- "apps/*"
- "packages/*"
Root package.json:
{
"name" : "monorepo" ,
"private" : true ,
"scripts" : {
"build" : "turbo build" ,
"dev" : "turbo dev" ,
"lint" : "turbo lint" ,
"test" : "turbo test"
,
"format"
:
"prettier --write \"**/*.{ts,tsx,md,json}\""
,
"changeset"
:
"changeset"
,
"version-packages"
:
"changeset version"
,
"release"
:
"turbo build --filter='./packages/*' && changeset publish"
}
,
"devDependencies"
:
{
"@changesets/cli"
:
"^2.27.0"
,
"prettier"
:
"^3.2.0"
,
"turbo"
:
"^2.3.0"
}
,
"packageManager"
:
"pnpm@9.15.0"
}
Shared ESLint Configuration Create a shared ESLint config package that all apps and packages extend.
{
"name" : "@repo/eslint-config" ,
"version" : "0.1.0" ,
"private" : true ,
"exports" : {
"./base" : "./base.js" ,
"./next" : "./next.js" ,
"./react" : "./react.js" ,
"./node" : "./node.js"
} ,
"dependencies" : {
"@typescript-eslint/eslint-plugin" : "^8.0.0" ,
"@typescript-eslint/parser" : "^8.0.0" ,
"eslint-config-prettier" : "^9.1.0" ,
"eslint-plugin-import" : "^2.29.0"
}
}
import tsPlugin from "@typescript-eslint/eslint-plugin" ;
import tsParser from "@typescript-eslint/parser" ;
import importPlugin from "eslint-plugin-import" ;
export default [
{
files : ["**/*.ts" , "**/*.tsx" ],
plugins : {
"@typescript-eslint" : tsPlugin,
import : importPlugin,
},
languageOptions : {
parser : tsParser,
parserOptions : {
projectService : true ,
},
},
rules : {
"@typescript-eslint/no-unused-vars" : [
"error" ,
{ argsIgnorePattern : "^_" , varsIgnorePattern : "^_" },
],
"@typescript-eslint/consistent-type-imports" : "error" ,
"import/order" : [
"error" ,
{
groups : [
"builtin" ,
"external" ,
"internal" ,
"parent" ,
"sibling" ,
"index" ,
],
"newlines-between" : "always" ,
alphabetize : { order : "asc" },
},
],
"import/no-duplicates" : "error" ,
},
},
];
import baseConfig from "@repo/eslint-config/base" ;
import nextConfig from "@repo/eslint-config/next" ;
export default [...baseConfig, ...nextConfig];
Shared TypeScript Configuration
{
"name" : "@repo/typescript-config" ,
"version" : "0.1.0" ,
"private" : true ,
"exports" : {
"./base" : "./base.json" ,
"./next" : "./next.json" ,
"./react-library" : "./react-library.json" ,
"./node" : "./node.json"
}
}
{
"$schema" : "https://json.schemastore.org/tsconfig" ,
"compilerOptions" : {
"strict" : true ,
"esModuleInterop" : true ,
"skipLibCheck" : true ,
"forceConsistentCasingInFileNames" : true ,
"moduleResolution" : "bundler" ,
"module" : "ESNext" ,
"target" : "ES2022" ,
"lib" : [ "ES2022" ] ,
"resolveJsonModule" : true ,
"isolatedModules" : true ,
"incremental" : true ,
"declaration" : true ,
"declarationMap" : true ,
"sourceMap" : true
} ,
"exclude" : [ "node_modules" , "dist" ]
}
{
"$schema" : "https://json.schemastore.org/tsconfig" ,
"extends" : "./base.json" ,
"compilerOptions" : {
"lib" : [ "ES2022" , "DOM" , "DOM.Iterable" ] ,
"module" : "ESNext" ,
"jsx" : "preserve" ,
"plugins" : [ { "name" : "next" } ] ,
"paths" : {
"@/*" : [ "./src/*" ]
}
}
}
{
"extends" : "@repo/typescript-config/next" ,
"include" : [ "next-env.d.ts" , "**/*.ts" , "**/*.tsx" , ".next/types/**/*.ts" ] ,
"exclude" : [ "node_modules" ]
}
Internal Packages Internal packages used within the monorepo but not published to npm.
{
"name" : "@repo/ui" ,
"version" : "0.1.0" ,
"private" : true ,
"exports" : {
"." : "./src/index.ts" ,
"./button" : "./src/button.tsx" ,
"./card" : "./src/card.tsx"
} ,
"devDependencies" : {
"@repo/typescript-config" : "workspace:*" ,
"react" : "^19.0.0" ,
"typescript" : "^5.7.0"
} ,
"peerDependencies" : {
"react" : "^19.0.0"
}
}
Key pattern: source-level imports (no build step for internal packages):
{
"$schema" : "https://turbo.build/schema.json" ,
"tasks" : {
"build" : {
"dependsOn" : [ "^build" ] ,
"outputs" : [ ".next/**" , "dist/**" ]
} ,
"dev" : {
"cache" : false ,
"persistent" : true
} ,
"lint" : {
"dependsOn" : [ "^lint" ]
} ,
"test" : {
"dependsOn" : [ "^build" ]
}
}
}
For internal packages consumed via source, Next.js transpiles them automatically:
const nextConfig = {
transpilePackages : ["@repo/ui" , "@repo/utils" ],
};
export default nextConfig;
Changesets for Versioning and Publishing
{
"$schema" : "https://unpkg.com/@changesets/config@3.0.0/schema.json" ,
"changelog" : "@changesets/cli/changelog" ,
"commit" : false ,
"fixed" : [ ] ,
"linked" : [ [ "@repo/ui" , "@repo/utils" ] ] ,
"access" : "public" ,
"baseBranch" : "main" ,
"updateInternalDependencies" : "patch" ,
"ignore" : [ "@repo/eslint-config" , "@repo/typescript-config" ]
}
pnpm changeset
pnpm changeset version
pnpm changeset publish
GitHub Actions for automated releases:
name: Release
on:
push:
branches: [main ]
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm
- run: pnpm install --frozen-lockfile
- name: Create Release PR or Publish
uses: changesets/action@v1
with:
publish: pnpm release
version: pnpm version-packages
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
Shared Tailwind Configuration
import type { Config } from "tailwindcss" ;
const config : Omit <Config , "content" > = {
theme : {
extend : {
colors : {
brand : {
50 : "#eff6ff" ,
500 : "#3b82f6" ,
600 : "#2563eb" ,
700 : "#1d4ed8" ,
900 : "#1e3a8a" ,
},
},
borderRadius : {
DEFAULT : "0.5rem" ,
},
spacing : {
18 : "4.5rem" ,
88 : "22rem" ,
},
},
},
plugins : [],
};
export default config;
import type { Config } from "tailwindcss" ;
import sharedConfig from "@repo/config-tailwind/tailwind.config" ;
const config : Config = {
...sharedConfig,
content : [
"./src/**/*.{ts,tsx}" ,
"../../packages/ui/src/**/*.{ts,tsx}" ,
],
};
export default config;
Best Practices
Use workspace:* protocol for internal dependencies -- pnpm resolves them to the local package during development and replaces with actual versions on publish.
Prefer source-level imports for internal packages -- skip the build step and let the consuming app's bundler handle transpilation.
Keep shared configs as separate packages -- @repo/eslint-config, @repo/typescript-config, @repo/config-tailwind.
Use linked in Changesets to version related packages together.
Mark internal-only packages as private: true to prevent accidental publishing.
Include transpilePackages in Next.js config for any workspace package imported from source.
Use Turborepo's dependsOn: ["^build"] to ensure dependencies build before dependents.
Common Pitfalls Pitfall Problem Fix Missing workspace:* protocol pnpm fetches from npm registry instead of local Use "@repo/ui": "workspace:*" in dependencies Forgetting transpilePackages Next.js fails to parse TypeScript from workspace packages Add internal packages to transpilePackages array Circular dependencies between packages Build fails or infinite loops Restructure -- extract shared types into a separate @repo/types package Running pnpm install in a package subdirectory Creates a separate lockfile Always run pnpm install from the monorepo root Publishing without Changesets Version bumps are manual and error-prone Use Changesets for automated, consistent versioning Content paths missing shared UI Tailwind misses classes from workspace packages Add ../../packages/ui/src/**/*.{ts,tsx} to content array
Git Strategies for Large Monorepos
Sparse Checkout Work with only a subset of the repository tree:
git clone --sparse --filter=blob:none https://github.com/org/monorepo.git
cd monorepo
git sparse-checkout add packages/web packages/shared libs/utils
- uses: actions/checkout@v4
with:
sparse-checkout: |
packages/web
packages/shared
package.json
pnpm-lock.yaml
sparse-checkout-cone-mode: true
fetch-depth: 1
Shallow & Treeless Clones
git clone --depth=1 --single-branch https://github.com/org/monorepo.git
git clone --filter=blob:none https://github.com/org/monorepo.git
Strategy Clone Time Full History Blame/Bisect Full clone Slow Yes Yes --depth=1Fast No No --filter=blob:noneMedium Yes Yes (on demand) --filter=blob:none --sparseFast Yes (sparse) Yes
Git Worktrees Work on multiple branches simultaneously without stashing:
git worktree add ../monorepo-feature-x feature/new-auth
git worktree add -b hotfix/urgent ../monorepo-hotfix main
git worktree list
git worktree remove ../monorepo-feature-x
Git LFS Track large binary files without bloating the repo:
git lfs install
git lfs track "*.psd" "*.mp4" "assets/models/**"
Performance Tuning git config core.fsmonitor true
git config core.untrackedCache true
git commit-graph write --reachable
git maintenance start
git config protocol.version 2
git config fetch.parallel 4
Git Pitfalls Pitfall Fix --depth=1 then git blameUse --filter=blob:none instead Forgetting lockfile in sparse checkout Always include root config files LFS pointers in CI Add git lfs install step or lfs: true Worktree on same branch Use git worktree add -b new-branch