The Kaizen Workspace: A Production-Ready Turborepo Architecture
The Kaizen Workspace: A Production-Ready Turborepo Architecture
In the digital realm, architecture isn't just about organizing code—it's about constructing a reality where developers can build at the speed of thought. Today, I'm pulling back the curtain on the Kaizen Workspace: a production-ready monorepo that combines modern tooling, comprehensive guardrails, and AI integration.
The Philosophy: Continuous Improvement
Kaizen (改善) - The Japanese philosophy of continuous improvement. This workspace embodies that principle through:
- Quality Guardrails: Pre-commit hooks, type safety, and automated testing
- Developer Velocity: Code generators, shared packages, and hot reload
- AI Augmentation: MCP server integration for intelligent workflows
- Production Ready: Security, performance, and deployment best practices
The Foundation: Why Turborepo?
The Monorepo Advantage
graph TB
subgraph "Traditional Multi-Repo"
A1[Auth Repo] -.-> A2[Duplicate Config]
B1[Web Repo] -.-> B2[Duplicate Config]
C1[API Repo] -.-> C2[Duplicate Config]
A1 --> D[Different Versions]
B1 --> D
C1 --> D
end
subgraph "Kaizen Monorepo"
E[Shared Config]
F[Auth Package]
G[Web App]
H[API App]
F --> E
G --> E
H --> E
G --> F
H --> F
I[Single Version]
F --> I
G --> I
H --> I
end
Why Turborepo specifically?
- Intelligent Caching: Remote and local caching means builds that take seconds, not minutes
- Parallel Execution: Build all packages simultaneously
- Incremental Builds: Only rebuild what changed
- Simple Configuration: JSON-based pipeline definition
{
"$schema": "https://turborepo.com/schema.json",
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": [".next/**", "dist/**"]
},
"dev": {
"cache": false,
"persistent": true
}
}
}
The Architecture: Layered Reality
Layer 1: Applications
apps/
├── web/ # Next.js 15 - Main web app
├── docs/ # Documentation site
├── matrix-blog/ # This blog (meta!)
└── api-auth/ # Microservice architecture
Each app is a self-contained universe with its own:
- Routes and pages
- Component library
- API endpoints
- Test suites
- Deployment configuration
Key Pattern: App Router Architecture
// apps/web/app/layout.tsx
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
<AuthProvider>
<Navigation />
{children}
</AuthProvider>
</body>
</html>
);
}
Layer 2: Shared Packages
packages/
├── auth/ # Authentication library
├── ui/ # React component library
├── eslint-config/ # Shared linting rules
├── typescript-config/# Shared TS config
└── mcp-server/ # AI integration server
The @repo/auth
Package
The crown jewel. A production-ready authentication library that supports:
Server-side:
// JWT token generation
import { generateTokenPair, verifyToken } from '@repo/auth/server';
const tokens = await generateTokenPair({
userId: user.id,
email: user.email,
role: user.role,
});
// Returns: { accessToken, refreshToken }
Client-side:
// React hooks for authentication
import { useAuth } from '@repo/auth/client';
function Dashboard() {
const { user, login, logout, isAuthenticated } = useAuth();
if (!isAuthenticated) {
return <LoginForm onSubmit={login} />;
}
return <div>Welcome, {user.email}!</div>;
}
Middleware:
// Next.js middleware protection
import { withAuth } from '@repo/auth/server/next-middleware';
export const GET = withAuth(
async (request, { user }) => {
return NextResponse.json({
message: "Secret data",
user: user.email
});
},
{ roles: ['admin'] } // Optional role-based access
);
Layer 3: Infrastructure & Tooling
tools/
└── generators/ # Code generation CLI
├── frontend # Generate Next.js apps
├── backend # Generate Fastify APIs
└── package # Generate packages
The Quality System: Maximum Guardrails
Pre-commit Pipeline
Every commit goes through a gauntlet of quality checks:
sequenceDiagram
participant Dev
participant Git
participant Husky
participant Lint
participant TypeScript
participant Tests
Dev->>Git: git commit
Git->>Husky: Trigger pre-commit
Husky->>Lint: ESLint + Prettier
Lint->>TypeScript: Type checking
TypeScript->>Tests: Run affected tests
Tests->>Git: ✅ All passed
Git->>Dev: Commit successful
Configuration:
// .husky/pre-commit
#!/usr/bin/env sh
npx lint-staged
npm run check-types
// .lintstagedrc.json
{
"*.{ts,tsx,js,jsx}": [
"eslint --fix",
"prettier --write"
],
"*.{json,md}": [
"prettier --write"
]
}
TypeScript: Strict Mode Everything
// packages/typescript-config/base.json
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"noEmit": true,
"isolatedModules": true,
"esModuleInterop": true,
"skipLibCheck": true
}
}
Benefits:
- ✅ Catch errors at compile time
- ✅ Better IDE autocomplete
- ✅ Self-documenting code
- ✅ Easier refactoring
The Build System: Turborepo in Action
Task Pipeline
{
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": [".next/**", "dist/**"]
},
"lint": {
"dependsOn": ["^lint"]
},
"test": {
"dependsOn": ["^build"],
"outputs": ["coverage/**"]
}
}
}
What this means:
- Dependencies First:
^build
means "build all dependencies before this package" - Parallel When Possible: Independent packages build simultaneously
- Smart Caching: Outputs are cached based on inputs
- Incremental: Only rebuild what changed
Build Performance
Before Turborepo:
npm run build
> 180 seconds (3 minutes)
After Turborepo (with cache):
turbo run build
> 12 seconds ⚡️
Code Generation: Consistency at Scale
The Generator CLI
npm run generate
? What would you like to generate?
❯ Frontend App (Next.js 15)
Backend App (Fastify + tRPC)
Shared Package
Full-stack App (Frontend + Backend)
Frontend Generator
Creates a fully-configured Next.js 15 app:
// Generated structure
apps/my-app/
├── app/
│ ├── layout.tsx # Root layout with auth
│ ├── page.tsx # Home page
│ └── api/
│ └── health/ # Health check endpoint
├── components/
│ ├── ui/ # Shadcn components
│ └── providers/ # React providers
├── lib/
│ └── utils.ts # Utility functions
├── __tests__/ # Vitest tests
├── e2e/ # Playwright tests
├── next.config.js # Next.js config
├── tailwind.config.ts # Tailwind config
└── package.json # Dependencies
Generator Benefits:
- ✅ Consistent structure across apps
- ✅ Best practices built-in
- ✅ Tests pre-configured
- ✅ Auth integration ready
- ✅ 5 minutes to production-ready app
AI Integration: The MCP Server
Model Context Protocol
graph LR
AI[Claude/AI Agents] --> MCP[MCP Server]
MCP --> TOOLS[17 Tools]
MCP --> RESOURCES[9+ Resources]
TOOLS --> GEN[Code Generators]
TOOLS --> DB[Database Ops]
TOOLS --> API[API Testing]
TOOLS --> GIT[Git Operations]
RESOURCES --> DOCS[Documentation]
RESOURCES --> CONFIG[Configurations]
RESOURCES --> SCHEMAS[DB Schemas]
Available Tools
Code Generation:
await mcpServer.tools.generate_frontend_app({
name: "my-app",
framework: "nextjs",
features: ["auth", "tailwind", "tests"]
});
Database Operations:
await mcpServer.tools.prisma_migrate({
name: "add_users_table"
});
API Testing:
await mcpServer.tools.test_api_endpoint({
url: "http://localhost:3000/api/health",
method: "GET"
});
Why MCP?
Traditional Workflow:
1. Open terminal
2. cd to project
3. Run command
4. Copy output
5. Paste in chat
6. Get suggestion
7. Execute manually
MCP Workflow:
1. Ask AI to generate app
2. Done ✅
Testing Strategy: The Test Pyramid
graph TD
E2E[E2E Tests<br/>Playwright<br/>~10 tests]
INT[Integration Tests<br/>Vitest<br/>~50 tests]
UNIT[Unit Tests<br/>Vitest<br/>~200+ tests]
E2E --> INT
INT --> UNIT
style UNIT fill:#4CAF50
style INT fill:#2196F3
style E2E fill:#FF9800
Unit Tests (Vitest)
// packages/auth/__tests__/jwt.test.ts
import { describe, it, expect } from 'vitest';
import { generateTokenPair, verifyToken } from '../src/server';
describe('JWT Token Generation', () => {
it('should generate valid token pair', async () => {
const payload = {
userId: '123',
email: 'neo@matrix.io',
role: 'admin'
};
const tokens = await generateTokenPair(payload);
expect(tokens).toHaveProperty('accessToken');
expect(tokens).toHaveProperty('refreshToken');
const verified = await verifyToken(tokens.accessToken);
expect(verified.userId).toBe(payload.userId);
});
});
Integration Tests
// apps/web/__tests__/api/auth.test.ts
import { describe, it, expect } from 'vitest';
describe('POST /api/auth/login', () => {
it('should return tokens for valid credentials', async () => {
const response = await fetch('http://localhost:3000/api/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: 'test@example.com',
password: 'password123'
})
});
expect(response.ok).toBe(true);
const data = await response.json();
expect(data).toHaveProperty('accessToken');
});
});
E2E Tests (Playwright)
// apps/web/e2e/auth-flow.spec.ts
import { test, expect } from '@playwright/test';
test('user can login and access dashboard', async ({ page }) => {
await page.goto('http://localhost:3000');
await page.click('[data-testid="login-button"]');
await page.fill('[name="email"]', 'neo@matrix.io');
await page.fill('[name="password"]', 'whiterabbit');
await page.click('[type="submit"]');
await expect(page).toHaveURL('/dashboard');
await expect(page.locator('text=Welcome, Neo')).toBeVisible();
});
Deployment: Multi-Environment Strategy
Application Deployment
Next.js Apps → Vercel
# apps/web, apps/docs, apps/matrix-blog
vercel --prod
Microservices → Railway/Render
# apps/api-auth
railway up
Environment Configuration
// apps/web/.env.production
DATABASE_URL="postgresql://..."
NEXTAUTH_SECRET="..."
NEXTAUTH_URL="https://app.kinho.dev"
API_URL="https://api.kinho.dev"
CI/CD Pipeline
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
ci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
with:
node-version: 20
- name: Install dependencies
run: npm ci
- name: Build packages
run: npm run build --workspace=@repo/auth --workspace=@repo/ui
- name: Lint
run: npm run lint
- name: Type check
run: npm run check-types
- name: Run tests
run: npm run test
- name: Build apps
run: npm run build --workspace=web --workspace=docs
Performance Optimizations
1. Build-Time Optimizations
Turborepo Caching:
- Remote cache via Vercel
- Local
.turbo
cache - Only rebuild changed packages
TypeScript Project References:
// tsconfig.json
{
"references": [
{ "path": "./apps/web" },
{ "path": "./apps/docs" },
{ "path": "./packages/auth" },
{ "path": "./packages/ui" }
]
}
2. Runtime Optimizations
Next.js App Router:
- Server Components by default
- Streaming HTML
- Automatic code splitting
- Image optimization
Example:
// app/blog/page.tsx - Server Component
async function BlogPage() {
const posts = await getPosts(); // Runs on server
return (
<div>
{posts.map(post => (
<PostCard key={post.id} post={post} />
))}
</div>
);
}
3. Package Optimizations
Auth Package:
- Tree-shakeable exports
- Minimal dependencies
- ESM-only build
// packages/auth/package.json
{
"exports": {
"./server": "./dist/server/index.js",
"./client": "./dist/client/index.js"
},
"sideEffects": false
}
Security Considerations
1. Authentication Security
// JWT with short expiration
const ACCESS_TOKEN_EXPIRY = '15m';
const REFRESH_TOKEN_EXPIRY = '7d';
// Password hashing with bcrypt
const hashedPassword = await hashPassword(password, 10);
// httpOnly cookies
res.setHeader('Set-Cookie', [
`accessToken=${accessToken}; HttpOnly; Secure; SameSite=Strict`,
`refreshToken=${refreshToken}; HttpOnly; Secure; SameSite=Strict`
]);
2. API Security
// Input validation with Zod
const loginSchema = z.object({
email: z.string().email(),
password: z.string().min(8)
});
// Type-safe validation
const data = loginSchema.parse(req.body);
3. Environment Security
// packages/auth/src/env.ts
import { z } from 'zod';
const envSchema = z.object({
JWT_SECRET: z.string().min(32),
DATABASE_URL: z.string().url(),
NODE_ENV: z.enum(['development', 'production', 'test'])
});
export const env = envSchema.parse(process.env);
Lessons Learned
What Worked Well
- Turborepo: 15x faster builds with caching
- Code Generators: Consistency across 5+ apps
- Shared Auth: One implementation, zero security drift
- TypeScript Strict Mode: Caught bugs before production
- MCP Integration: AI becomes a development partner
What We'd Do Differently
- Start with Monorepo: Don't migrate later, it's painful
- More Unit Tests Early: Integration tests are expensive
- Document as You Build: Architecture docs save weeks
- Invest in Generators: They pay dividends quickly
The Results
Metrics
- Build Time: 180s → 12s (15x improvement)
- Time to New App: 2 days → 5 minutes
- Code Duplication: ~40% → ~5%
- Test Coverage: 45% → 82%
- Developer Onboarding: 2 weeks → 3 days
Developer Experience
// Before: Every app different
apps/app1/pages/ // Pages Router
apps/app2/src/app/ // App Router
apps/app3/routes/ // Different framework
// After: Consistent structure
apps/*/app/ // App Router
apps/*/components/ // Components
apps/*/__tests__/ // Tests
Conclusion: Build Your Own Matrix
The Kaizen Workspace isn't just a monorepo—it's a framework for building frameworks. A meta-architecture that makes creating production-ready applications as simple as running npm run generate
.
Key Takeaways
- Monorepos scale: Share code, configuration, and knowledge
- Guardrails enable speed: More checks = more confidence = ship faster
- Generation > Duplication: Build tools that build apps
- AI is a multiplier: MCP integration isn't future—it's now
Get Started
# Clone the workspace
git clone https://github.com/kayossouza/kaizen-workspace
# Install dependencies
npm install
# Generate your first app
npm run generate
# Start development
turbo run dev
The code is in the repository. The architecture is documented. The tools are ready.
The only question is: what will you build?
Resources
- Kaizen Workspace GitHub
- Turborepo Documentation
- Next.js 15 Documentation
- Model Context Protocol
- Architecture Documentation
Remember: there is no spoon. There is only continuous improvement.
🔧 Built with: Turborepo • Next.js 15 • TypeScript • Vitest • Playwright • MCP
⚡️ Powered by: Kaizen Philosophy • Open Source • Coffee