Monorepo Integration
Guide to integrating Sofondo Framework into a monorepo architecture using Turborepo or other monorepo tools.
Overview
Sofondo Framework is designed to work seamlessly in monorepo environments, allowing you to share components, utilities, and configurations across multiple applications.
Monorepo Structure
Recommended monorepo structure with Sofondo:
my-monorepo/
├── apps/
│ ├── web/ # Next.js application
│ ├── admin/ # Admin dashboard
│ └── docs/ # Documentation site
├── packages/
│ ├── ui/ # Shared Sofondo components
│ ├── config/ # Shared Sofondo configs
│ └── utils/ # Shared utilities
├── package.json
└── turbo.json # Turborepo config
Setting Up Turborepo
Install Turborepo in your monorepo:
npm install turbo --save-dev
Create a turbo.json configuration:
{
"$schema": "https://turbo.build/schema.json",
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**"]
},
"dev": {
"cache": false,
"persistent": true
},
"lint": {
"dependsOn": ["^lint"]
}
}
}
Shared UI Package
Create a shared UI package that re-exports Sofondo components:
// packages/ui/src/index.ts
export {
PageHeader,
DataGrid,
StatCard,
StatGrid,
Card,
Breadcrumb,
ProgressBar,
Skeleton,
CustomScrollbar,
} from '@sofondo/react';
// Custom components built on top of Sofondo
export { CustomTable } from './components/CustomTable';
export { DashboardLayout } from './components/DashboardLayout';
Package.json for the UI package:
{
"name": "@mycompany/ui",
"version": "0.1.0",
"main": "./src/index.ts",
"types": "./src/index.ts",
"dependencies": {
"@sofondo/core": "workspace:*",
"@sofondo/react": "workspace:*",
"@sofondo/styles": "workspace:*"
},
"devDependencies": {
"react": "^18.3.1",
"react-dom": "^18.3.1"
}
}
Shared Configuration
Create a shared configuration package:
// packages/config/src/sofondo.config.ts
import { defineConfig } from '@sofondo/core';
export const baseConfig = defineConfig({
theme: {
defaultMode: 'light',
enableSystemTheme: true,
},
sidebar: {
defaultCollapsed: false,
collapsible: true,
},
});
export const adminConfig = defineConfig({
...baseConfig,
sidebar: {
defaultCollapsed: true,
collapsible: true,
},
});
Using in Applications
Import from shared packages in your apps:
// apps/web/app/layout.tsx
import { ConfigProvider } from '@sofondo/react';
import { baseConfig } from '@mycompany/config';
import '@sofondo/styles/global.css';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<ConfigProvider config={baseConfig}>
{children}
</ConfigProvider>
</body>
</html>
);
}
// apps/web/app/dashboard/page.tsx
import { PageHeader, DataGrid } from '@mycompany/ui';
import { CustomTable } from '@mycompany/ui';
export default function DashboardPage() {
return (
<div>
<PageHeader title="Dashboard" />
<CustomTable />
</div>
);
}
Workspace Configuration
Set up pnpm workspaces in pnpm-workspace.yaml:
packages:
- 'apps/*'
- 'packages/*'
Or for npm/yarn workspaces in root package.json:
{
"workspaces": [
"apps/*",
"packages/*"
]
}
Development Workflow
Run all apps in development mode:
turbo dev
Build all packages and apps:
turbo build
Run specific app:
turbo dev --filter=web
Dependency Management
Install dependencies at the root:
# Install to root
pnpm add -w typescript
# Install to specific package
pnpm add react --filter=@mycompany/ui
TypeScript Configuration
Share TypeScript configuration across packages:
// packages/typescript-config/base.json
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"lib": ["ES2020", "DOM"],
"jsx": "react-jsx",
"strict": true,
"moduleResolution": "bundler",
"resolveJsonModule": true,
"esModuleInterop": true,
"skipLibCheck": true
}
}
Use in applications:
// apps/web/tsconfig.json
{
"extends": "@mycompany/typescript-config/base.json",
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}
Benefits of Monorepo
- Code Sharing: Share Sofondo configurations and custom components
- Consistent Versioning: Keep dependencies aligned across apps
- Atomic Changes: Update shared code and all consuming apps together
- Better Collaboration: Easier to maintain and review cross-app changes
- Faster Development: Shared build cache and parallel execution
Common Pitfalls
Circular Dependencies
Avoid circular dependencies between packages:
// ❌ Bad: packages/ui imports from packages/config, and vice versa
// packages/ui/src/index.ts
import { config } from '@mycompany/config';
// packages/config/src/index.ts
import { Component } from '@mycompany/ui';
Version Mismatches
Keep Sofondo versions consistent across all packages:
{
"dependencies": {
"@sofondo/core": "0.1.0",
"@sofondo/react": "0.1.0",
"@sofondo/styles": "0.1.0"
}
}
Next Steps
- Review Configuration Guide for advanced setup options
- See Best Practices for recommended patterns
- Check Real-World Examples for complete implementations