Felipe Moacir

Remix vs Next.js: Quando o Nested Routing Faz Sentido

RemixNext.jsRouting
Remix vs Next.js: Quando o Nested Routing Faz Sentido

Remix e Next.js são ambos frameworks React fullstack. Mas a filosofia é completamente diferente.

Nested Routes: O Diferencial do Remix

No Remix, cada segmento da URL pode ter seu próprio loader, action, error boundary e layout.

/dashboard/projects/123

routes/
  dashboard.tsx          ← Layout + loader
    projects.tsx         ← Layout + loader
      $projectId.tsx     ← Loader do projeto específico

Cada nível carrega seus dados em paralelo, não em cascata.

Exemplo: Loader Hierarchy

// routes/dashboard.tsx
export async function loader() {
  return json({ user: await getUser() });
}

// routes/dashboard/projects.tsx
export async function loader() {
  return json({ projects: await getProjects() });
}

// routes/dashboard/projects/$id.tsx
export async function loader({ params }) {
  return json({ project: await getProject(params.id) });
}

Todos os 3 loaders executam simultaneamente. No Next.js, você teria:

// app/dashboard/projects/[id]/page.tsx
async function Page({ params }) {
  const user = await getUser();        // Cascata
  const projects = await getProjects(); // Cascata
  const project = await getProject(params.id);
  
  return <Layout user={user}>...</Layout>;
}

Isso é waterfall - cada await bloqueia o próximo.

Forms: HTML-First

Remix abraça o modelo de formulários do HTML. Sem useState, sem onSubmit.

export async function action({ request }) {
  const formData = await request.formData();
  const title = formData.get('title');
  
  await createProject({ title });
  return redirect('/dashboard/projects');
}

export default function NewProject() {
  return (
    <form method="post">
      <input name="title" />
      <button type="submit">Criar</button>
    </form>
  );
}

Se o JavaScript falhar, o formulário ainda funciona. Progressive enhancement.

Error Boundaries por Rota

Cada rota pode ter seu próprio boundary:

export function ErrorBoundary() {
  const error = useRouteError();
  return <div>Erro ao carregar projeto: {error.message}</div>;
}

Isso isola erros. Se /dashboard/projects/123 falha, o resto do dashboard continua funcionando.

Quando Usar Remix?

✅ Apps com muitas rotas aninhadas (dashboards, admin panels)
✅ Formulários complexos com validação server-side
✅ Progressive enhancement é prioridade

❌ Sites estáticos (use Astro)
❌ Precisa de ISR/Streaming do Next.js


Opinião: Remix tem o melhor modelo de roteamento para apps complexos. Next.js é melhor para sites de conteúdo com ISR.