Sofondo Framework - Migration Strategy
This document outlines various migration strategies for adopting the Sofondo Framework in your projects.
Table of Contents
- Migration Scenarios
- New Project Setup
- Migrating Existing Projects
- Monorepo Integration
- Component Migration
- Common Patterns
- Troubleshooting
Migration Scenarios
Scenario 1: New Project from Scratch
Best for: Starting fresh with the Sofondo Framework
Steps:
- Install dependencies
- Set up configuration
- Add providers
- Build your app using framework components
Estimated Time: 15-30 minutes
Scenario 2: Existing Next.js Project
Best for: Adding Sofondo to an existing Next.js application
Steps:
- Install framework packages
- Configure Next.js for framework packages
- Add providers to root layout
- Gradually migrate components
Estimated Time: 1-2 hours
See Migrating Existing Projects
Scenario 3: Existing React Project
Best for: Non-Next.js React applications
Steps:
- Install framework packages
- Set up navigation adapter
- Add providers
- Use base components with custom adapter
Estimated Time: 2-4 hours
Scenario 4: Monorepo Integration
Best for: Projects already using monorepos or wanting to contribute to the framework
Steps:
- Clone or fork the monorepo
- Add your app to
apps/directory - Use workspace protocol for dependencies
- Leverage shared configuration
Estimated Time: 30 minutes - 1 hour
New Project Setup
Prerequisites
- Node.js 18+ installed
- Package manager (npm, yarn, or pnpm)
- Next.js 15+ (recommended) or React 18+
Step 1: Create Next.js Project
npx create-next-app@latest my-admin-panel
cd my-admin-panel
Recommended options:
- TypeScript: Yes
- ESLint: Yes
- Tailwind CSS: No (framework includes styles)
- App Router: Yes
- Import alias: @/* (or your preference)
Step 2: Install Framework Packages
npm install @sofondo/core @sofondo/react @sofondo/styles @sofondo/next
Optional dependencies:
npm install framer-motion lucide-react clsx
Step 3: Configure Next.js
Update next.config.ts:
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
transpilePackages: [
'@sofondo/core',
'@sofondo/react',
'@sofondo/styles',
'@sofondo/next'
],
};
export default nextConfig;
Step 4: Create Configuration File
Create sofondo.config.ts:
import { defineConfig } from '@sofondo/core';
export default defineConfig({
theme: {
defaultMode: 'system',
enableSwitcher: true,
},
sidebar: {
defaultCollapsed: false,
width: 240,
},
animations: {
enabled: true,
},
});
Step 5: Set Up Providers
Update app/layout.tsx:
import { ConfigProvider, ThemeProvider, ToastProvider } from '@sofondo/react';
import config from '../sofondo.config';
import '@sofondo/styles/global.css';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
<ConfigProvider config={config}>
<ThemeProvider>
<ToastProvider>
{children}
</ToastProvider>
</ThemeProvider>
</ConfigProvider>
</body>
</html>
);
}
Step 6: Create Admin Layout
Create app/(admin)/layout.tsx:
import { AdminLayout } from '@sofondo/next';
import { Home, Settings, Users } from 'lucide-react';
const menuItems = [
{ icon: Home, label: 'Dashboard', href: '/', exact: true },
{ icon: Users, label: 'Users', href: '/users' },
{ icon: Settings, label: 'Settings', href: '/settings' },
];
export default function AdminLayoutWrapper({
children,
}: {
children: React.ReactNode;
}) {
return (
<AdminLayout
menuItems={menuItems}
user={{
name: 'John Doe',
email: 'john@example.com',
}}
>
{children}
</AdminLayout>
);
}
Step 7: Create Your First Page
Create app/(admin)/page.tsx:
import { PageHeader, StatCard, StatGrid } from '@sofondo/react';
import { Users, Activity, DollarSign } from 'lucide-react';
export default function Dashboard() {
return (
<>
<PageHeader
title="Dashboard"
subtitle="Welcome to your admin panel"
/>
<StatGrid>
<StatCard
icon={Users}
label="Total Users"
value="1,234"
change="+12% this month"
changeClassName="positive"
/>
<StatCard
icon={Activity}
label="Active Sessions"
value="89"
change="Live"
changeClassName="positive"
/>
<StatCard
icon={DollarSign}
label="Revenue"
value="$12,345"
change="+8% this month"
changeClassName="positive"
/>
</StatGrid>
</>
);
}
Step 8: Run Your App
npm run dev
Visit http://localhost:3000 to see your admin panel!
Migrating Existing Projects
Assessment Phase
Before migrating, assess your project:
Checklist:
- What framework are you using? (Next.js, React, etc.)
- Do you have existing UI components to replace?
- What’s your current state management solution?
- Do you have existing navigation/routing?
- What’s your current styling approach?
Migration Strategies
Strategy 1: Gradual Migration (Recommended)
Migrate components incrementally to minimize risk.
Week 1: Foundation
- Install framework packages
- Add configuration
- Set up providers
- Keep existing components
Week 2: Layout Migration 5. Replace header with framework header 6. Replace sidebar with framework sidebar 7. Test navigation
Week 3: Component Migration 8. Replace data tables with DataGrid 9. Replace loading states with Skeleton 10. Add toast notifications
Week 4: Polish 11. Add animations 12. Customize theme 13. Remove old code
Strategy 2: Feature Branch Migration
Create a feature branch and migrate everything at once.
Pros:
- Clean break from old code
- Easier to test as a whole
- Can compare old vs new
Cons:
- Longer branch lifetime
- More merge conflicts
- Harder to rollback partially
Strategy 3: New Route Migration
Migrate new features first, keep existing routes unchanged.
Best for:
- Large applications
- Risk-averse teams
- Continuous delivery environments
Existing Next.js Project Migration
1. Install Dependencies
npm install @sofondo/core @sofondo/react @sofondo/styles @sofondo/next
2. Update Next.js Config
Add transpilePackages to next.config.ts (see New Project Setup).
3. Import Global Styles
In your root layout, import framework styles:
import '@sofondo/styles/global.css';
Note: This may conflict with existing global styles. You may need to:
- Remove conflicting CSS
- Adjust CSS specificity
- Use CSS modules for isolation
4. Wrap with Providers
Add framework providers around your existing app structure:
// app/layout.tsx
import { ConfigProvider, ThemeProvider } from '@sofondo/react';
import config from '../sofondo.config';
import '@sofondo/styles/global.css';
export default function RootLayout({ children }) {
return (
<html>
<body>
<ConfigProvider config={config}>
<ThemeProvider>
{/* Your existing app structure */}
{children}
</ThemeProvider>
</ConfigProvider>
</body>
</html>
);
}
5. Create Parallel Routes
Use Next.js route groups to create parallel admin and public routes:
app/
├── (admin)/
│ ├── layout.tsx (AdminLayout)
│ └── dashboard/
│ └── page.tsx
├── (public)/
│ ├── layout.tsx (Your existing layout)
│ └── page.tsx
└── layout.tsx (Root with providers)
6. Migrate Components Gradually
Replace components one at a time:
Before:
<MyCustomTable data={data} columns={columns} />
After:
import { DataGrid } from '@sofondo/react';
<DataGrid data={data} columns={columns} keyField="id" />
Monorepo Integration
Option 1: Move Platform to Monorepo
Move your existing platform into the Sofondo monorepo as an example app.
Benefits:
- No symlink/build issues
- Faster development
- Shared configuration
- Direct framework changes
Structure:
sofondo-monorepo/
├── packages/
│ ├── core/
│ ├── react/
│ └── styles/
├── apps/
│ ├── platform/ (your app here)
│ └── docs/
└── package.json
Steps:
- Back up your existing platform:
cp -r /c/Dev/sofondo-platform /c/Dev/sofondo-platform-backup
- Create apps directory in monorepo:
cd /c/Dev/sofondo-monorepo
mkdir -p apps
- Copy platform to monorepo:
cp -r /c/Dev/sofondo-platform apps/platform
- Update platform package.json:
{
"name": "@sofondo/platform",
"dependencies": {
"@sofondo/core": "workspace:*",
"@sofondo/react": "workspace:*",
"@sofondo/styles": "workspace:*",
"@sofondo/next": "workspace:*"
}
}
- Update root package.json:
{
"workspaces": [
"packages/*",
"apps/*"
]
}
- Update turbo.json:
{
"tasks": {
"dev": {
"cache": false,
"persistent": true,
"dependsOn": ["^build"]
}
}
}
- Install and test:
npm install
cd apps/platform
npm run dev
Option 2: Keep Platform Separate
Keep your platform as a separate repository and use published packages.
When to use:
- Platform is in a separate organization
- Need independent deployment
- Different team ownership
- Want to use versioned releases
See: Build System Notes for publishing strategies.
Component Migration
Common Component Mappings
| Your Component | Sofondo Component |
|---|---|
| Header | BaseHeader / Header |
| Sidebar | BaseSidebar / Sidebar |
| Table | DataGrid |
| Loading | Skeleton |
| Notification | Toast |
| Progress | ProgressBar |
| Stats Card | StatCard |
| Page Title | PageHeader |
Migration Patterns
Pattern 1: Direct Replacement
Before:
<MyTable data={users} />
After:
import { DataGrid } from '@sofondo/react';
<DataGrid
data={users}
keyField="id"
columns={[
{ key: 'name', header: 'Name' },
{ key: 'email', header: 'Email' },
]}
/>
Pattern 2: Wrapper Component
Keep your API, wrap framework component:
// components/MyTable.tsx
import { DataGrid } from '@sofondo/react';
export function MyTable({ data }) {
return (
<DataGrid
data={data}
keyField="id"
columns={[
{ key: 'name', header: 'Name' },
{ key: 'email', header: 'Email' },
]}
/>
);
}
Pattern 3: Gradual Props Migration
Migrate props incrementally:
// Stage 1: Keep existing props, map internally
export function MyButton({ label, ...props }) {
return <Button {...props}>{label}</Button>;
}
// Stage 2: Update all call sites to use children
// Then remove wrapper
State Management Migration
The framework doesn’t impose state management. Keep your existing solution:
Redux:
<ConfigProvider>
<Provider store={store}>
<ThemeProvider>
<App />
</ThemeProvider>
</Provider>
</ConfigProvider>
Zustand:
<ConfigProvider>
<ThemeProvider>
<App /> {/* Zustand hooks work anywhere */}
</ThemeProvider>
</ConfigProvider>
Common Patterns
Pattern: Adding Toast Notifications
Old code:
alert('Settings saved!');
New code:
import { useToast } from '@sofondo/react';
function Settings() {
const { addToast } = useToast();
const handleSave = () => {
// Save logic...
addToast('Settings saved!', 'success');
};
return <button onClick={handleSave}>Save</button>;
}
Pattern: Adding Loading States
Old code:
{loading ? <div>Loading...</div> : <Table data={data} />}
New code:
import { Skeleton, DataGrid } from '@sofondo/react';
{loading ? (
<>
<Skeleton width="100%" height={40} />
<Skeleton width="100%" height={40} />
<Skeleton width="100%" height={40} />
</>
) : (
<DataGrid data={data} columns={columns} keyField="id" />
)}
Pattern: Adding Progress Indicators
Old code:
<div style={{ width: `${percentage}%` }} />
New code:
import { ProgressBar, getStorageStatus, getStorageColor } from '@sofondo/react';
const status = getStorageStatus(used, total);
const color = getStorageColor(status);
<ProgressBar value={used} max={total} color={color} />
Pattern: Customizing Theme
Add custom colors to config:
export default defineConfig({
theme: {
colors: {
light: {
'--primary': '#0066cc',
'--background': '#ffffff',
},
dark: {
'--primary': '#3399ff',
'--background': '#0a0a0a',
},
},
},
});
Troubleshooting
Issue: Module Not Found
Problem:
Module not found: Can't resolve '@sofondo/core'
Solutions:
- Check
transpilePackagesinnext.config.ts - Restart dev server after config changes
- Clear
.nextcache:rm -rf .next - Reinstall dependencies:
rm -rf node_modules && npm install
Issue: Styles Not Applied
Problem: Components render but look unstyled
Solutions:
- Import global styles:
import '@sofondo/styles/global.css' - Check import order (global styles should be early)
- Check for CSS conflicts with existing styles
- Verify
@sofondo/stylesis installed
Issue: TypeScript Errors
Problem:
Type 'MenuItem[]' is not assignable...
Solutions:
- Import types:
import type { MenuItem } from '@sofondo/core' - Check type versions match
- Restart TypeScript server in IDE
- Clear TypeScript cache
Issue: Hooks Error
Problem:
useConfig must be used within a ConfigProvider
Solutions:
- Wrap app with
<ConfigProvider> - Check provider order (ConfigProvider should be outermost)
- Verify you’re using hooks inside the provider tree
Issue: Build Fails in Production
Problem: Dev works, production build fails
Solutions:
- See Build System Notes
- Consider publishing to npm/GitHub packages
- Use yalc for local testing
- Move to monorepo structure
Migration Checklist
Use this checklist to track your migration progress:
Setup
- Install framework packages
- Configure Next.js/bundler
- Create configuration file
- Add providers to root
- Import global styles
Layout
- Migrate header
- Migrate sidebar
- Set up navigation
- Add menu items
- Test routing
Components
- Replace data tables
- Add loading skeletons
- Implement toasts
- Add progress bars
- Migrate stat cards
Features
- Set up theme switching
- Configure animations
- Test accessibility
- Add keyboard navigation
- Test mobile responsiveness
Polish
- Customize theme colors
- Adjust configuration
- Remove old code
- Update documentation
- Train team
Production
- Test production build
- Performance audit
- Accessibility audit
- Browser testing
- Deploy
Getting Help
Resources
Common Questions
Q: Can I use with existing CSS frameworks? A: Yes, but there may be conflicts. The framework’s CSS is scoped to avoid most issues.
Q: Do I need to use all components? A: No, use what you need. The framework is modular.
Q: Can I customize everything? A: Yes, via configuration, props, or by wrapping components.
Q: Is TypeScript required? A: Recommended but not required. The framework works with JavaScript.
Q: What about SSR/SSG? A: Fully supported. Components are designed for Next.js App Router.
Summary
Choose your migration path based on your situation:
- New project: Follow New Project Setup (~30 min)
- Existing project: Use Gradual Migration (~4 weeks)
- Monorepo: Consider moving to monorepo (~1 hour)
- Risk-averse: Try parallel routes first
The framework is designed to be adopted incrementally. Start small, prove value, then expand usage.