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.
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.