docs/monorepo-structure.md

Monorepo structure

Map of apps, packages, and infra in the studyflash monorepo — what each is for and where boundaries lie.

publishedrajivarchitecturemonorepoonboarding

PH analogue: posthog.com/handbook/engineering/project-structure.

TODO: architecture diagram (Excalidraw). The previous link was stale.

Apps

AppStackDescription
portalNuxt 3Student-facing web app
core-apiHono (TS)API service — auth, subscriptions, orchestration
learning-apiFastAPI (Py)AI content generation (flashcards, quizzes, summaries)
mobile-appExpo / React NativeMobile app
supabaseSupabaseSchemas, migrations, seeds, edge functions
landing-pageNuxt 3Marketing site

Other

AppDescription
mountain-maxMicrosite
subway-maxMicrosite
wrappedStudyflash Wrapped microsite
email-previewsTransactional email previews
marketing-emails-previewMarketing email previews

Packages

  • types — Shared TypeScript types (incl. generated Supabase DB types)
  • common — Shared utilities and constants
  • api-client — Shared API client
  • tsconfig — Shared TypeScript configs
  • devtools — Developer tooling scripts (Deno)
  • learning-service — Shared learning service client

Infra

infra/* — one Pulumi stack per concern. Examples:

  • infra/learning-api — Hetzner VM + preview environments (see preview environment plan)
  • infra/dns — DNS records
  • infra/infisical — secrets manager stack
  • infra/dokploy, infra/openreplay, infra/turborepo-cache — self-hosted services
  • infra/sentry — explicitly excluded from the workspace

Internal

internal/* — services and surfaces that aren't products:

  • internal/support-bot — Chatwoot SLA + triage assistant
  • internal/chatwoot — Chatwoot provider config
  • internal/docs — this handbook surface (Nuxt 3 + Nuxt Content)

internal/docs is intentionally not in pnpm-workspace.yaml. It runs its own pnpm install --ignore-workspace, so a half-finished docs demo can't break the workspace lockfile or CI pipeline.

Build order

Internal packages/* must be built before type-checking dependent apps:

pnpm turbo build --filter=@studyflash-ai/types \
                 --filter=@studyflash-ai/common \
                 --filter=@studyflash-ai/api-client \
                 --filter=@studyflash-ai/learning-service \
                 --filter=@studyflash-ai/marketing-emails

(Or pnpm turbo build for everything.)

Quick start

Prerequisites: Node.js, pnpm v10, Deno, Python 3, Docker, Infisical CLI.

pnpm install        # install dependencies
pnpm dev            # interactive dev launcher
pnpm dev:local      # full local dev stack
pnpm build          # build all apps
pnpm test           # run tests
pnpm lint           # lint all packages

Boundaries and rules

TODO. Things to capture:

  • What lives in packages/ vs inline in an app.
  • When a new app/ is justified.
  • core-apilearning-api boundary.
  • portalmobile-app shared code path (api-client, types).
  • internal/ vs apps/ — why support-bot isn't an app.