mcpField
R
remix-v2-routing-review

remix-v2-routing-review

github.com/existential-birdsTesting & quality8540 installsUpdated 11w ago
Repository

About remix-v2-routing-review

An Agent Skill for reviewing Remix v2 routing code, aimed at developers checking `app/routes/` and the root route module. It applies context-sensitive checks for route naming, layouts, resource routes, and migration adapters to avoid false positives.

Key features

  1. 01Check route filenames and path segments
  2. 02Review layouts and Outlet usage
  3. 03Check resource route exports and links
  4. 04Detect v1 holdovers and imports
  5. 05Apply version- and context-specific rules

Use cases

  1. 01Review Remix v2 routing changes
  2. 02Investigate nested route layout issues
  3. 03Check links to resource routes

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/existential-birds/beagle --skill remix-v2-routing-review

After installing, type/remix-v2-routing-reviewin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

references/
layouts-outlets.md
resource-routes.md
root-shell.md
route-files.md
v1-holdovers.md

Details

From the project README

Remix v2 Routing Code Review

Loaded by review-remix-v2 (umbrella) to flag routing anti-patterns in app/routes/ modules. See remix-v2-routing for canonical patterns.

Quick Reference

Issue TypeReference
Filename smells (index.tsx, __auth, wrong escape, non-route files)references/route-files.md
Missing <Outlet />, orphan dotted segments, duplicated layout logicreferences/layouts-outlets.md
Default export on a resource, <Link> without reloadDocument, splat paramsreferences/resource-routes.md
react-router-dom imports, __double folders, v1-adapter fallbackreferences/v1-holdovers.md
Missing <Meta />/<Links />/<Scripts />/<ScrollRestoration />, Vite-vs-Classic <LiveReload />, root ErrorBoundary without document shellreferences/root-shell.md

Scope

This skill flags issues in:

  • Files under app/routes/ (filenames, exports, imports, JSX shape)
  • app/root.tsx (document shell, root <Outlet />)
  • remix.config.js (entries that change route discovery: routes(), ignoredRouteFiles, @remix-run/v1-route-convention)
  • Any module that links to a resource route (<Link> usage)

Out of scope: loader/action data contracts (covered by remix-v2-data-flow-review), form behavior (remix-v2-forms-review), meta/headers (remix-v2-meta-sessions-review).

Review Checklist

  • Index routes named _index.tsx, not index.tsx
  • Pathless layouts use single underscore (_auth.tsx), not double (__auth/)
  • Dotted child routes (users.profile.tsx) have a parent module or use trailing underscore (users_.profile.tsx)
  • Parent route modules render <Outlet />
  • Splat segments read params["*"], never params.splat / params.rest
  • Literal dots/special chars escaped with brackets (sitemap[.]xml.tsx)
  • Resource routes have no default export
  • <Link> to a resource route uses reloadDocument (or is a plain <a>)
  • Imports come from @remix-run/react, not react-router-dom
  • Non-route files (CSS, helpers, tests) live in a folder with route.tsx, or are listed in ignoredRouteFiles
  • Trailing-underscore opt-outs only used when a parent layout actually exists to escape
  • Optional segments ($lang) narrow params.lang in the loader (see references/route-files.md)

Valid Patterns (Do NOT Flag)

  • Resource route with no default export — this is the convention that makes it a resource route. Never flag.
  • Any _-prefixed pathless layout file without <Outlet /> when the module is intentionally a wrapper that renders fixed UI only. Confirm by checking children — if no *.{segment}.tsx siblings exist, the wrapper-only shape is intentional.
  • Files prefixed with _ that don't appear in any URL — pathless layouts and _index are supposed to be hidden from the URL.
  • @remix-run/v1-route-convention wired up in remix.config.js — legitimate migration adapter, not a smell on its own. Only flag if v1-style files appear without the adapter installed.
  • useLoaderData<typeof loader>() — type annotation, not assertion.
  • Splat route accessing params["*"] with bracket syntax — that is the only correct access pattern.
  • Folder app/routes/dashboard/ with route.tsx plus sibling .server.ts, .css, component files — co-location is the documented pattern.
  • Trailing underscore (concerts_.mine.tsx) when a sibling concerts.tsx layout exists and this URL intentionally skips it.

Context-Sensitive Rules

Only flag these issues when the specific context applies:

IssueFlag ONLY IF
index.tsx under app/routes/Project is v2 and @remix-run/v1-route-convention is NOT wired in remix.config.js
Parent module without <Outlet />Sibling dotted children (parent.*.tsx) exist in app/routes/
__double underscore folderNo v1-convention adapter is installed
Trailing-underscore segmentNo corresponding parent layout exists (nothing to opt out of)
Default export on a module returning non-HTMLThe loader/action actually returns a raw Response (PDF, JSON, RSS)
<Link> to resource routeTarget route has no default export AND <Link> lacks reloadDocument

Hard gates (before writing findings)

Run these in order. Do not draft user-facing findings until every gate passes for the batch you are about to report.

  1. Location evidence — Pass: Each issue lists a repo path (file under app/routes/ or remix.config.js) and either a line range or a short verbatim quote from the file you read. Filename-only smells must quote the literal filename.

  2. Exemption check — Pass: For each issue, state in one line why it is not covered by Valid Patterns (Do NOT Flag). Resource-route flags require explicit evidence of a default export or a <Link> without reloadDocument.

  3. Version check — Pass: Confirm the project is Remix v2 (check package.json for @remix-run/react ^2, or presence of v2 flat-routes filenames elsewhere in app/routes/). If @remix-run/v1-route-convention is wired in remix.config.js, v1 filenames (__auth/, index.tsx) are intentional — do not flag them as smells.

  4. Protocol — Pass: Complete the Pre-Report Verification Checklist in review-verification-protocol for this review.

When to Load References

Review Questions

  1. Does every parent route render <Outlet />, or is it a deliberate wrapper-only?
  2. Do filenames match the v2 grammar (single _ for pathless, _index for index, [...] for escapes)?
  3. Are resource routes free of default exports, and do all <Link>s to them use reloadDocument?
  4. Are all router imports from @remix-run/react (and server helpers from @remix-run/node)?
  5. If v1 filenames exist, is @remix-run/v1-route-convention wired up — or are they accidental?

Additional Documentation

  • Route file naming smells: references/route-files.md — index.tsx, __double folders, wrong escape syntax, dot/underscore confusion, non-route files under app/routes/.
  • Layouts and outlets: references/layouts-outlets.md — pathless layout misuse, missing <Outlet />, orphan dotted children, duplicated layout logic.
  • Resource routes: references/resource-routes.md — accidental default export, <Link> without reloadDocument, splat params["*"] access.
  • v1 holdovers: references/v1-holdovers.md — react-router-dom imports, __auth folders, @remix-run/v1-route-convention as a deliberate-vs-accidental tell.

Comments

Markdown supported