When a Monorepo Makes Sense for an AI Product
A monorepo is not appropriate for every AI product at MVP stage. If you are building a single Next.js application with a PostgreSQL backend, a monorepo adds unnecessary complexity. Turborepo becomes valuable when you have two or more applications that share code: a Next.js web app and a React Native mobile app sharing TypeScript type definitions, a main application and an admin portal sharing UI components and utilities, or a web frontend and an Express API sharing validation schemas and business logic types. Without a monorepo in these scenarios, shared code is either duplicated (creating drift and maintenance burden) or published to a private npm registry (adding publishing overhead for every change). Turborepo lets shared packages live in the same repository as the applications that use them, with changes immediately available without a publish step.
Repository Structure and Package Organisation
A Turborepo monorepo is organised into apps (deployable applications) and packages (shared libraries). A typical AI product monorepo structure: apps/web (Next.js AI application), apps/mobile (React Native app), apps/api (Express or Fastify API server), packages/types (shared TypeScript type definitions), packages/ui (shared UI component library), packages/db (Prisma or Drizzle schema and client), packages/config (shared ESLint, TypeScript, and Tailwind configuration). SpeedMVPs designs the package boundaries to minimise coupling: the packages/types package has no dependencies on other packages; packages/ui depends only on packages/types; apps depend on packages but not on each other. This hierarchy ensures that circular dependencies cannot occur and that the incremental build cache can work effectively.
Incremental Builds and CI/CD Performance
Turborepo's key performance feature is incremental builds. Each task (build, test, lint, type-check) is cached based on the hash of its inputs (source files, dependency tree, environment variables). If nothing has changed since the last successful run, Turborepo replays the cached output rather than re-running the task. In a monorepo where a PR changes only the web app, the mobile app's build is not re-run. In a CI pipeline running on every PR, this can reduce build time from 15 minutes to 3 minutes for PRs that touch a single package. SpeedMVPs configures Turborepo's remote caching via Vercel's Remote Cache (free with Vercel) or a self-hosted Turborepo remote cache for non-Vercel deployments, so the cache is shared across all developers' machines and CI runners.
Shared Types and API Contracts
One of the most practical benefits of a Turborepo monorepo for AI products is shared TypeScript types between the frontend, backend, and mobile app. When the AI API changes its response format, a shared types package makes the type change visible immediately across all consumers: the TypeScript compiler fails in the web app and the mobile app if the change breaks the interface they depend on, before any code is deployed. This eliminates a class of integration bugs where the backend and frontend have diverged in their understanding of an API contract. SpeedMVPs designs the shared types package with Zod schemas that serve dual purpose: runtime validation on the API and TypeScript type inference in consumers, so the type system is grounded in the actual runtime data structure.
Managing Dependencies and Workspace Updates
In a monorepo, dependency management requires care. Mismatched versions of shared dependencies (React, TypeScript, Tailwind) between packages cause subtle build errors and runtime issues. Turborepo uses pnpm workspaces as the underlying package manager, with pnpm's catalog feature (from pnpm 9) for centralised version pinning: all packages declare a dependency using catalog:default, and the single version in the pnpm-workspace.yaml file controls the version across the entire repository. SpeedMVPs configures the workspace with pinned versions for core shared dependencies and uses Dependabot with grouped update rules to keep dependencies current without requiring individual updates in each package.
Turborepo and AI Service Code Organisation
A Python AI service does not fit naturally into a JavaScript Turborepo monorepo, but it can coexist in the same repository without being part of the Turborepo task graph. SpeedMVPs structures the repository so the Python AI service has its own directory (services/ai-processor) with its own virtual environment and test runner, while the JavaScript apps and packages are managed by Turborepo. The CI pipeline runs Turborepo tasks for the JavaScript workspaces and a separate pytest step for the Python service in parallel. This keeps all code in a single repository (useful for cross-reference and shared configuration) without forcing the Python service into a JavaScript build tool.