Declarative routing for React
This report summarizes scanner evidence for remix-run/react-router, a TypeScript project with 56,626 GitHub stars. SynthScan examined 295,821 lines of code across 1128 source files, recording 241 pattern matches distributed across 8 syntactic categories. The legacy adjusted pattern signal is 0.9 (Low pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Payload schema: 1.0.0 · Engine: 2.0.0 · Scoring: heuristic-density-v1 · Scan date: 2026-10-31.
Can maintainers explain intent, assumptions, and trade-offs? 240 finding(s).
Are imports declared and package/API names verified? 1 finding(s).
Are wrappers, guards, and repeated structures necessary? 164 finding(s).
Which changes need focused human review? 241 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 241 distinct pattern matches across 8 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | …p/routes/client-loader-without-server-loader/route.tsx | 7 | export default function ClientLoaderWithoutServerLoaderRoute({ | CODE |
| LOW | …p/routes/client-loader-without-server-loader/route.tsx | 7 | export default function ClientLoaderWithoutServerLoaderRoute({ | CODE |
| LOW | integration/prefetch-test.ts | 97 | function getRouteModulePreloadHrefs(fixture: Fixture, routeIds: string[]) { | CODE |
| LOW | integration/prefetch-test.ts | 109 | function getInitialScriptsPreloadHrefs(fixture: Fixture, routeIds: string[]) { | CODE |
| LOW | integration/rsc-client-version-test.ts | 85 | async function interceptWithStaleClientVersion(page: Page) { | CODE |
| LOW⚡ | integration/split-route-modules-test.ts | 231 | async function splittableHydrateFallbackDownloaded(page: Page) { | CODE |
| LOW⚡ | integration/split-route-modules-test.ts | 237 | async function unsplittableHydrateFallbackDownloaded(page: Page) { | CODE |
| LOW⚡ | integration/split-route-modules-test.ts | 242 | async function mixedHydrateFallbackDownloaded(page: Page) { | CODE |
| LOW | integration/vite-hmr-hdr-rsc-test.ts | 147 | export function ImportedServerComponentClientMounted() { | CODE |
| LOW | integration/vite-css-lazy-loading-test.ts | 178 | export default function SiblingsWithLazyCssComponent() { | CODE |
| LOW | integration/vite-css-lazy-loading-test.ts | 190 | export default function WithStaticOnlyCssComponent() { | CODE |
| LOW | integration/error-data-request-test.ts | 103 | function assertLoggedErrorInstance(message: string) { | CODE |
| LOW | docs/explanation/sessions-and-cookies.md | 334 | function createDatabaseSessionStorage({ | CODE |
| LOW | scripts/docs.ts | 207 | function getReactRouterApiDocsVersion() { | CODE |
| LOW | scripts/docs.ts | 357 | function getDeclarationDescription(child: JSONOutput.DeclarationReflection) { | CODE |
| LOW | scripts/docs.ts | 415 | function generateMarkdownForComment(comment: SimplifiedComment): string { | CODE |
| LOW | scripts/release-comments.ts | 122 | async function commentOnPrAndLinkedIssues(pr: MergedPR, latest: Tag) { | CODE |
| LOW | scripts/release-comments.ts | 304 | function getIssuesLinkedToPullRequest(prHtmlUrl: string): Array<number> { | CODE |
| LOW | scripts/changes/validate.ts | 6 | function getMissingChangelogPackageDirNames(): string[] { | CODE |
| LOW | scripts/changes/version.ts | 160 | function formatWhatsChangedSection(content: string): string { | CODE |
| LOW | scripts/utils/packages.ts | 39 | return function getNpmPackageNameToDirectoryMap(): Map<string, string> { | CODE |
| LOW | scripts/utils/packages.ts | 75 | export function packageNameToDirectoryName(packageName: string): string | null { | CODE |
| LOW | scripts/previews/branch.ts | 94 | async function updatePackageDependencies() { | CODE |
| LOW | …s/react-router-remix-routes-option-adapter/manifest.ts | 16 | export function routeManifestToRouteConfig( | CODE |
| LOW | packages/create-react-router/loading-indicator.ts | 98 | function getGradientAnimationFrames() { | CODE |
| LOW | packages/create-react-router/utils.ts | 307 | export async function getDirectoryFilesRecursive(dir: string) { | CODE |
| LOW | packages/create-react-router/copy-template.ts | 86 | async function copyTemplateFromRemoteTarball( | CODE |
| LOW | packages/create-react-router/copy-template.ts | 94 | async function copyTemplateFromGithubRepoShorthand( | CODE |
| LOW⚡ | packages/create-react-router/copy-template.ts | 109 | async function copyTemplateFromGithubRepoUrl( | CODE |
| LOW⚡ | packages/create-react-router/copy-template.ts | 117 | async function copyTemplateFromGenericUrl( | CODE |
| LOW⚡ | packages/create-react-router/copy-template.ts | 125 | async function copyTemplateFromLocalFilePath( | CODE |
| LOW | packages/create-react-router/copy-template.ts | 172 | async function downloadAndExtractRepoTarball( | CODE |
| LOW | packages/create-react-router/copy-template.ts | 206 | async function downloadAndExtractTarball( | CODE |
| LOW | packages/create-react-router/copy-template.ts | 349 | async function writeReadableStreamToWritable( | CODE |
| LOW | packages/create-react-router/copy-template.ts | 427 | function getGithubReleaseAssetInfo(browserUrl: string): ReleaseAssetInfo { | CODE |
| LOW | packages/create-react-router/index.ts | 246 | async function copyTemplateToTempDirStep(ctx: Context) { | CODE |
| LOW | packages/create-react-router/index.ts | 314 | async function copyAgentSkillsToAppDirStep(ctx: Context) { | CODE |
| LOW | packages/create-react-router/index.ts | 432 | async function installDependenciesQuestionStep(ctx: Context) { | CODE |
| LOW | packages/react-router-fs-routes/flatRoutes.ts | 513 | export function getRoutePathConflictErrorMessage( | CODE |
| LOW | packages/react-router-fs-routes/flatRoutes.ts | 532 | export function getRouteIdConflictErrorMessage( | CODE |
| LOW | packages/react-router-fs-routes/manifest.ts | 16 | export function routeManifestToRouteConfig( | CODE |
| LOW | packages/react-router-node/stream.ts | 4 | export async function writeReadableStreamToWritable( | CODE |
| LOW | packages/react-router-node/stream.ts | 187 | export async function writeAsyncIterableToWritable( | CODE |
| LOW | packages/react-router-node/__tests__/stream-test.ts | 15 | function createBackpressureSamplingWritable( | CODE |
| LOW | packages/react-router-dev/config/routes.ts | 357 | export function configRoutesToRouteManifest( | CODE |
| LOW | packages/react-router-dev/typegen/index.ts | 25 | async function clearRouteModuleAnnotations(ctx: Context) { | CODE |
| LOW | packages/react-router-dev/vite/vite.ts | 70 | export function defineOptimizeDepsCompilerOptions(options: { | CODE |
| LOW | packages/react-router-dev/vite/vite.ts | 86 | export function getUserBuildRollupOptions( | CODE |
| LOW | packages/react-router-dev/vite/remove-exports.ts | 161 | function validateDestructuredExports( | CODE |
| LOW | packages/react-router-dev/vite/plugin.ts | 171 | function isSsrBundleEnvironmentName( | CODE |
| LOW | packages/react-router-dev/vite/plugin.ts | 192 | function isReactRouterServerEnvironment( | CODE |
| LOW | packages/react-router-dev/vite/plugin.ts | 3228 | async function validateSsrFalsePrerenderExports( | CODE |
| LOW | packages/react-router-dev/vite/plugin.ts | 3365 | function getRoutesByServerBundleId( | CODE |
| LOW | packages/react-router-dev/vite/plugin.ts | 3415 | async function detectRouteChunksIfEnabled( | CODE |
| LOW | packages/react-router-dev/vite/plugin.ts | 3649 | export async function getEnvironmentOptionsResolvers( | CODE |
| LOW | packages/react-router-dev/vite/plugin.ts | 3865 | export function resolveEnvironmentsOptions( | CODE |
| LOW | packages/react-router-dev/vite/plugin.ts | 3917 | function assertPrerenderPathsMatchRoutes( | CODE |
| LOW | packages/react-router-dev/vite/plugin.ts | 3933 | function getPrerenderConcurrencyConfig( | CODE |
| LOW | packages/react-router-dev/vite/plugin.ts | 3996 | function createResourceRouteRequest( | CODE |
| LOW | packages/react-router-dev/vite/route-chunks.ts | 54 | function assertNodePathIsStatement( | CODE |
| 104 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | CHANGELOG.md | 2441 | // ^ cursor is here and you ask for autocompletion | COMMENT |
| LOW | playground/rsc-vite/src/routes/root/root.tsx | 41 | // return ( | COMMENT |
| LOW | playground/rsc-vite/src/routes/root/root.tsx | 61 | // ); | COMMENT |
| LOW | playground/rsc-vite/src/routes/root/root.tsx | 81 | // {" | "} | COMMENT |
| LOW | integration/bug-report-test.ts | 21 | // | COMMENT |
| LOW | integration/bug-report-test.ts | 41 | // | COMMENT |
| LOW | integration/bug-report-test.ts | 121 | // Go check out the other tests to see what else you can do. | COMMENT |
| LOW | integration/helpers/vite-8-template/env.d.ts | 1 | /// <reference types="@react-router/node" /> | COMMENT |
| LOW | integration/helpers/vite-7-template/env.d.ts | 1 | /// <reference types="@react-router/node" /> | COMMENT |
| LOW | packages/react-router-dev/vite/plugin.ts | 381 | isRootRoute | COMMENT |
| LOW | packages/react-router-dev/vite/plugin.ts | 2001 | } | COMMENT |
| LOW | packages/react-router/index.ts | 341 | // DANGER! PLEASE READ ME! | COMMENT |
| LOW | packages/react-router/__tests__/router/fetchers-test.ts | 4261 | root: "ROOT**", | COMMENT |
| LOW | packages/react-router/lib/hooks.tsx | 801 | // it will never match /blog/post/123 */} | COMMENT |
| LOW | packages/react-router/lib/dom/lib.tsx | 101 | //////////////////////////////////////////////////////////////////////////////// | COMMENT |
| LOW | packages/react-router/lib/dom/lib.tsx | 3381 | stripBasename(vtContext.currentLocation.pathname, basename) || | COMMENT |
| LOW | packages/react-router/lib/dom/ssr/single-fetch.tsx | 61 | } | COMMENT |
| LOW | packages/react-router/lib/dom/ssr/single-fetch.tsx | 261 | // SPA mode because we may load a SPA fallback page but then navigate into | COMMENT |
| LOW | packages/react-router/lib/dom/ssr/single-fetch.tsx | 281 | // - We opt out of revalidation automatically for routes with a `loader` | COMMENT |
| LOW | packages/react-router/lib/dom/ssr/single-fetch.tsx | 461 | }), | COMMENT |
| LOW | packages/react-router/lib/dom/ssr/routes.tsx | 581 | } | COMMENT |
| LOW | packages/react-router/lib/router/router.ts | 1701 | // replace with an optional submission | COMMENT |
| LOW | packages/react-router/lib/router/router.ts | 4481 | COMMENT | |
| LOW | packages/react-router/lib/router/utils.ts | 1961 | `Cannot include a '${char}' character in a manually specified ` + | COMMENT |
| LOW | packages/react-router/lib/router/utils.ts | 2041 | let from: string; | COMMENT |
| LOW | .github/workflows/aw-comment-router.lock.yml | 1 | # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"6e4dccd86ee1b1616ec82523bae740eddc4d8e6653da39ec16caa3844b1 | COMMENT |
| LOW | .github/workflows/aw-comment-router.lock.yml | 21 | # gh aw compile | COMMENT |
| LOW | .github/workflows/aw-comment-router.lock.yml | 41 | # - actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | COMMENT |
| LOW | .github/workflows/aw-command-iterate.lock.yml | 1 | # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"e336fe480b06a8803ced7a7f5e288e060b3f943027decc59f50cf705ae8 | COMMENT |
| LOW | .github/workflows/aw-command-iterate.lock.yml | 21 | # gh aw compile | COMMENT |
| LOW | .github/workflows/aw-command-iterate.lock.yml | 41 | # - OPENAI_API_KEY | COMMENT |
| LOW | .github/workflows/aw-command-review-proposal.lock.yml | 1 | # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"d895812522c59471d439f4988fec05189576ee43233c0935aa6a19f6ab2 | COMMENT |
| LOW | .github/workflows/aw-command-review-proposal.lock.yml | 21 | # gh aw compile | COMMENT |
| LOW | .github/workflows/aw-command-review-proposal.lock.yml | 41 | # - SHOPIFY_AI_PROXY | COMMENT |
| LOW | …thub/workflows/aw-command-review-pull-request.lock.yml | 1 | # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"852c40c7c825a06668e56551f3dc30c12121dc6cd7a78b8051c4914fd24 | COMMENT |
| LOW | …thub/workflows/aw-command-review-pull-request.lock.yml | 21 | # gh aw compile | COMMENT |
| LOW | …thub/workflows/aw-command-review-pull-request.lock.yml | 41 | # - SHOPIFY_AI_PROXY | COMMENT |
| LOW | .github/workflows/aw-command-review-issue.lock.yml | 1 | # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"82baeae8246e058d8b8c6c669e384f10b72b553d02fa30a69fdcce383d5 | COMMENT |
| LOW | .github/workflows/aw-command-review-issue.lock.yml | 21 | # gh aw compile | COMMENT |
| LOW | .github/workflows/aw-command-review-issue.lock.yml | 41 | # - SHOPIFY_AI_PROXY | COMMENT |
| LOW | .github/workflows/aw-command-implement.lock.yml | 1 | # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"34c9ad22618038a603f663c252a577d8845ee98854df9939debbe28aaed | COMMENT |
| LOW | .github/workflows/aw-command-implement.lock.yml | 21 | # gh aw compile | COMMENT |
| LOW | .github/workflows/aw-command-implement.lock.yml | 41 | # | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | scripts/docs.ts | 303 | // to leverage the same description for the `@param` JSDoc tag. Mostly needed | COMMENT |
| MEDIUM | packages/react-router/lib/components.tsx | 1987 | // Indirection to leverage useAsyncValue for a render-prop API on `<Await>` | COMMENT |
| MEDIUM | packages/react-router/lib/router/router.ts | 4493 | // such as not being able to leverage `headers()`, or respect | COMMENT |
| MEDIUM | packages/react-router/lib/router/router.ts | 5701 | // provide this value so they can leverage it if needed after they check | COMMENT |
| MEDIUM | packages/react-router/lib/router/router.ts | 6675 | // Opt-ing into the `shouldCallHandler` API changes some nuanced behavior | COMMENT |
| MEDIUM | .github/workflows/test-integration.yml | 3 | # Incrementally comprehensive based on the type of change: | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | integration/vite-dev-custom-entry-test.ts | 17 | export default function handleRequest( | CODE |
| LOW | integration/server-entry-test.ts | 17 | export default function handleRequest() { | CODE |
| LOW | integration/single-fetch-test.ts | 1748 | export default function handleRequest( | CODE |
| LOW | integration/single-fetch-test.ts | 1844 | export default function handleRequest( | CODE |
| LOW | integration/single-fetch-test.ts | 4421 | export default function handleRequest( | CODE |
| LOW | integration/vite-spa-mode-test.ts | 200 | export default function handleRequest( | CODE |
| LOW | integration/vite-spa-mode-test.ts | 468 | export default function handleRequest( | CODE |
| LOW | integration/custom-entry-server-test.ts | 22 | export default function handleRequest( | CODE |
| LOW | integration/error-sanitization-test.ts | 494 | export default function handleRequest( | CODE |
| LOW | integration/middleware-test.ts | 2004 | export default function handleRequest( | CODE |
| LOW | …/react-router-dev/config/defaults/entry.server.web.tsx | 8 | export default async function handleRequest( | CODE |
| LOW | …react-router-dev/config/defaults/entry.server.node.tsx | 12 | export default function handleRequest( | CODE |
| LOW | packages/react-router/lib/dom/server.tsx | 134 | * export async function handleRequest(request: Request) { | COMMENT |
| LOW | packages/react-router/lib/dom/server.tsx | 337 | * export async function handleRequest(request: Request) { | COMMENT |
| LOW | packages/react-router/lib/router/router.ts | 4311 | * export async function handleRequest(request: Request) { | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | CHANGELOG.md | 2533 | // Step 1: Enable middleware | COMMENT |
| LOW | CHANGELOG.md | 2540 | // Step 2: Enable middleware types | COMMENT |
| LOW | CHANGELOG.md | 2555 | // Step 1: Enable middleware | COMMENT |
| LOW | decisions/0016-plan-remove-agnostic-types.md | 49 | #### Step 1: Update `lib/router/utils.ts` | COMMENT |
| LOW | decisions/0016-plan-remove-agnostic-types.md | 153 | #### Step 2: Update `lib/context.ts` | COMMENT |
| LOW | decisions/0016-plan-remove-agnostic-types.md | 228 | #### Step 5: Update Helper Functions | COMMENT |
| LOW | packages/react-router-dev/CHANGELOG.md | 1069 | // Step 1: Enable middleware | COMMENT |
| LOW | packages/react-router-dev/CHANGELOG.md | 1076 | // Step 2: Enable middleware types | COMMENT |
| LOW | packages/react-router-dev/CHANGELOG.md | 1093 | // Step 1: Enable middleware | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| CRITICAL | scripts/release-comments.ts | 386 | return (parsed as IssueLabelsResult).data.repository.issue.labels.nodes.map( | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | …act-router/__tests__/router/utils/data-router-setup.ts | 236 | // Enhance routes with loaders/actions as requested that will call the | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | .github/aw/README.md | 1 | # React Router agentic workflows | COMMENT |
| MEDIUM | .github/workflows/aw-comment-router.lock.yml | 26 | # Route administrator mentions to an agentic workflow | COMMENT |