About remix
A skill for developers building or maintaining Remix applications. It emphasizes checking the installed documentation and the app’s existing structure rather than relying on assumptions from other Remix versions.
Key features
- 01Installed documentation lookup
- 02Route, router, and controller guidance
- 03Remix component model
- 04App-scoped change guidance
- 05Testing and verification steps
Use cases
- 01Finding the right installed Remix API
- 02Adding or changing route behavior
- 03Building interactive Remix components
- 04Checking changes to server-rendered UI
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ remix-run/ remix --skill remixAfter installing, type/remixin Claude Code to confirm it loaded.
Details
From the project READMEBuild and Review a Remix App
Find Context and Documentation
Read the relevant installed documentation before using unfamiliar Remix APIs:
- Read the app's
AGENTS.md,package.json, andtsconfig.json, then inspect the code that owns the behavior being changed. - Search
node_modules/remix/INDEX.mdby task, export, or keyword, for examplegrep -i 'session' node_modules/remix/INDEX.md. For a specific function, type, or attribute, searchnode_modules/remix/guidesandnode_modules/remix/src. - Follow the index to the relevant guide for the workflow, then the package README for exact imports, options, behavior, and examples. If there is no relevant guide, use the API README and existing app patterns.
Treat the installed documentation as canonical, including when it differs from this skill. Do not rely on remembered Remix 2 patterns or online APIs from a newer version. If the installation has no index, inspect its package.json exports and matching installed READMEs, source, and types.
Remix Mental Model
Remix builds on Web APIs such as Request, Response, URL, and FormData. Its APIs compose explicitly at runtime; do not assume file-based routing, generated route types, or a mandatory build step.
Routes, Router, and Controllers
Remix apps generally separate routing into three parts:
- Routes define the URL and method contract, including typed URL generation (
app/routes.tsin the starter). - The router connects routes, middleware, and controllers (
app/router.ts). - Controllers implement the actions that handle matched routes (
app/actions/).
This organization applies to server apps and browser apps using the SPA router. Remix's pieces are composable and replaceable; using one does not require adopting the others. Follow the existing app's choices and use the documented starter conventions when establishing a new app.
A minimal server route can return a plain Web Response:
// app/routes.ts
import { get, route } from 'remix/routes'
export const routes = route({
hello: get('/hello/:name'),
})
// app/actions/controller.ts
import { createController } from 'remix/router'
import { routes } from '../routes.ts'
export default createController(routes, {
actions: {
hello(context) {
return new Response(`Hello, ${context.params.name}!`)
},
},
})
// app/router.ts
import { createRouter } from 'remix/router'
import controller from './actions/controller.ts'
import { routes } from './routes.ts'
export const router = createRouter()
router.map(routes, controller)
The runtime adapter passes requests to router.fetch(request). Generate URLs from the same route contract: routes.hello.href({ name: 'Remix' }) produces /hello/Remix.
Components
Remix components use JSX, but they are not React. A component's setup function runs once per instance and returns a render function. Local variables in setup preserve state between renders; event handlers change that state and call handle.update() to request another render:
import { on } from 'remix/component'
import type { Handle } from 'remix/component'
function Counter(handle: Handle) {
let count = 0
return () => (
<button
type="button"
mix={on('click', () => {
count++
handle.update()
})}
>
Count: {count}
</button>
)
}
Read changing props from handle.props during render, rather than capturing their initial values in setup. Do not apply React hooks or lifecycle assumptions.
Event handlers run only when the component is mounted or hydrated in the browser; server-rendered HTML alone is not interactive. Follow the installed interactivity guide and the app's existing browser-entry setup.
Work Within the App
- Preserve the app's package manager, scripts, runtime, middleware order, and import conventions unless the task requires changing them. Do not replace an existing solution merely to match the starter.
- Change the narrowest owner of the behavior. Keep route-local code together and share it only when multiple areas need it.
- Prefer Web APIs, native links, buttons, and forms, plus existing first-party Remix primitives, over custom abstractions.
- Treat browser-reachable modules as public: keep secrets and trusted server logic out of them. In the starter, colocated
public/directories mark browser-reachable source.
Verify the Behavior
Use the app's scripts for relevant tests and typechecking, then verify the changed behavior directly. For UI changes, exercise the interaction in the browser, not just the rendered appearance. When enhancing a server-rendered page, check both ordinary document behavior and the enhanced path. Test rejection and failure paths for changes involving untrusted input or access control.
Use the installed testing guide for test patterns and CLI documentation for diagnostics. Run remix doctor after structural or configuration changes; review findings before applying fixes. Do not run destructive database commands or rewrite configuration merely to make a diagnostic pass. Report what was checked and what remains unverified.