Monorepo (Monolithic Repository) adalah pendekatan manajemen proyek di mana beberapa package atau modul dikembangkan dan disimpan dalam satu repository Git. Ini sangat berguna untuk tim besar, proyek modular, atau sistem dengan banyak bagian saling terkait.


Apa Itu Monorepo?

Secara sederhana, monorepo adalah struktur di mana beberapa package disatukan dalam satu repositori, bukannya dibuat dan dipisah ke banyak repository kecil.

Misalnya:

my-project/
├── packages/
│   ├── utils/
│   ├── components/
│   └── api/
├── apps/
│   └── frontend/
├── package.json
└── pnpm-workspace.yaml

Kenapa Pakai Monorepo?

Keuntungan Penjelasan
🔁 Reuse Code Semua modul bisa saling impor tanpa perlu publish ke npm.
🚀 Build Cepat Tool seperti pnpm, turbo, atau nx bisa melakukan build hanya pada package yang berubah.
🛠️ Dependency Terpusat Semua dependency dikelola dalam satu tempat.
🤝 Kolaborasi Lebih Mudah Tim bisa bekerja di berbagai bagian sistem tanpa berpindah repo.
✅ Konsistensi Tooling Linter, formatter, dan test bisa disatukan di root.

Setup Dasar Monorepo dengan pnpm

1. Struktur Folder

my-monorepo/
├── packages/
│   ├── @internal/utils/
│   └── @internal/ui/
├── apps/
│   └── dashboard/
├── package.json
└── pnpm-workspace.yaml

2. package.json di root

{
  "private": true,
  "workspaces": ["packages/*", "apps/*"],
  "devDependencies": {
    "typescript": "^5.0.0",
    "vite": "^5.0.0"
  }
}

3. pnpm-workspace.yaml

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

Contoh Package Lokal: @internal/utils

packages/@internal/utils/package.json:

{
  "name": "@internal/utils",
  "version": "1.0.0",
  "main": "dist/index.js",
  "exports": {
    ".": {
      "import": "./dist/index.mjs",
      "require": "./dist/index.js"
    }
  }
}

Jangan lupa untuk membuild package-nya (pnpm build) agar file dist/ tersedia saat diimpor oleh project lain.


Mengimpor Package Internal

Contoh import dari aplikasi frontend:

// apps/dashboard/src/main.ts
import { formatDate } from "@internal/utils";

Vite atau bundler lain akan resolve path ini karena pnpm sudah membuat symlink antar package.


Konfigurasi Tambahan (Opsional)

TypeScript Path Alias (tsconfig.json)

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@internal/utils": ["packages/@internal/utils/src"]
    }
  }
}

Alias di Vite (vite.config.ts)

import { defineConfig } from "vite";
import path from "path";

export default defineConfig({
  resolve: {
    alias: {
      "@internal/utils": path.resolve(__dirname, "../packages/@internal/utils/src")
    }
  }
});

Tool yang Sering Dipakai di Monorepo

Tool Fungsi
pnpm / yarn / npm workspaces Manajemen dependency lintas package
turbo Build dan cache task dengan cepat
nx Framework monorepo yang powerful dan scalable
lerna Tool klasik untuk monorepo, kini banyak digantikan oleh Turbo/Nx

Tips Tambahan

  • Gunakan pnpm dev atau pnpm --filter untuk menjalankan per-package script.
  • Pisahkan devDependencies di root untuk menjaga konsistensi.
  • Tambahkan prettier, eslint, dan tooling lain di root agar rapi.

Penutup

Monorepo memberikan efisiensi tinggi untuk tim pengembang modern, terutama dalam proyek besar atau sistem modular. Dengan tools seperti pnpm dan vite, kamu bisa membuat workflow development yang cepat, ringan, dan scalable.

Jika kamu belum pernah coba, mungkin ini saatnya mengubah cara kamu mengelola proyek ✨