ADR-0009: Monorepo: Bun workspace (single go.mod)¶
Umbra 는 단일 레포에 Go 프로세스와 TypeScript 웹을 함께 두는 모노레포 구조이며, TypeScript 는 Bun workspace 로, Go 는 단일
go.mod로 관리한다.go.work는 도입하지 않는다.
Status¶
Accepted
- Decided at — 2026-04-13
- Decided by — Pablo
Context¶
Umbra 는 네 개의 프로세스로 구성된다.
- Go 프로세스 3개 — bot, api, worker
- TypeScript 웹 1개 —
apps/web/
Go 프로세스들은 engine/* 과 platform/* 패키지를 공유하며 단일 go.mod 를 사용한다. TypeScript 웹은 독립된 package.json 을 갖지만 루트 차원의 스크립트, lint, 타입 공유가 필요하다.
결정해야 할 것:
- 모노레포 vs 멀티 레포
- 모노레포 내 JS/TS 패키지 매니저
- 빌드 orchestrator 필요 여부
Decision¶
단일 레포 (모노레포) 로 운영하며 다음 구조를 사용한다.
- Go module — 루트의 단일
go.mod(github.com/luxtradev/Umbra).go.work는 도입하지 않는다 — 단일 module 만으로engine/*,platform/*,apps/*의 cross-package import 가 모두 해결된다 - JS workspace —
package.json의workspaces: ["apps/web"]로 Bun workspace 구성 - Script orchestration —
justfile이 단일 오케스트레이터 (recipes:dev-bot,dev-api,dev-worker,dev-web,db-migrate,sqlc,openapi,lint,test) - Build orchestrator — 사용 안 함. Turborepo / Nx 도입 안 함
선택 근거:
- 도메인 공유 —
engine/*을 세 Go 프로세스가 함께 쓰므로 모노레포가 필수 - 단일
go.mod의 단순성 — multi-module +go.work는 의존성 그래프가 복잡해지고 IDE/도구 호환성 이슈가 늘어난다. 단일 module 은 import path 가 직관적이고go test ./...한 번으로 전체 검사 가능 - Bun 속도 — npm 대비 install/빌드가 빠름. Luxtra 팀의 다른 프로젝트에도 확산 검토
- 단일성 우선 — 외부 도구(Turborepo, Nx) 없이 Bun scripts + justfile 로 충분. 오버엔지니어링 회피
- 경계 명확 — Go internal package convention 으로 프로세스 경계 강제 (ADR-0017, ADR-0018)
Consequences¶
Positive¶
- 한 PR 로 프론트엔드와 백엔드를 같이 변경 가능 → 기능 개발 속도 ↑
engine/*공유로 도메인 코드 중복 없음- Bun install 속도로 CI 시간 단축
- 구조 단순 (빌드 orchestrator 학습 부담 0)
Negative¶
- 레포가 커질수록 clone/checkout 시간 증가
- 프론트와 백엔드 기여자가 섞이면 코드 리뷰 부담 증가
- Luxtra 팀 다른 프로젝트(luxtra-bot, luxtra.dev)는 pnpm 이라 컨벤션 차이
Neutral¶
- Bun lockfile (
bun.lockb) 은 binary 라 diff 확인이 text 대비 불편 —bun install --save-text-lockfile옵션 검토 - Turborepo 없이도 cache 가 필요해지면 추후 도입 가능
Alternatives considered¶
Alternative 1: 멀티 레포 (Go 와 TS 분리)¶
Pros
- 각 레포가 가볍고 단순
- 소유권 분리 명확
Cons
- 도메인 코드 공유 시 git submodule 또는 퍼블리싱 필요
- PR 이 두 레포에 걸치면 조정 부담
- CI/CD 파이프라인 중복
Why rejected — engine/* 공유로 인한 이점이 멀티 레포 이점 압도.
Alternative 2: pnpm workspace (Luxtra 팀 컨벤션)¶
Pros
- Luxtra 다른 프로젝트와 도구 일치
Cons
- Bun 대비 install 속도 느림
- Bun 이 이미 runtime 으로 선택됨(ADR-0008)이라 Bun workspace 사용이 자연스러움
Why rejected — Bun workspace 가 Bun runtime 과 통합이 강함. Luxtra 컨벤션 차이는 감수.
Alternative 3: Turborepo¶
Pros
- 빌드 캐시, task orchestration
- PR 속도 향상
Cons
- 학습 부담 (config, pipeline 정의)
- Umbra 규모(2개 워크스페이스)에서 과한 도구
- Bun scripts 로 충분히 대체 가능
Why rejected — MVP 규모에 과함. 레포가 커지면 도입 재검토.
Alternative 4: Nx¶
Pros
- 강력한 빌드 캐시, plugin 생태계
Cons
- Turborepo 보다 더 무거움
- Angular/NestJS 컨벤션이 강해 React/Go 와 이질
Why rejected — 과도한 복잡도.
Compliance¶
- 루트
justfile의 recipes 에 프로세스별 명령 정의 (dev-bot,dev-api,dev-worker,dev-web,lint-go,lint-web,db-migrate,openapi등) - 루트
package.json은 Bun workspace 선언 전용 (scripts비움) - 프론트엔드 의존성 추가는
bun --cwd apps/web add <pkg>사용 - Go module 은 단일
go.mod만 사용.go.work는 도입하지 않음 (도입 시 별도 ADR 로 재논의) - 빌드 orchestrator(Turborepo 등) 도입은 ADR 로 재논의
Revisit triggers¶
- 워크스페이스가 5개 이상으로 늘어나면 Turborepo 검토
- 빌드 시간이 CI 에서 10분 이상으로 길어지면 캐시 도구 재평가
- Luxtra 전사 컨벤션이 Bun 으로 통일되지 않고 혼용이 문제가 되면 재검토
- Go 도메인이 별도 module 로 분리될 필요 (예: 외부 SDK 공개) 가 생기면
go.work도입 ADR 작성