Frontend Modernization15 min read2026-01-28

Migrating to React Server Components: The Good, The Bad, and The ugly

We migrated a 50k LOC Next.js app to App Router. Here is what broke, what got faster, and why context providers are your new enemy.

QC
Sarah K. (Senior Frontend Dev)
Published 2026-01-28
#react#next.js#server components#frontend performance

Real Talk on React Server Components (RSC)

The docs make it look easy. "Just move files to /app". In reality, it involves rethinking your entire data flow.

1. The "Client Component" Trap You will find yourself putting `'use client'` at the top of everything initially. That's okay. **The Trap:** If you import a Server Component into a Client Component, it becomes a Client Component download. Even if it's just text.

2. Fetching Data **Old Way (useEffect):** ```javascript useEffect(() => { fetch('/api/user').then(d => setData(d)); }, []); ``` **RSC Way:** ```javascript // This runs on the server. No bundle size cost. const data = await db.query('SELECT * FROM users'); return <div>{data.name}</div> ``` This removal of the API layer for internal reads is the biggest win.

3. The Context Hell Context only works in Client Components. If your layout relies heavily on `<ThemeContext>` wrapping the whole app, you need to isolate it.

```javascript // providers.tsx (Client) 'use client' export function Providers({children}) { return <ThemeContext>{children}</ThemeContext> }

// layout.tsx (Server) export default function Layout({children}) { return ( <html> <body><Providers>{children}</Providers></body> </html> ) } ```

Final Verdict RSC is worth it for the 0KB bundle size on static content, but the learning curve is steeper than advertised.

Have a complex project?

Our engineering team is available for architectural reviews and custom software development.