[{"data":1,"prerenderedAt":1053},["ShallowReactive",2],{"blog-monorepo":3,"blog-monorepo-favor-of":1029},{"id":4,"title":5,"body":6,"cover_image":1029,"date":1030,"decidedDate":1030,"decision":1031,"decisionInFavorOf":1029,"decisionReason":1032,"description":1033,"evaluatedScore":562,"extension":1034,"link":1029,"logoPath":1029,"meta":1035,"navigation":565,"path":1036,"placements":1037,"reviewTrigger":1029,"satisfaction":1029,"seo":1041,"stage":1042,"stem":1043,"tags":1044,"target":1029,"type":1051,"__hash__":1052},"radar\u002Fradar\u002Fmonorepo.md","Monorepo",{"type":7,"value":8,"toc":1007},"minimark",[9,14,18,30,37,46,49,54,61,64,69,91,130,134,148,158,206,208,212,215,219,238,242,257,260,276,301,303,307,310,314,338,341,357,361,382,385,408,410,414,420,424,427,443,451,459,462,665,667,671,856,858,862,919,921,925,928,1003],[10,11,13],"h1",{"id":12},"monorepo-architecture-from-native-workspaces-to-polyglot-build-systems","Monorepo Architecture: From Native Workspaces to Polyglot Build Systems",[15,16,17],"p",{},"One repository for related services, libraries, and applications, rather than scattering them across a dozen disconnected repositories.",[15,19,20,21,25,26],{},"The most common objection to monorepos—",[22,23,24],"em",{},"\"How do we maintain independent deployability?\"","—conflates code organization with artifact delivery. ",[27,28,29],"strong",{},"Independent deployment is a CI\u002FCD pipeline concern, not a repository layout problem.",[15,31,32,33,36],{},"With path-based triggers, containerized builds, and targeted deployment pipelines, services in a monorepo deploy just as independently as polyrepo services. The difference is developer velocity: when a cross-cutting feature spans an API contract, two backend microservices, and a frontend client, it lives in a ",[27,34,35],{},"single atomic Pull Request",". It is reviewed together, type-checked together, and merged without the fragile ceremony of semantic version bumping, registry publishing, and multi-repo deployment sequencing.",[15,38,39,40,45],{},"See also: ",[41,42,44],"a",{"href":43},"\u002Fblog\u002Fpolyrepo","Polyrepo",", the alternative this was weighed against.",[47,48],"hr",{},[50,51,53],"h2",{"id":52},"_1-the-foundation-native-package-manager-workspaces","1. The Foundation: Native Package Manager Workspaces",[15,55,56,57,60],{},"Before reaching for heavy monorepo build orchestrators, every modern monorepo starts with ",[27,58,59],{},"native package manager workspaces",".",[15,62,63],{},"Workspaces solve the fundamental code-sharing problem: allowing internal packages to depend on one another locally via symlinks without publishing intermediate packages to npm or PyPI.",[65,66,68],"h3",{"id":67},"pnpm-workspaces-typescript-nodejs","pnpm Workspaces (TypeScript \u002F Node.js)",[15,70,71,72,78,79,83,84,90],{},"In the JavaScript and TypeScript world, ",[27,73,74],{},[41,75,77],{"href":76},"\u002Fblog\u002Fpnpm","pnpm workspaces"," (configured via ",[80,81,82],"code",{},"pnpm-workspace.yaml",") is our adopted foundation, replacing legacy ",[27,85,86],{},[41,87,89],{"href":88},"\u002Fblog\u002Fnpm","npm",":",[92,93,94,110,120],"ul",{},[95,96,97,100,101,105,106,109],"li",{},[27,98,99],{},"Strict symlink isolation:"," Unlike ",[27,102,103],{},[41,104,89],{"href":88}," or Yarn classic which flatten ",[80,107,108],{},"node_modules"," and invite phantom dependency bugs, pnpm's content-addressable store creates strict, isolated symlinks.",[95,111,112,115,116,119],{},[27,113,114],{},"Workspace protocol:"," Using ",[80,117,118],{},"\"@org\u002Fshared-ui\": \"workspace:*\""," ensures internal dependencies always link directly to local source code during development.",[95,121,122,125,126,129],{},[27,123,124],{},"Recursive commands:"," Commands like ",[80,127,128],{},"pnpm --filter .\u002Fapps\u002Fweb build"," allow scoped execution across projects.",[65,131,133],{"id":132},"uv-workspaces-python","uv Workspaces (Python)",[15,135,136,137,143,144,147],{},"Historically, Python was notoriously painful in monorepos. Legacy tools like ",[27,138,139],{},[41,140,142],{"href":141},"\u002Fblog\u002Fpip","pip"," and requirements.txt (as well as Poetry and Pipenv) lacked native workspace semantics, forcing brittle ",[80,145,146],{},"pip install -e ."," hacks or complex path manipulation.",[15,149,150,151,157],{},"Astral's ",[27,152,153],{},[41,154,156],{"href":155},"\u002Fblog\u002Fuv","uv workspaces"," changed the game completely:",[92,159,160,178,191],{},[95,161,162,165,166,169,170,173,174,177],{},[27,163,164],{},"Single unified lockfile:"," A root ",[80,167,168],{},"pyproject.toml"," declares ",[80,171,172],{},"[tool.uv.workspace]",", resolving a single, deterministic ",[80,175,176],{},"uv.lock"," across all microservices, shared libraries, and CLI tools.",[95,179,180,183,184,187,188,60],{},[27,181,182],{},"Shared virtual environment:"," Rather than creating 15 separate virtual environments that each re-download PyTorch, FastAPI, or Pandas, ",[80,185,186],{},"uv"," shares packages from its global cache and links internal packages instantly using ",[80,189,190],{},"{ workspace = true }",[95,192,193,196,197,201,202,60],{},[27,194,195],{},"Blazing performance:"," Written in Rust, ",[27,198,199],{},[41,200,186],{"href":155}," resolves dependencies 10–100× faster than legacy ",[27,203,204],{},[41,205,142],{"href":141},[47,207],{},[50,209,211],{"id":210},"_2-workspaces-vs-full-monorepo-tooling-when-to-transition","2. Workspaces vs. Full Monorepo Tooling: When to Transition?",[15,213,214],{},"A common architectural mistake is adopting heavy build orchestration tools too early—or waiting until CI pipelines grind to a halt before realizing native workspaces are not enough.",[65,216,218],{"id":217},"what-native-workspaces-do-well","What Native Workspaces Do Well:",[92,220,221,224,227],{},[95,222,223],{},"Local package linking and resolution.",[95,225,226],{},"Dependency deduplication and unified lockfiles.",[95,228,229,230,233,234,237],{},"Basic filtered command running (",[80,231,232],{},"pnpm --filter ...",", ",[80,235,236],{},"uv run --package ...",").",[65,239,241],{"id":240},"where-native-workspaces-hit-the-wall","Where Native Workspaces Hit the Wall:",[15,243,244,245,248,249,252,253,256],{},"Native package managers have ",[27,246,247],{},"no concept of build graphs or computation caching",". When you run ",[80,250,251],{},"pnpm -r test"," or ",[80,254,255],{},"uv run pytest",", the package manager naively runs tests in every package—even if only a single markdown file changed.",[258,259],"monorepo-transition-card",{},[15,261,262,263,233,267,233,271,275],{},"Dedicated monorepo engines (",[41,264,266],{"href":265},"\u002Fblog\u002Fmoon","Moon",[41,268,270],{"href":269},"\u002Fblog\u002Fturborepo","Turborepo",[41,272,274],{"href":273},"\u002Fblog\u002Fnx","Nx",") introduce three transformative capabilities:",[277,278,279,289,295],"ol",{},[95,280,281,284,285,288],{},[27,282,283],{},"Affected \u002F Impact Analysis:"," Using Git diffs and dependency graphs to execute tasks ",[22,286,287],{},"only"," on packages affected by a commit.",[95,290,291,294],{},[27,292,293],{},"Computation Caching (Local & Remote):"," Hashing file inputs, environment variables, and dependencies. If the hash hasn't changed, the tool restores build and test outputs from cache in milliseconds.",[95,296,297,300],{},[27,298,299],{},"Task Pipeline Parallelism:"," Executing tasks topologically according to a defined graph (e.g. build shared UI before building web app, while running lint in parallel).",[47,302],{},[50,304,306],{"id":305},"_3-homogeneous-stacks-pure-typescript-vs-pure-python","3. Homogeneous Stacks: Pure TypeScript vs. Pure Python",[15,308,309],{},"When your entire monorepo lives within a single language ecosystem, your tooling choice simplifies considerably.",[65,311,313],{"id":312},"scenario-a-pure-typescript-javascript","Scenario A: Pure TypeScript \u002F JavaScript",[92,315,316,324],{},[95,317,318,321,322],{},[27,319,320],{},"Base:"," ",[80,323,77],{},[95,325,326,321,329,333,334],{},[27,327,328],{},"Orchestrator Choices:",[27,330,331],{},[41,332,270],{"href":269}," vs. ",[27,335,336],{},[41,337,274],{"href":273},[15,339,340],{},"For pure TypeScript\u002FJavaScript monorepos (e.g., Next.js\u002FNuxt web apps, Node\u002FFastify microservices, shared UI components, shared TS schemas):",[92,342,343,352],{},[95,344,345,347,348,351],{},[27,346,270],{}," is the recommended default. It is lightweight, configuration-minimal (",[80,349,350],{},"turbo.json","), written in Rust, and focuses squarely on fast caching and task orchestration. It integrates seamlessly with Vercel and self-hosted remote caches without altering how your packages build.",[95,353,354,356],{},[27,355,274],{}," is a heavier, enterprise-grade alternative. It provides deep AST analysis, project visualizers, and code generators. However, it introduces significant abstraction that can feel intrusive for teams wanting standard build scripts.",[65,358,360],{"id":359},"scenario-b-pure-python","Scenario B: Pure Python",[92,362,363,369],{},[95,364,365,321,367],{},[27,366,320],{},[80,368,156],{},[95,370,371,321,374],{},[27,372,373],{},"Tooling:",[27,375,376,378,379],{},[80,377,186],{}," + ",[80,380,381],{},"ruff",[15,383,384],{},"For a pure Python monorepo (e.g., several FastAPI microservices, shared data models, and Celery workers):",[92,386,387,398,405],{},[95,388,389,391,392,394,395,60],{},[80,390,156],{}," paired with ",[80,393,381],{}," for linting and formatting is so ridiculously fast that ",[27,396,397],{},"many Python teams do not even need a secondary monorepo build orchestrator",[95,399,400,401,404],{},"Tests can be scoped via ",[80,402,403],{},"uv run pytest --package service-a",", and dependency installation takes under 2 seconds.",[95,406,407],{},"You only need a monorepo task runner in pure Python if you have heavy, multi-stage artifact builds (e.g. compiling Cython\u002FC-extensions, generating PyInstaller binaries, or baking complex multi-stage Docker images in CI) where distributed remote caching pays dividends.",[47,409],{},[50,411,413],{"id":412},"_4-the-polyglot-challenge-multi-language-monorepos","4. The Polyglot Challenge: Multi-Language Monorepos",[15,415,416,417,60],{},"The real trial begins when a monorepo combines different language runtimes: ",[27,418,419],{},"Python backend services + TypeScript web applications + Rust\u002FGo microservices or WASM modules",[65,421,423],{"id":422},"why-js-first-tools-struggle-with-polyglot","Why JS-First Tools Struggle with Polyglot",[15,425,426],{},"Both Turborepo and Nx originated in the JavaScript\u002FNode.js ecosystem:",[92,428,429,438],{},[95,430,431,433,434,437],{},[27,432,270],{}," expects ",[80,435,436],{},"package.json"," files everywhere. It does not understand Python virtual environments, Cargo workspaces, or Go modules natively. Attempting to shoehorn Python tasks into Turborepo requires wrapping everything in custom npm scripts.",[95,439,440,442],{},[27,441,274],{}," supports Python through community plugins, but it can feel bolted on. Crucially, Nx assumes the developer’s local machine and CI runner already have the correct Python, Poetry, or Go versions installed and activated.",[65,444,446,447,450],{"id":445},"moon-moonrepo-the-true-polyglot-architecture","Moon (",[80,448,449],{},"moonrepo","): The True Polyglot Architecture",[15,452,453,454,458],{},"This is where ",[27,455,456],{},[41,457,266],{"href":265}," stands apart as the front-runner in our evaluation.",[15,460,461],{},"Moon was designed from day one as a language-agnostic, polyglot monorepo build system written in Rust:",[277,463,464,492,643,652],{},[95,465,466,473,474,476,477,480,481,233,484,487,488,491],{},[27,467,468,469,472],{},"Hermetic Toolchain Management (",[80,470,471],{},"proto","):","\nInstead of assuming Node 20, Python 3.12, and Rust 1.80 are pre-installed on every developer's machine and CI container, Moon manages language runtimes natively via its toolchain system (",[80,475,471],{},"). It automatically downloads, pins, and executes the exact runtime specified in ",[80,478,479],{},".moon\u002Ftoolchain.yml",". No ",[80,482,483],{},"nvm",[80,485,486],{},"pyenv",", or ",[80,489,490],{},"rustup"," configuration drift.",[95,493,494,497,498,501,502,504,505,507,508,511,512,515,516],{},[27,495,496],{},"First-Class Tier Support:","\nMoon treats JavaScript\u002FTypeScript (",[80,499,500],{},"pnpm","), Python (",[80,503,186],{}," \u002F ",[80,506,142],{},"), Rust (",[80,509,510],{},"cargo","), and Go as first-class citizens. Tasks are declared declaratively in ",[80,513,514],{},"moon.yml"," files per project:\n",[517,518,523],"pre",{"className":519,"code":520,"language":521,"meta":522,"style":522},"language-yaml shiki shiki-themes github-light github-dark","# apps\u002Fanalytics-api\u002Fmoon.yml (Python service)\ntype: application\nlanguage: python\n\ntasks:\n  test:\n    command: uv run pytest\n    inputs:\n      - \"src\u002F**\u002F*\"\n      - \"tests\u002F**\u002F*\"\n\n  lint:\n    command: uv run ruff check .\n","yaml","",[80,524,525,534,549,560,567,576,584,595,603,612,620,625,633],{"__ignoreMap":522},[526,527,530],"span",{"class":528,"line":529},"line",1,[526,531,533],{"class":532},"sJ8bj","# apps\u002Fanalytics-api\u002Fmoon.yml (Python service)\n",[526,535,537,541,545],{"class":528,"line":536},2,[526,538,540],{"class":539},"s9eBZ","type",[526,542,544],{"class":543},"sVt8B",": ",[526,546,548],{"class":547},"sZZnC","application\n",[526,550,552,555,557],{"class":528,"line":551},3,[526,553,554],{"class":539},"language",[526,556,544],{"class":543},[526,558,559],{"class":547},"python\n",[526,561,563],{"class":528,"line":562},4,[526,564,566],{"emptyLinePlaceholder":565},true,"\n",[526,568,570,573],{"class":528,"line":569},5,[526,571,572],{"class":539},"tasks",[526,574,575],{"class":543},":\n",[526,577,579,582],{"class":528,"line":578},6,[526,580,581],{"class":539},"  test",[526,583,575],{"class":543},[526,585,587,590,592],{"class":528,"line":586},7,[526,588,589],{"class":539},"    command",[526,591,544],{"class":543},[526,593,594],{"class":547},"uv run pytest\n",[526,596,598,601],{"class":528,"line":597},8,[526,599,600],{"class":539},"    inputs",[526,602,575],{"class":543},[526,604,606,609],{"class":528,"line":605},9,[526,607,608],{"class":543},"      - ",[526,610,611],{"class":547},"\"src\u002F**\u002F*\"\n",[526,613,615,617],{"class":528,"line":614},10,[526,616,608],{"class":543},[526,618,619],{"class":547},"\"tests\u002F**\u002F*\"\n",[526,621,623],{"class":528,"line":622},11,[526,624,566],{"emptyLinePlaceholder":565},[526,626,628,631],{"class":528,"line":627},12,[526,629,630],{"class":539},"  lint",[526,632,575],{"class":543},[526,634,636,638,640],{"class":528,"line":635},13,[526,637,589],{"class":539},[526,639,544],{"class":543},[526,641,642],{"class":547},"uv run ruff check .\n",[95,644,645,648,649],{},[27,646,647],{},"Cross-Language Dependency Graph:","\nMoon allows cross-language task dependencies. For example, a TypeScript frontend build task can declare a dependency on a Python OpenAPI schema generation task or a Rust WASM compilation task:\n",[650,651],"monorepo-dag-chart",{},[95,653,654,657,658,252,661,664],{},[27,655,656],{},"Universal Unified CI:","\nRunning ",[80,659,660],{},"moon run :lint",[80,662,663],{},"moon run :test"," runs the appropriate linter and test suite across TypeScript, Python, and Rust in topological order, parallelizing where possible and caching every output.",[47,666],{},[50,668,670],{"id":669},"_5-architectural-decision-matrix","5. Architectural Decision Matrix",[672,673,674,701],"table",{},[675,676,677],"thead",{},[678,679,680,685,692,694,696],"tr",{},[681,682,684],"th",{"align":683},"left","Dimension",[681,686,687,504,689,691],{"align":683},[80,688,500],{},[80,690,186],{}," Workspaces",[681,693,270],{"align":683},[681,695,274],{"align":683},[681,697,446,698,700],{"align":683},[80,699,449],{},")",[702,703,704,724,745,766,785,802,835],"tbody",{},[678,705,706,712,715,718,721],{},[707,708,709],"td",{"align":683},[27,710,711],{},"Primary Scope",[707,713,714],{"align":683},"Package linking & lockfiles",[707,716,717],{"align":683},"JS\u002FTS Task Orchestrator",[707,719,720],{"align":683},"Enterprise JS\u002FTS Ecosystem",[707,722,723],{"align":683},"Polyglot Repository Orchestrator",[678,725,726,731,734,737,740],{},[707,727,728],{"align":683},[27,729,730],{},"Language Support",[707,732,733],{"align":683},"Single language (JS or Python)",[707,735,736],{"align":683},"JS \u002F TS native (others via npm hacks)",[707,738,739],{"align":683},"JS \u002F TS native (Python via plugins)",[707,741,742],{"align":683},[27,743,744],{},"Node, Python, Rust, Go, Bun (Native)",[678,746,747,752,755,757,759],{},[707,748,749],{"align":683},[27,750,751],{},"Toolchain Management",[707,753,754],{"align":683},"None (host managed)",[707,756,754],{"align":683},[707,758,754],{"align":683},[707,760,761],{"align":683},[27,762,763,764,700],{},"Built-in hermetic toolchains (",[80,765,471],{},[678,767,768,773,776,779,782],{},[707,769,770],{"align":683},[27,771,772],{},"Computation Caching",[707,774,775],{"align":683},"❌ No",[707,777,778],{"align":683},"✅ Local & Remote (Vercel\u002FS3)",[707,780,781],{"align":683},"✅ Local & Remote (Nx Cloud)",[707,783,784],{"align":683},"✅ Local & Remote (AWS\u002FGCP\u002Fmoonbase)",[678,786,787,792,794,797,800],{},[707,788,789],{"align":683},[27,790,791],{},"Affected Detection",[707,793,775],{"align":683},[707,795,796],{"align":683},"✅ Git-based",[707,798,799],{"align":683},"✅ Git + AST graph",[707,801,796],{"align":683},[678,803,804,809,817,822,829],{},[707,805,806],{"align":683},[27,807,808],{},"Config Overhead",[707,810,811,812,814,815,700],{"align":683},"Minimal (",[80,813,436],{},"\u002F",[80,816,168],{},[707,818,819,820,700],{"align":683},"Low (",[80,821,350],{},[707,823,824,825,828],{"align":683},"Medium-High (",[80,826,827],{},"nx.json"," + generators)",[707,830,831,832,700],{"align":683},"Medium (",[80,833,834],{},".moon\u002F*.yml",[678,836,837,842,845,848,851],{},[707,838,839],{"align":683},[27,840,841],{},"Best Fit For",[707,843,844],{"align":683},"Small or pure single-stack repos",[707,846,847],{"align":683},"High-velocity pure TS\u002FJS repos",[707,849,850],{"align":683},"Large enterprise Angular\u002FReact setups",[707,852,853],{"align":683},[27,854,855],{},"Polyglot Python + TS + Rust architectures",[47,857],{},[50,859,861],{"id":860},"_6-summary-radar-verdict","6. Summary & Radar Verdict",[92,863,864,873,889],{},[95,865,866,321,869,872],{},[27,867,868],{},"Architecture Decision:",[27,870,871],{},"Adopt Monorepo."," The developer experience of unified PRs, atomic cross-service refactors, and synchronized contracts far outweighs the multi-repo coordination overhead.",[95,874,875,878,879,883,884,888],{},[27,876,877],{},"Phase 1 Foundation:"," Always start with native workspaces—",[27,880,881],{},[80,882,77],{}," for TypeScript, ",[27,885,886],{},[80,887,156],{}," for Python. Keep things simple until build times demand orchestration.",[95,890,891,894],{},[27,892,893],{},"Phase 2 Scaling:",[92,895,896,908],{},[95,897,898,899,902,903,907],{},"If the repo remains ",[27,900,901],{},"purely TypeScript",", adopt ",[27,904,905],{},[41,906,270],{"href":269}," for zero-friction caching.",[95,909,910,911,233,914,918],{},"If the repo is a ",[27,912,913],{},"polyglot hybrid (Python + TypeScript + Rust)",[27,915,916],{},[41,917,266],{"href":265}," is the clear front-runner, providing hermetic multi-runtime toolchains and true cross-language task pipelines.",[47,920],{},[50,922,924],{"id":923},"_7-connected-deep-dives-tech-reports","7. Connected Deep Dives & Tech Reports",[15,926,927],{},"Explore the individual technology evaluations that form our monorepo web:",[92,929,930,938,946,954,962,970,978,986,994],{},[95,931,932,937],{},[27,933,934,90],{},[41,935,936],{"href":43},"Polyrepo (Rejected)"," Why multi-repo architectures failed our velocity tests and were rejected.",[95,939,940,945],{},[27,941,942,90],{},[41,943,944],{"href":76},"pnpm (Adopted Standard)"," Content-addressable package management and workspace linking for Node\u002FTS.",[95,947,948,953],{},[27,949,950,90],{},[41,951,952],{"href":88},"npm (Rejected)"," Detailed analysis of phantom dependencies and flat node_modules liabilities.",[95,955,956,961],{},[27,957,958,90],{},[41,959,960],{"href":155},"uv (Adopted Standard)"," The high-speed Rust toolchain powering our Python workspaces.",[95,963,964,969],{},[27,965,966,90],{},[41,967,968],{"href":141},"pip (Rejected)"," Why pip and requirements.txt were retired in favor of uv.",[95,971,972,977],{},[27,973,974,90],{},[41,975,976],{"href":269},"Turborepo (Adopted for TS)"," Task orchestration and remote caching for pure TypeScript monorepos.",[95,979,980,985],{},[27,981,982,90],{},[41,983,984],{"href":265},"Moon (Adopted for Polyglot)"," Polyglot monorepo build system unifying Python, TypeScript, and Rust.",[95,987,988,993],{},[27,989,990,90],{},[41,991,992],{"href":273},"Nx (Hold \u002F Assess)"," Enterprise-scale monorepo tool with deep AST code analysis and generators.",[95,995,996,1002],{},[27,997,998,90],{},[41,999,1001],{"href":1000},"\u002Fblog\u002Fbun","Bun (Trial)"," Fast JavaScript runtime, bundler, and package manager evaluated for edge services.",[1004,1005,1006],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":522,"searchDepth":536,"depth":536,"links":1008},[1009,1013,1017,1021,1026,1027,1028],{"id":52,"depth":536,"text":53,"children":1010},[1011,1012],{"id":67,"depth":551,"text":68},{"id":132,"depth":551,"text":133},{"id":210,"depth":536,"text":211,"children":1014},[1015,1016],{"id":217,"depth":551,"text":218},{"id":240,"depth":551,"text":241},{"id":305,"depth":536,"text":306,"children":1018},[1019,1020],{"id":312,"depth":551,"text":313},{"id":359,"depth":551,"text":360},{"id":412,"depth":536,"text":413,"children":1022},[1023,1024],{"id":422,"depth":551,"text":423},{"id":445,"depth":551,"text":1025},"Moon (moonrepo): The True Polyglot Architecture",{"id":669,"depth":536,"text":670},{"id":860,"depth":536,"text":861},{"id":923,"depth":536,"text":924},null,"2026-08-08","adopt","Preferred mainly because independent deployment is still fully achievable through proper CI\u002FCD, while a feature spanning multiple modules (say, two microservices and a UI) stays a single PR: easy to review, and deployed together without coordinating release order across repositories. Deployment is a CI\u002FCD problem, not a code organization problem.","Single-repository architecture, adopted in favor of splitting services across multiple repos.","md",{},"\u002Fradar\u002Fmonorepo",[1038],{"category":1039,"subCategory":1040},"techniques","architecture",{"title":5,"description":1033},"trial","radar\u002Fmonorepo",[1045,1040,1046,1047,1048,1049,1050],"monorepo","cicd","devops","tooling","python","typescript","tech_report","YlO4m1SL1bxbKo3xcspMeLb6HYbRRW0jSKXiKvQmDec",1790263542563]