Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

rr-next-routes

vniehues5.3kMIT0.0.9TypeScript support: included

generate nextjs-style routes in your react-router-v7 application

better, routes, react-router, nextjs, directory, based, routing

readme

<picture> <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/vniehues/rr-next-routes/main/assets/rr-next-routes-dark.svg"> rr-next-routes logo </picture>

rr-next-routes

NPM version License

Features

rr-next-routes is a utility library for generating Next.js-style routes for your React Router v7 or Remix applications.
It provides a directory-based routing solution for React applications, similar to Next.js, and supports features like layouts, route parameters, and dynamic routing with nested route management.

<summary>Motivation</summary>
I really enjoy using file-based (directory-based) routing when working with next.js

While there are different solutions like generouted, most of them require you to modify multiple files and some even bring their own routing.
rr-next-routes is a simple drop in solution for project using remix or react-router v7 in framework mode.
you can even still use the manual routing to add more routes to your liking while rr-next-routes takes care of the pages dir:

routes.ts

import {route, type RouteConfig} from "@react-router/dev/routes";
import {nextRoutes, appRouterStyle} from "rr-next-routes/react-router";
//import {nextRoutes, appRouterStyle} from "rr-next-routes/remix";

const autoRoutes = nextRoutes({
    ...appRouterStyle,
    print: "tree",
});

export default [
    ...autoRoutes,
    route("some/path", "./some/file.tsx"),
] satisfies RouteConfig;

Features

Keep using React Router v7 in framework mode and still get:

  • Generate route configurations from a file-based structure.
  • Supports for (nested) layouts
  • Handles dynamic routes, optional parameters, and catch-all routes ([param].tsx, [[param]].tsx, [...param].tsx).
  • Compatible with React Router v7 (framework mode) and Remix routing systems.
  • Predefined configurations to suit both app-router and page-router patterns.
  • Flexible configuration system.
  • Configurable printing options: info, table, or tree to console log the generation results

Installation

You can install the library using npm:

npm install rr-next-routes

Usage

Example

Here’s a sample usage of rr-next-routes for generating route configurations:

routes.ts

import { type RouteConfig } from "@react-router/dev/routes";
import {nextRoutes, appRouterStyle} from "rr-next-routes/react-router";
// for remix use this instead
// import {nextRoutes, appRouterStyle} from "rr-next-routes/remix";

const routes = nextRoutes({ print: "info" });

export default routes satisfies RouteConfig;

Configuration Options

The nextRoutes function accepts an optional configuration object of type Options:

Options Type

type PrintOption = "no" | "info" | "table" | "tree";

type Options = {
    folderName?: string;       // Folder to scan for routes (default: "pages").
    print?: PrintOption;       // Controls printing output (default: "info").
    layoutFileName?: string;   // Name of layout files (default: "_layout").
    routeFileNames?: string[]; // Names for route files (e.g., ["page", "index"]).
    routeFileNameOnly?: boolean; // Restrict routes to matching routeFileNames.
    extensions?: string[];     // File extensions to process (e.g., [".tsx", ".ts"]).
};

Predefined Styles

1. appRouterStyle (default)

Best for projects following the Next.js app-router convention:

export const appRouterStyle: Options = {
    folderName: "",
    print: "info",
    layoutFileName: "layout",
    routeFileNames: ["page", "route"],
    extensions: [".tsx", ".ts", ".jsx", ".js"],
    routeFileNameOnly: true,
};

2. pageRouterStyle

Best for projects following the Next.js pages-router convention:

export const pageRouterStyle: Options = {
    folderName: "pages",
    print: "info",
    layoutFileName: "_layout",
    routeFileNames: ["index"],
    extensions: [".tsx", ".ts", ".jsx", ".js"],
    routeFileNameOnly: false,
};

Example Configurations

Default Configuration:

const routes = nextRoutes(); // Uses default options (appRouterStyle).

Using Pages Router:

const routes = nextRoutes(pageRouterStyle);

Custom App Router:

const routes = nextRoutes({
    ...appRouterStyle,
    print: "tree",
    layoutFileName: "_customLayout",
});

Example File Structure (pageRouterStyle)

app/
├── pages/
│   ├── index.tsx
│   ├── about.tsx
│   ├── dashboard/
│   │   ├── _layout.tsx
│   │   ├── index.tsx
│   │   ├── settings.tsx
│   ├── profile/
│   │   ├── name.tsx
│   │   ├── email.tsx
│   │   ├── password.tsx

Generated Routes

The above structure will result in the following routes:

  • /pages/index.tsx
  • /aboutpages/about.tsx
  • /dashboardpages/dashboard/index.tsx (wrapped by layout: pages/dashboard/_layout.tsx)
  • /dashboard/settingspages/dashboard/settings.tsx (wrapped by layout: pages/dashboard/_layout.tsx)
  • /profile/namepages/profile/name.tsx
  • /profile/emailpages/profile/email.tsx
  • /profile/passwordpages/profile/password.tsx

Dynamic Routes

The library supports Next.js-style dynamic and optional routes:

Example

File Structure

app/
├── pages/
│   ├── [id].tsx
│   ├── [[optional]].tsx
│   ├── [...all].tsx

Generated Routes

  • /:idpages/[id].tsx
  • /:optional?pages/[[optional]].tsx
  • /*pages/[...all].tsx

These routes are created using a special character mapping:

File Name Route Path
[id].tsx /:id
[[optional]].tsx /:optional?
[...all].tsx /*

Testing

This project uses Vitest for testing. To run the tests:

npm test

Development

The project supports ES modules and is built using tsup.

Build

To build the project:

npm run build

Watch (Test in Development Mode)

npm run dev