Creating a project
A framework mode project is created from the official template. It sets up Vite (the bundler and dev server), TypeScript and server rendering, so you can open the first page within a minute.
Creating
npx create-react-router@latest blog
cd blog
npm run devThe wizard asks whether to create a Git repository and install dependencies — answer yes. npm run dev starts the dev server, and the site opens at http://localhost:5173. You will see the template's welcome page.
Project structure
blog/
├── app/
│ ├── routes/
│ │ └── home.tsx the "/" page
│ ├── welcome/ welcome component (can be deleted)
│ ├── app.css global styles
│ ├── root.tsx root module: the HTML shell
│ └── routes.ts the list of routes
├── public/ static files: favicon, images
├── react-router.config.ts framework settings
├── vite.config.ts Vite settings
├── tsconfig.json
└── package.jsonAll your code lives in app/. After the first run a hidden .react-router/ folder with generated types appears — you do not edit it or add it to Git.
The root module
app/root.tsx describes the HTML shared by all pages. Its main part:
// app/root.tsx
import { Links, Meta, Outlet, Scripts, ScrollRestoration } from "react-router";
import "./app.css";
export function Layout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<Meta />
<Links />
</head>
<body>
{children}
<ScrollRestoration />
<Scripts />
</body>
</html>
);
}
export default function App() {
return <Outlet />;
}Meta and Links output the title and stylesheet tags of pages, Scripts loads JavaScript, ScrollRestoration restores the scroll position on navigation. The current page appears in place of Outlet.
Scripts
| Command | What it does |
|---|---|
npm run dev | Dev server with live reload |
npm run build | Production build into build/ |
npm start | Runs the built app |
npm run typecheck | Generates types and runs TypeScript checks |
Common mistake
If you delete <Scripts /> from app/root.tsx (say, while "cleaning up" the file), pages look fine but do not react to clicks: the HTML came from the server, but JavaScript never loaded. Meta, Links, ScrollRestoration and Scripts must stay in the root module.