← Back to list

Stop Managing 5 Repos. Use a Monorepo Instead.

If you’ve ever maintained a web app, a mobile app, and a backend API as separate repositories, you already know the pain. You change a…

Muhibullah · 2026-04-09 04:22 · 4 claps · 5.0 min read
#monorepo #nx #nx-monorepo #git #software-architecture
Open on Medium ↗
Wiki topics: 🌐 · Web Development 📱 · Mobile Development 🔓 · Open Source 🏛️ · Architecture

Photo by Waqas Sultan on Unsplash

Photo by Waqas Sultan on Unsplash

Stop Managing 5 Repos. Use a Monorepo Instead.

If you’ve ever maintained a web app, a mobile app, and a backend API as separate repositories, you already know the pain. You change a shared utility, then spend the next hour updating three repos, bumping versions, publishing packages, and praying nothing breaks. A monorepo eliminates that entire category of problems.

This guide covers what a monorepo is, why it works, and how to set one up with Nx — one of the most capable monorepo tools available today.

What Is a Monorepo?

A monorepo (short for monolithic repository) is a single Git repository that houses multiple projects — apps, services, libraries — all living together.

Instead of this:

frontend-app/     ← separate repo
backend-api/      ← separate repo
mobile-app/       ← separate repo
shared-utils/     ← separate repo

You get this:

my-monorepo/
  apps/
    web/
    mobile/
    api/
  libs/
    ui/
    utils/
    date-utils/

One repo. One install. One source of truth.

The Real Problem It Solves

Let’s say you’re building a SaaS product with:

  • A React web dashboard
  • A React Native mobile app
  • A Node.js backend API
  • Shared UI components (buttons, modals, forms)
  • Shared utilities (date formatting, validation, API clients)

With separate repos, you hit these walls constantly:

Problem Impact Shared code must be published as packages Slow iteration, versioning overhead Version mismatches between packages Subtle bugs that are hard to trace Changes require PRs across multiple repos Coordination overhead Onboarding new developers Multiple setups, multiple contexts

A monorepo collapses all of this. Shared code is just a local import. Changes propagate instantly. Onboarding is one git clone and one install.

Why Nx?

Nx is a build system built for monorepos. It adds:

  • Dependency graph awareness — Nx knows which projects depend on which libraries
  • Incremental builds — only rebuilds what actually changed
  • Computation caching — if nothing changed, results are served from cache instantly
  • Code generators — scaffolds apps and libraries with best-practice structure
  • Task orchestration — runs tasks in the correct dependency order

This matters a lot at scale. A naive monorepo without tooling becomes slow. Nx keeps builds fast even as the codebase grows.

Setting Up a Monorepo with Nx

Step 1: Create the Workspace

npx create-nx-workspace@latest my-monorepo

When prompted, choose Integrated Monorepo. This gives you Nx’s full project graph and caching.

Your initial structure:

my-monorepo/
  apps/           ← deployable applications
  libs/           ← shared libraries
  nx.json         ← Nx configuration
  package.json

Step 2: Generate Applications

Create a Next.js web app:

npx nx g @nx/next:app web

Create a Node API:

npx nx g @nx/node:app api

These aren’t just empty folders — Nx scaffolds them with proper configs, test setups, and build targets already wired up.

Step 3: Create Shared Libraries

Shared UI components:

npx nx g @nx/react:lib ui

Shared utility functions:

npx nx g @nx/js:lib utils

Date formatting helpers:

npx nx g @nx/js:lib date-utils

Step 4: Use Shared Code Across Apps

Nx automatically sets up TypeScript path aliases so you can import libraries like installed packages — no publishing required.

// apps/web/src/pages/dashboard.tsx
import { Button } from '@my-monorepo/ui';
import { formatDate } from '@my-monorepo/date-utils';
import { validateEmail } from '@my-monorepo/utils';
// apps/api/src/routes/users.ts
import { validateEmail } from '@my-monorepo/utils';

Change something in libs/utils and both web and api see the update immediately — no publish, no version bump.

Development Workflow

Install all dependencies:

npm install

Run the web app:

npx nx serve web

Run the API:

npx nx serve api

Run both simultaneously:

