> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/remix-run/react-router/llms.txt
> Use this file to discover all available pages before exploring further.

# Picking a Mode

> Choose between Declarative, Data, and Framework modes for React Router

# Picking a Mode

React Router is a multi-strategy router for React. There are three primary ways, or "modes", to use it in your app. The features available in each mode are additive, so moving from Declarative to Data to Framework simply adds more features at the cost of architectural control.

<Note>
  Pick your mode based on how much control or how much help you want from React Router.
</Note>

## The Three Modes

The mode depends on which "top level" router API you're using:

<Tabs>
  <Tab title="Declarative">
    Enables basic routing features like matching URLs to components, navigating around the app, and providing active states.

    ```tsx theme={null}
    import { BrowserRouter } from "react-router";

    ReactDOM.createRoot(root).render(
      <BrowserRouter>
        <App />
      </BrowserRouter>
    );
    ```
  </Tab>

  <Tab title="Data">
    Adds data loading, actions, pending states and more by moving route configuration outside of React rendering.

    ```tsx theme={null}
    import { createBrowserRouter, RouterProvider } from "react-router";

    let router = createBrowserRouter([
      {
        path: "/",
        Component: Root,
        loader: loadRootData,
      },
    ]);

    ReactDOM.createRoot(root).render(
      <RouterProvider router={router} />
    );
    ```
  </Tab>

  <Tab title="Framework">
    Wraps Data Mode with a Vite plugin for the full React Router experience with type-safe routing, intelligent code splitting, and SSR/SPA/SSG strategies.

    ```ts filename="routes.ts" theme={null}
    import { index, route } from "@react-router/dev/routes";

    export default [
      index("./home.tsx"),
      route("products/:pid", "./product.tsx"),
    ];
    ```
  </Tab>
</Tabs>

## Mode Comparison

| Feature               | Declarative | Data   | Framework |
| --------------------- | ----------- | ------ | --------- |
| URL Matching          | ✅           | ✅      | ✅         |
| Navigation            | ✅           | ✅      | ✅         |
| Active States         | ✅           | ✅      | ✅         |
| Data Loading          | ❌           | ✅      | ✅         |
| Actions               | ❌           | ✅      | ✅         |
| Pending States        | ❌           | ✅      | ✅         |
| Type Safety           | ❌           | ❌      | ✅         |
| Code Splitting        | ❌           | ❌      | ✅         |
| SSR/SSG               | Manual      | Manual | Built-in  |
| Setup Complexity      | Low         | Medium | Higher    |
| Architectural Control | Full        | High   | Medium    |

## Decision Guide

Every mode supports any architecture and deployment target, so the question isn't really about if you want SSR, SPA, etc. It's about how much you want to do yourself.

<Steps>
  ### Choose Framework Mode if you:

  * Are too new to have an opinion
  * Are considering Next.js, Solid Start, SvelteKit, Astro, TanStack Start, etc. and want to compare
  * Just want to build something with React
  * Might want to server render, might not
  * Are coming from Remix (React Router v7 is the "next version" after Remix v2)
  * Are migrating from Next.js

  [→ Get Started with Framework Mode](/getting-started/framework-mode)

  ### Choose Data Mode if you:

  * Want data features but also want to have control over bundling, data, and server abstractions
  * Started a data router in v6.4 and are happy with it
  * Have your own build setup and don't want to add a Vite plugin

  [→ Get Started with Data Mode](/getting-started/data-mode)

  ### Choose Declarative Mode if you:

  * Want to use React Router as simply as possible
  * Are coming from v6 and are happy with `<BrowserRouter>`
  * Have a data layer that either skips pending states (like local first, background data replication/sync) or has its own abstractions for them
  * Are coming from Create React App (you may want to consider framework mode though)

  [→ Get Started with Declarative Mode](/getting-started/declarative-mode)
</Steps>

## Examples By Mode

<CodeGroup>
  ```tsx Declarative theme={null}
  import { BrowserRouter, Routes, Route, Link } from "react-router";

  function App() {
    return (
      <BrowserRouter>
        <nav>
          <Link to="/">Home</Link>
          <Link to="/about">About</Link>
        </nav>
        <Routes>
          <Route index element={<Home />} />
          <Route path="about" element={<About />} />
        </Routes>
      </BrowserRouter>
    );
  }
  ```

  ```tsx Data theme={null}
  import { createBrowserRouter, RouterProvider, Link } from "react-router";

  const router = createBrowserRouter([
    {
      path: "/",
      Component: Root,
      children: [
        {
          index: true,
          loader: async () => ({ message: "Hello" }),
          Component: Home,
        },
        { path: "about", Component: About },
      ],
    },
  ]);

  function App() {
    return <RouterProvider router={router} />;
  }
  ```

  ```tsx Framework theme={null}
  // routes.ts
  import { index, route } from "@react-router/dev/routes";

  export default [
    index("./home.tsx"),
    route("about", "./about.tsx"),
  ];

  // home.tsx
  import type { Route } from "./+types/home";

  export async function loader() {
    return { message: "Hello" };
  }

  export default function Home({ loaderData }: Route.ComponentProps) {
    return <h1>{loaderData.message}</h1>;
  }
  ```
</CodeGroup>

## Can I Switch Modes Later?

Yes! The modes are designed to be upgrade paths:

<Steps>
  ### Declarative → Data

  Replace `<BrowserRouter>` with `createBrowserRouter` and `<RouterProvider>`. You can migrate routes incrementally by adding loaders and actions.

  ### Data → Framework

  Add the Vite plugin and move your route configuration to `routes.ts`. You get instant type safety and code splitting.

  ### Framework → Data

  Remove the Vite plugin and convert your route modules to plain route objects. You keep all the data loading features.
</Steps>

<Note>
  Start simple and upgrade as your needs grow. Each mode builds on the previous one.
</Note>
