Alim Studio

Blog

Arsitektur Monorepo yang Tetap Ringan untuk Tim Kecil

Panduan membangun monorepo yang ringan, cepat, dan mudah dipelihara untuk tim kecil, lengkap dengan strategi tooling, struktur folder, dan praktik terbaik.

Jumadil Abdul Rahman Selian

Tanggal terbit
Waktu baca
5 menit baca
Total dilihat
2 dilihat
Kategori
Engineering

Pendahuluan

Monorepo sering dianggap solusi berat yang hanya cocok untuk perusahaan besar. Faktanya, dengan pemilihan tooling yang tepat, monorepo bisa menjadi pilihan paling ringan untuk tim kecil yang ingin berbagi kode, menjaga konsistensi, dan mempercepat onboarding. Artikel ini membahas arsitektur monorepo yang tetap ramping, tanpa membebani pipeline dan workstation developer.

Tujuan artikel: memberi panduan end-to-end mulai dari pemilihan tool, struktur direktori, konfigurasi workspace, hingga praktik operasional untuk tim kecil beranggotakan 2–10 orang.

Ilustrasi monorepo untuk tim kecil


Pengertian Monorepo

Monorepo adalah strategi penyimpanan kode di mana banyak project atau package disimpan dalam satu repositori git tunggal. Berbeda dengan polyrepo yang memisahkan tiap service ke repo berbeda, monorepo menyimpan semuanya di satu tempat dengan sistem workspace.

Dalam konteks tim kecil, monorepo memberikan tiga keuntungan utama:

  • Visibilitas kode penuh: anggota tim bisa membaca dan mengubah kode package lain tanpa proses clone tambahan.
  • Refactor lintas package lebih aman: satu PR bisa menyentuh banyak package sekaligus, CI memvalidasi ketergantungan.
  • Onboarding cepat: developer baru cukup clone satu repo, menjalankan satu perintah install, lalu langsung produktif.

Monorepo vs Polyrepo untuk Tim Kecil

Polyrepo cocok ketika tiap service benar-benar independen dan dimiliki tim berbeda. Untuk tim kecil yang sering berbagi utilitas, tipe, atau komponen UI, polyrepo menimbulkan overhead berupa duplikasi kode, drift versi, dan proses sinkronisasi manual.

AspekMonorepoPolyrepoOnboarding1 clone, 1 installClone banyak repoRefactor1 PR, atomicMulti-repo, multi-PRCIButuh filter pathPer-repo independenUkuran repoLebih besarLebih kecil per repoCocok untukTim kecil–menengahTim besar terdistribusi

Untuk tim kecil, monorepo biasanya menang pada aspek kolaborasi harian, meski ukuran repo lebih besar.

Perbandingan monorepo dan polyrepo


Tooling Monorepo yang Ringan

Pemilihan tool menentukan apakah monorepo terasa ringan atau berat. Untuk tim kecil, prioritaskan tool yang minim konfigurasi, cepat diinstall, dan tidak menambah dependency besar ke setiap package.


1. npm workspaces

npm versi 7+ sudah mendukung workspaces secara native. Tidak perlu install tool tambahan. Cukup tambahkan blok workspaces di package.json root.


{
  "name": "monorepo-root",
  "private": true,
  "workspaces": [
    "packages/*",
    "apps/*"
  ]
}

Kelebihan: zero extra dependency, sudah tersedia di Node.js. Kekurangan: fitur terbatas dibanding tool khusus (misal Turborepo atau Nx).


2. pnpm workspaces

pnpm menggunakan content-addressable store sehingga package yang sama di banyak workspace tidak diduplikasi di disk. Hemat ruang dan install lebih cepat.


npm install -g pnpm
pnpm init
pnpm add -w typescript

3. monorepo (CLI oleh mariuslundgard)

Paket npm bernama monorepo adalah CLI utility untuk proyek Node.js monorepo. Versi terbaru di registry adalah 1.2.2. Homepage resmi: github.com/mariuslundgard/monorepo.

Catatan: README resmi tidak tersedia di registry, sehingga detail perintah CLI, flag, dan opsi konfigurasi harus diverifikasi langsung ke repository GitHub di atas. Jangan mengarang opsi yang tidak tercantum di sumber.


4. Turborepo (opsional, saat perlu caching)

Turborepo menambahkan cache build dan task pipeline. Untuk tim kecil yang sering menjalankan CI, Turborepo memangkas waktu build drastis. Namun untuk project dengan 3–5 package, npm workspaces saja sudah cukup.

Tooling monorepo yang ringan


Struktur Folder yang Disarankan

Struktur folder memengaruhi seberapa mudah tim menavigasi repo. Untuk tim kecil, gunakan dua top-level folder: apps/ dan packages/.


monorepo/
├── apps/
│   ├── web/            # Next.js / Vite app
│   └── api/            # Express / Fastify service
├── packages/
│   ├── ui/             # komponen UI bersama
│   ├── config/         # eslint, tsconfig, tailwind preset
│   └── utils/          # helper functions
├── package.json
├── pnpm-workspace.yaml
└── tsconfig.base.json

Prinsip:

  • apps/ berisi deployable unit (web, api, worker).
  • packages/ berisi library yang di-import apps atau package lain.
  • Konfigurasi bersama (eslint, tsconfig, prettier) diletakkan di packages/config agar tidak duplikat.

