ADR-001: Go + Next.js Monorepo
Status: Accepted
Date: 2026-05-09
Context
Embercore needs two distinct runtime components:
- An AI engine that orchestrates LLM-powered marketing agents, executes plans with topological ordering, manages SQLite persistence, and exposes tools via the MCP protocol.
- A web dashboard for plan visualization, checkpoint approvals, agent configuration, and artifact browsing.
We needed to choose languages/frameworks for each component and decide whether to structure them as separate repositories or a unified monorepo.
Decision
Go for the engine (packages/engine/)
- Performance and concurrency: Go’s goroutine model is ideal for orchestrating multiple agents executing plan steps in parallel layers (see
plan/toposort.go— Kahn’s algorithm produces concurrent execution layers). - Static binary:
go buildproduces a single binary (embercore-engine) with zero runtime dependencies. This simplifies distribution and local-first deployment. - Cross-compilation: Go’s built-in cross-compilation (
GOOS/GOARCH) pairs well with our choice of a pure-Go SQLite driver (see ADR-002). - Strong standard library:
net/http,encoding/json,database/sql,context, andslogcover most of our needs without third-party dependencies.
Next.js for the web dashboard (apps/web/)
- React ecosystem: Rich component libraries and community tooling for building interactive plan/agent UIs.
- App Router + SSR: Next.js 16 with the App Router enables server-side rendering for plan detail pages (
src/app/plans/[id]/page.tsx) and API routes for engine communication (src/app/api/). - TypeScript: Type safety across the frontend, with shared type definitions for plans, checkpoints, and artifacts.
Monorepo via pnpm workspaces
- Shared tooling: Single
pnpm-workspace.yamlmanagesapps/*,packages/*, andexamples/*. Root-level scripts coordinate builds across Go and Node.js. - Atomic changes: Cross-cutting changes (e.g., adding a new agent that needs both engine logic and a UI page) land in a single PR.
- Consistent CI: One GitHub Actions workflow validates both engine and web.
Consequences
Benefits:
- Single
git clonegives contributors the full system - Go engine can be developed and tested independently (
cd packages/engine && make test) - Web dashboard iterates independently (
cd apps/web && pnpm dev) - Shared examples and documentation live alongside both components
Trade-offs:
- Contributors need both Go 1.23+ and Node 20+ / pnpm 9+ installed (see DEVELOPMENT.md)
- The monorepo root requires pnpm workspace awareness — raw
npm installwon’t work - Go module path (
packages/engine/go.mod) is nested, which can confuse Go tooling expecting repo-root modules
Related decisions: