.agents/skills/make-demo/SKILL.md
Create or revise demos in the Remix repository. Use when adding a new demo under demos/, updating an existing demo, or reviewing demo code to ensure it showcases Remix packages, strong code hygiene, and production-quality patterns.
npx skillsauth add remix-run/remix make-demoInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Demos in this repository are not throwaway prototypes. They are durable code artifacts that should teach people and other agents how to write Remix code well.
A good demo should:
demos/<name>/ using the same conventions as the existing demos.package.json with remix as a dependency when appropriate, and import from package exports such as remix/component instead of reaching back into packages/ with relative imports.remix/component, prefer idiomatic Remix component patterns. Use normal JSX composition and built-in styling/mixin props such as css={...} or mix={css(...)} and mix={[...]} instead of dropping down to manual DOM mutation or ad hoc class management.remix/component JSX, configure that demo's tsconfig.json with jsx: "react-jsx", jsxImportSource: "remix/component", and preserveSymlinks: true. Do not add paths entries that point back into packages/remix/src. The goal is for TypeScript to resolve remix through the demo's own node_modules view, not through repo-relative source paths.remix/component, prefer a tiny local render() helper that calls renderToStream(...) and wraps it with createHtmlResponse(...) from remix/response/html instead of manually building HTML Response headers or wrapping the stream yourself.session.get(), session.set(), session.flash(), session.unset(), redirect(), or context.get(...) unless the wrapper adds real domain logic, reusable policy, or a genuinely clearer abstraction.44100.SIGINT and SIGTERM cleanly by closing the server and exiting.Use only the files the scenario needs, but prefer this shape:
demos/<name>/package.jsondemos/<name>/tsconfig.json when the demo has TypeScript or JSX sourcedemos/<name>/server.tsdemos/<name>/README.mddemos/<name>/app/demos/<name>/public/ when serving built assets or other static filesWhen a demo is a real application, prefer a uniform Remix application layout instead of inventing a new structure for each demo.
Use these root directories consistently:
app/ for runtime application codedb/ for database artifacts such as migrations and local SQLite filestest/ for shared test helpers, fixtures, and any true cross-application integration testspublic/ for static files served as-istmp/ for runtime scratch files such as sessions, uploads, and cachesInside app/, organize code by responsibility:
controllers/ for all controller-owned features, with folders such as controllers/home/, controllers/auth/, or controllers/account/, each with a controller.tsx entrypoint and the UI it ownscontrollers/ui/ for reusable cross-feature UI primitives used by those controllersdata/ for runtime data definitions such as table schema and setup helpers used by the application at startupmiddleware/ for request-layer concerns such as auth, database injection, sessions, and other request lifecycle setuputils/ for shared runtime support code that does not clearly belong to one of the other app layerscontroller.tsx. Do not split controller files across the app root and feature folders.signup-controller.tsx when the parent already lives at auth/controller.tsx; prefer auth/signup/controller.tsx.controllers/ui/.controllers/ui/ only for reusable UI primitives. Do not create a generic app/components/ dumping ground.app/lib/ dumping ground.index.ts. Import feature modules directly.controllers/.middleware/.app/data/.db/.utils/ only for genuinely cross-layer support code. Prefer a topic-specific name like utils/external-auth.ts over catch-all names like helpers.ts or misc.ts.test/ directory only for shared test code, fixtures, and truly broad integration coverage that does not belong to a single app module.demos/<name>/
app/
router.ts
router.test.ts
routes.ts
controllers/
render.tsx
home/
controller.tsx
login-page.tsx
auth/
controller.tsx
signup/
controller.tsx
resolve-external-auth.ts
account/
controller.tsx
account-page.tsx
ui/
auth-card.tsx
document.tsx
form-field.tsx
notice.tsx
icons.tsx
design-system.ts
styles.ts
data/
schema.ts
setup.ts
setup.test.ts
middleware/
auth.ts
database.ts
session.ts
utils/
auth-session.ts
auth-session.test.ts
password-hash.ts
external-auth.ts
db/
migrations/
app.sqlite
test/
fixtures/
helpers.ts
public/
tmp/
remix package exports where available.pnpm -C demos/<name> typecheck when the demo defines a typecheck script.pnpm -C demos/<name> test when the demo defines tests.pnpm run lint before finishing.tools
Build the UI of a Remix app. Use when creating pages, layouts, client entries, interactions, stateful UI, navigation, hydration, styling, animations, reusable mixins, or UI tests.
development
Describe the ideal layout of a Remix application, including canonical directories, route ownership, naming conventions, and file locations on disk. When asked to bootstrap that layout in a new directory, run the bundled TypeScript script.
documentation
Write or rewrite package README files in the style used by the Remix repository. Use when drafting a new package README, revising an existing README, or reviewing README structure, examples, installation instructions, and section ordering for Remix packages.
development
Write or audit public API docs for Remix packages. Use when adding or tightening JSDoc on exported functions, classes, interfaces, type aliases, or option objects.