#15456·react-router

Adding one export re-typechecks every route

Author: Junk-debugCreated Aug 31, 2026Updated Aug 31, 2026
Labelsbugfeat:typescriptpkg:@react-router/dev

Reproduction

https://github.com/Junk-debug/react-router-routemodules-repro

git clone https://github.com/Junk-debug/react-router-routemodules-repro
cd react-router-routemodules-repro
npm install && node bench.mjs

The script typechecks the project twice with the same edits

  1. without any changes in tsconfig
  2. with .react-router/types/+routes.ts excluded from tsconfig

and prints the results.

Because execution time is different on every machine, I recommend looking at the "largest SCC" row, it shows the biggest group of files that all depend on each other, directly or through other files.

Did not use the integration test template since this isn't a runtime bug, only type check

System Info

System:
    OS: macOS 15.7.7
    CPU: (11) arm64 Apple M3 Pro
    Memory: 97.23 MB / 18.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 22.22.3 - /Users/user/.nvm/versions/node/v22.22.3/bin/node
    Yarn: 1.22.22 - /Users/user/.nvm/versions/node/v22.22.3/bin/yarn
    npm: 10.9.8 - /Users/user/.nvm/versions/node/v22.22.3/bin/npm
    pnpm: 11.15.1 - /Users/user/.nvm/versions/node/v22.22.3/bin/pnpm
    bun: 1.2.23 - /Users/user/.bun/bin/bun
  Browsers:
    Chrome: 151.0.7922.175
    Safari: 26.5
  npmPackages:
    @react-router/dev: ^8 => 8.3.1 
    @react-router/node: ^8 => 8.3.1 
    @react-router/serve: ^8 => 8.3.1 
    react-router: ^8 => 8.3.1 
    vite: ^8.0.3 => 8.2.2

Used Package Manager

npm

Expected Behavior

Editing a file should only re-typecheck the files that actually depend on it

Actual Behavior

Adding a single export to a leaf module used by just 2 out of 300 routes causes TypeScript to re-check 458 of 913 files, increasing check time from 0.08s to 0.79s.

The problem seems to come from +routes.ts. It imports every route through routeModules and also augments the react-router module. As a result, anything that imports react-router ends up transitively depending on every route, so TypeScript can't check them independently

NOTE: You won’t see this with noEmit, which is what create-react-router uses by default. Without declaration emit, incremental compilation doesn’t make a difference here. The repro uses emitDeclarationOnly to make the issue visible

This is a minimal reproduction, so the numbers are quite small, but on our project it takes up to ~90s to run typechecks even if only one file has changed