npx nx run-many -t serve -p web api

Run all tests across the repo:

npx nx run-many -t test

How Nx Understands Your Dependency Graph

This is where Nx really earns its place. Run:

npx nx graph

You’ll see an interactive visualization of which apps depend on which libraries. Nx uses this graph to make intelligent decisions during builds and CI.

Example graph:

web  →  ui, utils, date-utils
api  →  utils

When you run npx nx build web, Nx automatically builds ui, utils, and date-utils first — in the correct order.

Builds and Caching

Build a single app:

npx nx build web
npx nx build api

Build everything:

npx nx run-many -t build

The cache is the killer feature. Run a build, then run it again without changing anything:

npx nx build web
# → [cached] Build completed in 0.3s

Nx hashes inputs (source files, env variables, dependencies) and short-circuits the build if nothing changed. This works locally and in CI.

Affected Commands: Only Test What Changed

This is essential for large teams. Instead of running all tests on every PR:

# Only test projects affected by your changes
npx nx affected -t test
# Only build projects affected by your changes
npx nx affected -t build

If you change libs/utils, Nx knows that web and api both depend on it and runs their tests. Libraries that don't use utils are skipped entirely.

Git Workflow

Nothing changes about how you use Git. It’s still one repo, standard branching.

git pull origin main
npm install          # always run after pulling
# Make your changes across apps/libs as needed
git add .
git commit -m "feat: add form validation to web and api"
git push origin main

The difference from a polyrepo: you can make a cross-cutting change — say, updating the Button component API and every place it's used — in a single commit with a single PR. That's an enormous quality-of-life improvement.

Installing Dependencies for Specific Projects

For a dependency only needed in one app:

npm install lodash --workspace=apps/web

For a shared dev dependency:

npm install -D typescript

This keeps dependency trees clean and intentional.

Structuring Libraries Well

As your monorepo grows, how you organize libs/ matters. A common pattern:

libs/
  ui/               ← shared React components
  utils/            ← pure utility functions
  date-utils/       ← date formatting and parsing
  api-client/       ← shared API request logic
  types/            ← shared TypeScript interfaces
  config/           ← shared configuration constants

The rule of thumb: if two or more apps need it, it belongs in libs/.

Team Collaboration

Here’s how a typical team flow looks in a monorepo:

  1. Developer A adds a new libs/api-client library
  2. Developer B pulls the branch, imports @my-monorepo/api-client immediately — no publish, no version coordination
  3. Developer A pushes and opens one PR covering both the library and its usage in web and api
  4. CI runs nx affected -t test,build — only the relevant projects are tested
  5. Merge. Done.

Compare this to the polyrepo version of the same workflow, which involves 2–3 separate PRs, package publishes, and version bumps.

When Not to Use a Monorepo

Monorepos aren’t always the right call:

  • Completely unrelated projects — a monorepo works best when projects share code or team context
  • Very small or solo codebases — the tooling overhead isn’t worth it if you have one app and no shared code
  • Strict access control requirements — monorepos make it harder to limit who can see what (though Nx has ownership tooling that helps)

Key Takeaways

A monorepo with Nx gives you:

  • Shared code without publishing — local imports, zero friction
  • Smart, fast builds — caching and affected commands mean you never rebuild what didn’t change
  • Atomic cross-project changes — one PR, one commit, full picture
  • Scalable structure — grows cleanly from 2 projects to 20

If you’re building a system with multiple apps and meaningful shared logic, a monorepo is almost certainly the right architecture. Start with npx create-nx-workspace and you'll wonder why you were managing separate repos in the first place.

Have questions or want to share how your team structures your monorepo? Drop a comment below.


메타데이터
post_id
15cbabc92db9
slug
stop-managing-5-repos-use-a-monorepo-instead-15cbabc92db9
url
https://medium.com/@muhebollah.diu/stop-managing-5-repos-use-a-monorepo-instead-15cbabc92db9
canonical_url
https://medium.com/@muhebollah.diu/stop-managing-5-repos-use-a-monorepo-instead-15cbabc92db9
author_url
https://medium.com/@muhebollah.diu
status
ok
fetched_at
2026-06-10 08:17:25