DEV Community

Alex Spinov
Alex Spinov

Posted on

Remix Has a Free React Framework Built for the Modern Web

Remix is a full-stack web framework built on React that focuses on web standards and modern UX patterns. It is completely free, open source, and now part of the React Router project. If you want a React framework that embraces the platform instead of fighting it, Remix is worth exploring.

What Makes Remix Different?

Remix takes a fundamentally different approach from other React frameworks. Instead of inventing new patterns, it leans on web standards — HTML forms, HTTP caching, URL-based routing, and progressive enhancement. The result is applications that are fast by default and work even when JavaScript fails.

Since merging with React Router v7, Remix has become even more powerful, combining the best routing library in the React ecosystem with full-stack capabilities.

Quick Setup

Getting started takes one command:

npx create-remix@latest my-remix-app
cd my-remix-app
npm run dev
Enter fullscreen mode Exit fullscreen mode

You will have a running application with server-side rendering, file-based routing, and hot module replacement.

Nested Routes — The Killer Feature

Remix uses nested routes, which means your UI hierarchy mirrors your URL hierarchy. Each route segment owns its data, errors, and loading states:

app/
  routes/
    _index.tsx          → /
    dashboard.tsx       → /dashboard (layout)
    dashboard._index.tsx → /dashboard
    dashboard.settings.tsx → /dashboard/settings
    dashboard.profile.tsx  → /dashboard/profile
Enter fullscreen mode Exit fullscreen mode

The dashboard.tsx file acts as a layout that wraps all child routes:

// app/routes/dashboard.tsx
import { Outlet, NavLink } from "@remix-run/react";

export default function DashboardLayout() {
  return (
    <div className="dashboard">
      <nav>
        <NavLink to="/dashboard">Overview</NavLink>
        <NavLink to="/dashboard/settings">Settings</NavLink>
        <NavLink to="/dashboard/profile">Profile</NavLink>
      </nav>
      <main>
        <Outlet />
      </main>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

When a user navigates between child routes, only the changed section re-renders. The layout stays stable.

Server-Side Data Loading

Every route can export a loader function that runs on the server:

// app/routes/dashboard._index.tsx
import { json } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";

export async function loader({ request }) {
  const user = await getUser(request);
  const stats = await getDashboardStats(user.id);

  return json({
    user,
    stats,
    lastUpdated: new Date().toISOString()
  });
}

export default function Dashboard() {
  const { user, stats, lastUpdated } = useLoaderData<typeof loader>();

  return (
    <div>
      <h1>Welcome back, {user.name}</h1>
      <div className="stats-grid">
        <StatCard title="Revenue" value={stats.revenue} />
        <StatCard title="Users" value={stats.users} />
        <StatCard title="Orders" value={stats.orders} />
      </div>
      <p>Last updated: {lastUpdated}</p>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Remix automatically handles loading states, race conditions, and data revalidation.

Form Handling with Actions

Remix uses standard HTML forms for mutations, enhanced with JavaScript when available:

// app/routes/dashboard.settings.tsx
import { json, redirect } from "@remix-run/node";
import { Form, useActionData } from "@remix-run/react";

export async function action({ request }) {
  const formData = await request.formData();
  const name = formData.get("name");
  const email = formData.get("email");

  const errors = {};
  if (!name) errors.name = "Name is required";
  if (!email) errors.email = "Email is required";

  if (Object.keys(errors).length > 0) {
    return json({ errors }, { status: 400 });
  }

  await updateUserSettings({ name, email });
  return redirect("/dashboard");
}

export default function Settings() {
  const actionData = useActionData<typeof action>();

  return (
    <Form method="post">
      <div>
        <label>Name</label>
        <input name="name" type="text" />
        {actionData?.errors?.name && <span>{actionData.errors.name}</span>}
      </div>
      <div>
        <label>Email</label>
        <input name="email" type="email" />
        {actionData?.errors?.email && <span>{actionData.errors.email}</span>}
      </div>
      <button type="submit">Save Settings</button>
    </Form>
  );
}
Enter fullscreen mode Exit fullscreen mode

This form works without JavaScript. When JS is available, Remix intercepts the submission and handles it client-side with pending states and optimistic UI.

Error Boundaries Per Route

Each route can define its own error boundary, so a crash in one section does not take down the entire page:

export function ErrorBoundary() {
  const error = useRouteError();

  if (isRouteErrorResponse(error)) {
    return (
      <div className="error">
        <h2>{error.status} {error.statusText}</h2>
        <p>{error.data}</p>
      </div>
    );
  }

  return (
    <div className="error">
      <h2>Something went wrong</h2>
      <p>Please try refreshing the page.</p>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Built-in HTTP Caching

Remix makes HTTP caching a first-class concern. Add cache headers to any loader:

export async function loader() {
  const data = await getPublicData();

  return json(data, {
    headers: {
      "Cache-Control": "public, max-age=300, s-maxage=3600"
    }
  });
}
Enter fullscreen mode Exit fullscreen mode

This works with CDNs out of the box. No special configuration needed.

Why Remix Over Next.js?

Web standards first. Remix uses the Web Fetch API, FormData, and standard HTTP — skills that transfer to any platform.

Better error handling. Nested error boundaries mean partial failures, not full-page crashes.

Simpler data flow. Loader runs on server, component renders data. No useEffect for data fetching.

Progressive enhancement. Your app works without JavaScript and gets better with it.

Conclusion

Remix gives you a production-ready React framework with server rendering, data loading, form handling, and error boundaries — all built on web standards. It is free, open source, and actively maintained as part of React Router v7.


💡 Need web scraping or data extraction? Check out my Apify actors or email me at spinov001@gmail.com for custom solutions!

Top comments (0)