Set up and manage monorepos with Turborepo and shared packages
# Monorepo with Turborepo for Google Antigravity
Build scalable monorepo architectures using Turborepo in your Google Antigravity projects. This comprehensive guide covers workspace configuration, caching strategies, and pipeline optimization for maximum build performance.
## Turborepo Project Structure
Set up an optimized monorepo structure:
```
my-monorepo/
├── apps/
│ ├── web/ # Next.js web application
│ │ ├── package.json
│ │ └── src/
│ ├── api/ # Express/Fastify API server
│ │ ├── package.json
│ │ └── src/
│ └── mobile/ # React Native app
│ ├── package.json
│ └── src/
├── packages/
│ ├── ui/ # Shared UI components
│ │ ├── package.json
│ │ └── src/
│ ├── database/ # Prisma schema and client
│ │ ├── package.json
│ │ └── prisma/
│ ├── config/ # Shared configurations
│ │ ├── eslint/
│ │ ├── typescript/
│ │ └── tailwind/
│ └── utils/ # Shared utilities
│ ├── package.json
│ └── src/
├── turbo.json
├── package.json
└── pnpm-workspace.yaml
```
## Turborepo Configuration
Configure efficient build pipelines:
```json
// turbo.json
{
"$schema": "https://turbo.build/schema.json",
"globalDependencies": ["**/.env.*local"],
"globalEnv": ["NODE_ENV", "CI"],
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": [".next/**", "!.next/cache/**", "dist/**"],
"env": ["NEXT_PUBLIC_*", "DATABASE_URL"]
},
"lint": {
"dependsOn": ["^lint"],
"outputs": []
},
"type-check": {
"dependsOn": ["^build"],
"outputs": []
},
"test": {
"dependsOn": ["build"],
"outputs": ["coverage/**"],
"inputs": ["src/**/*.tsx", "src/**/*.ts", "tests/**/*.ts"]
},
"dev": {
"cache": false,
"persistent": true
},
"db:generate": {
"cache": false
},
"db:push": {
"cache": false
}
}
}
```
## Root Package Configuration
Set up workspace-level package management:
```json
// package.json (root)
{
"name": "my-monorepo",
"private": true,
"workspaces": ["apps/*", "packages/*"],
"scripts": {
"build": "turbo build",
"dev": "turbo dev",
"lint": "turbo lint",
"type-check": "turbo type-check",
"test": "turbo test",
"clean": "turbo clean && rm -rf node_modules",
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
"db:generate": "turbo db:generate",
"db:push": "turbo db:push"
},
"devDependencies": {
"@turbo/gen": "^1.11.0",
"prettier": "^3.1.0",
"turbo": "^1.11.0"
},
"packageManager": "pnpm@8.10.0",
"engines": {
"node": ">=18"
}
}
```
```yaml
# pnpm-workspace.yaml
packages:
- "apps/*"
- "packages/*"
```
## Shared UI Package
Create a reusable component library:
```typescript
// packages/ui/package.json
{
"name": "@repo/ui",
"version": "0.0.0",
"private": true,
"main": "./src/index.ts",
"types": "./src/index.ts",
"exports": {
".": "./src/index.ts",
"./components/*": "./src/components/*.tsx",
"./hooks/*": "./src/hooks/*.ts"
},
"scripts": {
"lint": "eslint src/",
"type-check": "tsc --noEmit"
},
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
},
"devDependencies": {
"@repo/config": "workspace:*",
"@types/react": "^18.2.0",
"typescript": "^5.3.0"
}
}
```
```typescript
// packages/ui/src/components/Button.tsx
import { forwardRef, ButtonHTMLAttributes } from "react";
import { cn } from "../utils/cn";
export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
variant?: "primary" | "secondary" | "outline" | "ghost";
size?: "sm" | "md" | "lg";
isLoading?: boolean;
}
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant = "primary", size = "md", isLoading, children, disabled, ...props }, ref) => {
const variants = {
primary: "bg-gradient-to-r from-indigo-500 to-purple-500 text-white hover:opacity-90",
secondary: "bg-gray-800 text-white border border-gray-700 hover:bg-gray-700",
outline: "border-2 border-indigo-500 text-indigo-500 hover:bg-indigo-500/10",
ghost: "text-gray-400 hover:text-white hover:bg-gray-800",
};
const sizes = {
sm: "px-3 py-1.5 text-sm",
md: "px-4 py-2 text-base",
lg: "px-6 py-3 text-lg",
};
return (
<button
ref={ref}
className={cn(
"inline-flex items-center justify-center rounded-lg font-medium transition-all",
"focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2",
"disabled:opacity-50 disabled:cursor-not-allowed",
variants[variant],
sizes[size],
className
)}
disabled={disabled || isLoading}
{...props}
>
{isLoading && (
<svg className="animate-spin -ml-1 mr-2 h-4 w-4" fill="none" viewBox="0 0 24 24">
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
</svg>
)}
{children}
</button>
);
}
);
Button.displayName = "Button";
```
## Shared Database Package
Configure Prisma for workspace sharing:
```typescript
// packages/database/package.json
{
"name": "@repo/database",
"version": "0.0.0",
"private": true,
"main": "./src/index.ts",
"types": "./src/index.ts",
"scripts": {
"db:generate": "prisma generate",
"db:push": "prisma db push",
"db:migrate": "prisma migrate dev",
"db:studio": "prisma studio"
},
"dependencies": {
"@prisma/client": "^5.7.0"
},
"devDependencies": {
"prisma": "^5.7.0"
}
}
```
```typescript
// packages/database/src/index.ts
import { PrismaClient } from "@prisma/client";
const globalForPrisma = globalThis as unknown as {
prisma: PrismaClient | undefined;
};
export const db = globalForPrisma.prisma ?? new PrismaClient({
log: process.env.NODE_ENV === "development" ? ["query", "error", "warn"] : ["error"],
});
if (process.env.NODE_ENV !== "production") {
globalForPrisma.prisma = db;
}
export * from "@prisma/client";
```
## Remote Caching Configuration
Enable Vercel Remote Cache for CI:
```bash
# .github/workflows/ci.yml
- name: Setup Turbo Remote Cache
uses: actions/cache@v3
with:
path: .turbo
key: turbo-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
- name: Build with Remote Cache
run: pnpm turbo build --token=${{ secrets.TURBO_TOKEN }} --team=${{ secrets.TURBO_TEAM }}
```
Google Antigravity generates scalable monorepo configurations with optimized caching and build pipelines that dramatically improve development velocity across large codebases.This Monorepo prompt is ideal for developers working on:
By using this prompt, you can save hours of manual coding and ensure best practices are followed from the start. It's particularly valuable for teams looking to maintain consistency across their monorepo implementations.
Yes! All prompts on Antigravity AI Directory are free to use for both personal and commercial projects. No attribution required, though it's always appreciated.
This prompt works excellently with Claude, ChatGPT, Cursor, GitHub Copilot, and other modern AI coding assistants. For best results, use models with large context windows.
You can modify the prompt by adding specific requirements, constraints, or preferences. For Monorepo projects, consider mentioning your framework version, coding style, and any specific libraries you're using.