Emmanuel Doji

Portfolio · 2026

000%

EmmanuelED · 26
All case studies

Pagrin · 2025 · Founding engineer / architect

Pagrin — Multi-App Monorepo with Shared AI, Analytics, and i18n

Apps in workspace
2
Shared packages
4
Build time (cold)
~45s
Build time (Turbo cache hit)
~3s

Why a monorepo

The partners dashboard and the embeddable web SDK had three things in common: a chat component (LLM-backed support agent), analytics emission (every interaction is a span), and i18n. Three copy-paste-shaped problems.

Turborepo with pnpm workspaces lets both apps consume the same package source. A change to the chat UI ships to both surfaces in one PR. The dependency graph is explicit in turbo.json, so CI rebuilds only what changed.

The packages

  • @pagrin/ai-chat — React component + hook backed by the Vercel AI SDK. Streaming responses, tool-call rendering, conversation persistence via callbacks (the app decides where to store).
  • @pagrin/analytics — OpenTelemetry wrapper. Every chat message, every CTA click, every page view emits a span. Exporters are pluggable: Sentry, Honeycomb, Vercel Analytics, or a local development exporter.
  • @pagrin/i18n — typed translation keys with a validate-translations script that flags drift between locales in CI, plus a translate script that pipes new keys through an LLM for a first-draft translation.
  • @pagrin/ui — design system primitives (Button, Input, Modal, Toast) on top of Radix with Tailwind-styled defaults.

What I'd do differently

I overinvested in i18n tooling early — the translate script was clever but only ran twice before we shipped a hardcoded English MVP for the first three partners. Tooling that doesn't get used twice in production is debt, not infrastructure.