Konfigurasi Workspace Praktis

Bagian ini menunjukkan konfigurasi minimal untuk monorepo berbasis pnpm, karena paling ringan untuk tim kecil.


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

Perintah pnpm -r menjalankan script di semua package. Flag --parallel mempercepat task seperti dev yang berjalan bersamaan.


Strategi Dependency dan Versi

Kesalahan umum di monorepo tim kecil adalah mencampurkan versi dependency antar package. Atur strategi sejak awal:

  • Hoist dependency umum (react, typescript, eslint) ke root package.json.
  • Dependency spesifik (database driver, framework UI) tetap di package yang membutuhkannya.
  • Gunakan peerDependencies untuk package UI agar versi React ditentukan oleh app, bukan di-pin.
  • Hindari duplicate React: jika muncul dua versi React di node_modules, tambahkan resolutions di root.
{
  "resolutions": {
    "react": "^18.3.0",
    "react-dom": "^18.3.0"
  }
}

CI/CD yang Tetap Cepat

Monorepo sering gagal di CI karena CI menjalankan semua test untuk semua package setiap push. Solusinya: filter berdasarkan path yang berubah.


GitHub Actions dengan filter path

name: CI
on:
  push:
    branches: [main]
  pull_request:

jobs:
  changed:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v3
        with:
          version: 9
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: pnpm
      - run: pnpm install --frozen-lockfile
      - run: pnpm -r --filter "./[origin/main...HEAD]" run test
      - run: pnpm -r --filter "./[origin/main...HEAD]" run build

Flag --filter memastikan hanya package yang berubah (atau dependensi dari package yang berubah) yang diuji. Ini memangkas waktu CI secara signifikan.

Pipeline CI monorepo dengan filter path


Best Practice untuk Tim Kecil

  • Mulai dari 2–3 package. Jangan over-engineer. Tambah package baru hanya saat ada kode yang benar-benar dipakai di ≥2 tempat.
  • Conventional commits + changesets. Gunakan Changesets untuk versioning dan changelog otomatis saat package di-publish.
  • Linting bersama. Taruh konfigurasi ESLint dan Prettier di packages/config, extend dari tiap package.
  • TypeScript project references. Aktifkan di tsconfig.base.json agar IDE bisa navigasi antar package dengan cepat.
  • Lockfile tunggal. Jangan biarkan tiap package punya lockfile sendiri. Gunakan satu pnpm-lock.yaml atau package-lock.json di root.
  • Dokumentasi singkat di root. File README.md berisi: cara install, cara jalankan dev, cara tambah package baru, cara publish.

Troubleshooting Umum

Masalah: dependency tidak ter-link

Penyebab: package di packages/ di-import dengan path relatif atau nama yang salah.

Debug: cek name di package.json package target, lalu import sesuai nama tersebut.


{
  "name": "@repo/utils",
  "version": "0.1.0",
  "main": "./src/index.ts"
}

Masalah: versi dependency duplikat

Penyebab: tiap package mendeklarasikan versi sendiri untuk dependency yang sama.

Debug: jalankan pnpm why react untuk melihat pohon dependency.

Fix: hoist ke root atau gunakan resolutions.


Masalah: CI lambat

Penyebab: CI menjalankan semua package tanpa filter.

Fix: gunakan --filter berdasarkan diff, atau adopsi Turborepo dengan remote cache.


Masalah: TypeScript tidak mengenali path antar package

Penyebab: tsconfig tidak menggunakan project references.

Fix: buat tsconfig.base.json dengan composite: true dan references di tiap tsconfig.json package.

Troubleshooting monorepo


Perbandingan Tool Ringan

ToolExtra dependencyInstall speedCocok untuknpm workspacesTidak adaCukup cepatTim kecil, project sederhanapnpm workspacespnpmCepat, hemat diskTim kecil–menengahmonorepo (mariuslundgard)npm packageTergantung CLIProyek Node.js monorepoTurborepoturborepoCepat dengan cacheTim yang butuh CI cepatNxnxBerat di awalTim besar, monorepo kompleks


Kapan Tidak Perlu Monorepo

Monorepo bukan solusi universal. Hindari monorepo jika:

  • Tiap service dimiliki tim berbeda dengan release cycle independen.
  • Repo sudah mendekati batas ukuran yang membuat clone lambat (misal >5 GB).
  • Tidak ada kode yang benar-benar dipakai bersama antar project.

Untuk kasus di atas, polyrepo tetap lebih sehat.


Kesimpulan

Monorepo untuk tim kecil bukan soal menambah tool sebanyak mungkin, melainkan memilih struktur dan tooling secukupnya. Mulailah dengan npm atau pnpm workspaces, struktur apps/ + packages/, konfigurasi bersama di satu tempat, dan CI yang memfilter perubahan. Tambahkan Turborepo atau Changesets hanya saat benar-benar dibutuhkan.

Dengan disiplin tersebut, monorepo tetap ringan: install cepat, CI singkat, onboarding mulus, dan refactor aman. Tim kecil bisa fokus pada produk, bukan pada overhead tooling.

Ringkasan arsitektur monorepo ringan

  • monorepo
  • dx
  • typescript