Sofondo
SofondoFrameworkDocs

Sofondo Framework - Migration Strategy

This document outlines various migration strategies for adopting the Sofondo Framework in your projects.

Table of Contents


Migration Scenarios

Scenario 1: New Project from Scratch

Best for: Starting fresh with the Sofondo Framework

Steps:

  1. Install dependencies
  2. Set up configuration
  3. Add providers
  4. Build your app using framework components

Estimated Time: 15-30 minutes

See New Project Setup


Scenario 2: Existing Next.js Project

Best for: Adding Sofondo to an existing Next.js application

Steps:

  1. Install framework packages
  2. Configure Next.js for framework packages
  3. Add providers to root layout
  4. 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:

  1. Install framework packages
  2. Set up navigation adapter
  3. Add providers
  4. 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:

  1. Clone or fork the monorepo
  2. Add your app to apps/ directory
  3. Use workspace protocol for dependencies
  4. Leverage shared configuration

Estimated Time: 30 minutes - 1 hour

See Monorepo Integration


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

Migrate components incrementally to minimize risk.

Week 1: Foundation

  1. Install framework packages
  2. Add configuration
  3. Set up providers
  4. 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:

  1. Back up your existing platform:
cp -r /c/Dev/sofondo-platform /c/Dev/sofondo-platform-backup
  1. Create apps directory in monorepo:
cd /c/Dev/sofondo-monorepo
mkdir -p apps
  1. Copy platform to monorepo:
cp -r /c/Dev/sofondo-platform apps/platform
  1. Update platform package.json:
{
  "name": "@sofondo/platform",
  "dependencies": {
    "@sofondo/core": "workspace:*",
    "@sofondo/react": "workspace:*",
    "@sofondo/styles": "workspace:*",
    "@sofondo/next": "workspace:*"
  }
}
  1. Update root package.json:
{
  "workspaces": [
    "packages/*",
    "apps/*"
  ]
}
  1. Update turbo.json:
{
  "tasks": {
    "dev": {
      "cache": false,
      "persistent": true,
      "dependsOn": ["^build"]
    }
  }
}
  1. 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 ComponentSofondo Component
HeaderBaseHeader / Header
SidebarBaseSidebar / Sidebar
TableDataGrid
LoadingSkeleton
NotificationToast
ProgressProgressBar
Stats CardStatCard
Page TitlePageHeader

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:

  1. Check transpilePackages in next.config.ts
  2. Restart dev server after config changes
  3. Clear .next cache: rm -rf .next
  4. Reinstall dependencies: rm -rf node_modules && npm install

Issue: Styles Not Applied

Problem: Components render but look unstyled

Solutions:

  1. Import global styles: import '@sofondo/styles/global.css'
  2. Check import order (global styles should be early)
  3. Check for CSS conflicts with existing styles
  4. Verify @sofondo/styles is installed

Issue: TypeScript Errors

Problem:

Type 'MenuItem[]' is not assignable...

Solutions:

  1. Import types: import type { MenuItem } from '@sofondo/core'
  2. Check type versions match
  3. Restart TypeScript server in IDE
  4. Clear TypeScript cache

Issue: Hooks Error

Problem:

useConfig must be used within a ConfigProvider

Solutions:

  1. Wrap app with <ConfigProvider>
  2. Check provider order (ConfigProvider should be outermost)
  3. Verify you’re using hooks inside the provider tree

Issue: Build Fails in Production

Problem: Dev works, production build fails

Solutions:

  1. See Build System Notes
  2. Consider publishing to npm/GitHub packages
  3. Use yalc for local testing
  4. 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:

The framework is designed to be adopted incrementally. Start small, prove value, then expand usage.