10 min read
ā¢Question 44 of 47hardNext.js Monorepo Architecture
Setting up monorepos with Next.js.
Monorepo Architecture
Turborepo Setup
data.jsonJSON
// turbo.json
{
"$schema": "https://turbo.build/schema.json",
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": [".next/**", "dist/**"]
},
"dev": {
"cache": false,
"persistent": true
},
"lint": {},
"test": {
"dependsOn": ["build"]
}
}
}Workspace Structure
code.jsJavaScript
monorepo/
āāā apps/
ā āāā web/ # Next.js main app
ā āāā admin/ # Next.js admin app
ā āāā docs/ # Next.js docs
āāā packages/
ā āāā ui/ # Shared components
ā āāā config/ # Shared configs
ā āāā database/ # Prisma schema
ā āāā utils/ # Shared utilities
āāā turbo.json
āāā package.jsonShared Packages
data.jsonJSON
// packages/ui/package.json
{
"name": "@repo/ui",
"exports": {
".": "./src/index.tsx",
"./button": "./src/Button.tsx"
}
}
// apps/web/package.json
{
"dependencies": {
"@repo/ui": "*",
"@repo/database": "*"
}
}Shared Configuration
code.txtTSX
// packages/config/tailwind.config.ts
import type { Config } from 'tailwindcss';
const config: Config = {
content: [
'./src/**/*.{ts,tsx}',
'../../packages/ui/**/*.{ts,tsx}',
],
theme: {
extend: {
colors: {
brand: '#0070f3',
},
},
},
};
export default config;
// apps/web/tailwind.config.ts
import baseConfig from '@repo/config/tailwind';
export default {
...baseConfig,
content: [...baseConfig.content, './app/**/*.{ts,tsx}'],
};Internal Packages
code.txtTSX
// packages/database/index.ts
export * from '@prisma/client';
export { prisma } from './client';
// Type-safe across all apps
import { prisma, User } from '@repo/database';