ADR-0001: Language: Go¶
Umbra 의 백엔드 언어로 Go 1.23 을 채택한다.
Status¶
Accepted
- Decided at — 2026-04-13
- Decided by — Pablo
Context¶
Umbra 는 luxtra-bot 의 후속작이다. luxtra-bot 은 Rust + Twilight 로 구현되었지만 진욱의 Rust 학습 곡선이 가팔라 페어 개발 속도가 현저히 떨어졌고, 결국 프로젝트가 정체되어 폐기되었다. Umbra 는 같은 비즈니스 가치를 "페어 개발이 가능한 스택" 으로 재구현하는 프로젝트이다.
새 언어 선택의 제약 조건:
- Pablo 와 진욱이 함께 구현 가능해야 함
- 결제 SaaS 수준의 프로덕션 안정성
- Discord 봇 생태계에 성숙한 라이브러리 존재
- Fly.io 같은 일반적 플랫폼에서 배포 가능
- 학습 곡선이 Rust 보다 현저히 낮아야 함
후보 언어: Go, TypeScript (Node/Bun), Python, Kotlin.
Decision¶
Go 1.23 을 백엔드 언어로 채택한다.
선택 근거:
- 낮은 학습 곡선 — Go 는 문법이 단순하고 개념 수가 적다. 진욱이 수 주 내 실무 생산성에 도달 가능하다.
- Discord 봇 생태계 — disgo 가 Components V2 를 정식 지원하며 활발히 유지보수된다.
- concurrency 모델 — goroutine 과 channel 은 Discord Gateway + HTTP API + 백그라운드 작업의 동시성을 자연스럽게 처리한다.
- 표준 라이브러리 —
net/http,context,slog등이 프로덕션 품질로 제공된다. - 빠른 컴파일과 배포 — 정적 바이너리로 distroless Docker 이미지에 가볍게 배포된다.
- Pablo 경험 — 이미 Go 숙련도가 있다. 리드 역할에 공백이 없다.
Consequences¶
Positive¶
- 페어 개발 속도 향상, 진욱의 기여도 증가
- Discord 봇 생태계 활용으로 차별화 영역(Recovery)에 집중 가능
- 바이너리 배포 단순성으로 Fly.io 운영 부담 ↓
- 표준 라이브러리 완성도로 외부 의존성 최소화
Negative¶
- Rust 대비 제로 코스트 추상화 포기 (예: no enum ADT, no generics on methods)
- 에러 처리 verbosity (
if err != nil반복) - Generics 가 상대적으로 제한적 (1.18+ 지원하나 실사용 사례 누적 중)
Neutral¶
- Nabi 런타임 위 Rust 재작성 계획이 존재하므로 Go 는 중간 단계 (ADR-0031 참조)
- 도메인 모델은 언어 무관하게 설계 (Hexagonal) 하여 재작성 비용 완화
Alternatives considered¶
Alternative 1: TypeScript (Node/Bun)¶
Pros
- 프론트엔드와 언어 통일, 풀스택 TypeScript
- Node 생태계 최대 규모
- Bun 런타임으로 빠른 시작
Cons
- long-running Discord Gateway 프로세스에 덜 적합
- Discord 라이브러리 중 Components V2 지원이 검증되지 않음
- 결제 도메인의 타입 안전성은 런타임 검증에 의존 (Go 의 컴파일 타입 안전성 대비 약함)
Why rejected — 백엔드-프론트엔드 언어 통일 이점보다 Go 의 concurrency 모델과 Discord 생태계 성숙도가 더 큰 가치. 풀스택 통일은 Phase 2 검토 가능.
Alternative 2: Python (FastAPI)¶
Pros
- 학습 곡선 가장 낮음
- 결제 도메인 레퍼런스 풍부
Cons
- Discord 봇 라이브러리(discord.py)의 Components V2 지원 미흡
- long-running 프로세스의 GIL 제약
- 타입 시스템이 런타임 의존
Why rejected — Discord 라이브러리 생태계와 GIL 제약이 Umbra 의 요구에 맞지 않음.
Alternative 3: Kotlin (Spring)¶
Pros
- JVM 생태계 성숙도
- JDA (Discord 라이브러리) 존재
Cons
- JVM 메모리 풋프린트와 시작 시간이 Fly.io machine 에 부담
- 진욱과 Pablo 모두 Spring 경험 낮음
- Gradle/Maven 빌드 부담
Why rejected — 경험 공백과 배포 풋프린트가 문제. Luxtra 팀 어느 곳에서도 Kotlin/Spring 을 메인으로 쓰지 않는다.
Alternative 4: Rust (luxtra-bot 방식 유지)¶
Pros
- 가장 강력한 타입 시스템
- zero-cost abstraction
- Pablo 의 선호 언어
Cons
- 진욱의 학습 곡선이 페어 개발 속도를 막음 (이미 luxtra-bot 에서 검증된 문제)
- 변경 빈도가 높은 비즈니스 도메인에서 borrow checker 마찰
Why rejected — luxtra-bot 에서 입증된 문제. Rust 재채택은 진욱의 숙련도가 충분히 쌓인 후 Nabi 런타임 위 재작성으로 진행 (ADR-0031).
Compliance¶
go.mod에 Go 1.23 명시.tool-versions또는mise.toml에 Go 1.23 고정- CI 는 Go 1.23 으로 테스트 (golangci-lint, go test)
Revisit triggers¶
- Nabi 런타임 완성 + 진욱의 Rust 숙련도 도달 → Rust 재작성 (ADR-0031 발동)
- Go 버전 업그레이드 (1.24+) — 주요 기능 도입 시 별도 ADR
- 팀 규모 확장으로 언어 분산이 필요해지면 재검토
References¶
- Go 1.23 Release Notes
- disgo GitHub
- luxtra-bot 폐기 결정 (팀 내부 논의, 2026-04)