React Router v7 brings powerful full-stack capabilities to React applications. While the default setup works great out of the box, there are a few tweaks I always make to create a cleaner, more organized project structure.
In this guide, I'll walk you through my preferred React Router v7 setup using Framework mode, including how to organize your code in a src
folder and customize the development server.
Creating Your React Router v7 Project
Let's start with the official template:
npx create-react-router@latest my-react-router-app
When prompted, I typically choose:
- Initialize a new git repository? → No (I prefer setting this up manually)
- Install dependencies with npm? → Yes
Why Use a src Folder Structure?
By default, React Router v7 places the app
folder at your project root. While this works fine, I prefer organizing everything inside a src
folder because it:
- Keeps the root clean - Configuration files stay at the top level while source code lives in
src
- Matches common React conventions - Most React developers expect to find components and app logic in
src
- Improves organization - Makes it easier to separate source code from build tools and config files
- Scales better - As your project grows, having a dedicated source folder prevents clutter
Moving to src Folder Structure
Here's how to reorganize your project:
cd my-react-router-app
mkdir src
mv app src/
Updating Configuration Files
After moving the app
folder, you need to update several configuration files to point to the new location.
1. Update react-router.config.ts
Tell React Router where to find your app directory:
import type { Config } from '@react-router/dev/config';
export default {
// Config options...
// Server-side render by default, to enable SPA mode set this to `false`
ssr: true,
appDirectory: './src/app',
} satisfies Config;
2. Update tsconfig.json
Update the TypeScript configuration to include the new src
structure:
{
"include": [
"src",
"**/*",
"**/.server/**/*",
"**/.client/**/*",
".react-router/types/**/*"
],
"compilerOptions": {
"lib": ["DOM", "DOM.Iterable", "ES2022"],
"types": ["node", "vite/client"],
"target": "ES2022",
"module": "ES2022",
"moduleResolution": "bundler",
"jsx": "react-jsx",
"rootDirs": [".", "./.react-router/types"],
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
},
"esModuleInterop": true,
"verbatimModuleSyntax": true,
"noEmit": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"strict": true
}
}
The key changes here are:
- Adding
"src"
to theinclude
array - Setting up path mapping with
"@/*": ["./src/*"]
for cleaner imports
3. Update vite.config.ts
The default development server runs on localhost:5173
, but I prefer the more common localhost:3000
. Here's how to change it in your vite.config.ts
:
import { reactRouter } from '@react-router/dev/vite';
import tailwindcss from '@tailwindcss/vite';
import { defineConfig } from 'vite';
import tsconfigPaths from 'vite-tsconfig-paths';
export default defineConfig({
plugins: [tailwindcss(), reactRouter(), tsconfigPaths()],
server: {
port: 3000,
},
});
Why port 3000? It's the conventional port for React development servers, and if you're coming from Create React App or Next.js, it feels more familiar.
Final Project Structure
After these changes, your project structure will look like this:
my-react-router-app/
├── src/
│ ├── app/
│ │ ├── routes/
│ │ ├── root.tsx
│ │ └── ...
│ ├── components/ (you'll add these)
│ ├── lib/ (you'll add these)
│ ├── utils/ (you'll add these)
│ └── hooks/ (you'll add these)
├── react-router.config.ts
├── vite.config.ts
├── tsconfig.json
└── package.json
Common Folders I Add Later
Depending on the project complexity, I typically add these folders inside src
:
components/
- Reusable UI componentslib/
- Third-party library configurations and utilitiesutils/
- Pure utility functionsservices/
- API calls and external service integrationshooks/
- Custom React hookstypes/
- TypeScript type definitions
Time-Saving Template
I've created a custom template with these configurations pre-applied, so I don't have to repeat these steps for every new project.
To use it:
git clone https://github.com/yourusername/react-router-v7-template.git my-new-project
cd my-new-project
npm install
You can also fork the official React Router starter and apply these changes yourself.
Wrapping Up
These small tweaks make React Router v7 projects feel more organized and familiar, especially if you're coming from other React frameworks. The src
folder structure keeps things tidy, and the port change makes the development experience more consistent with other React tools.