### Install and Run Bookstore Demo
Source: https://github.com/remix-run/remix/blob/main/demos/bookstore/README.md
Commands to install dependencies and start the Bookstore Demo application. Visit http://localhost:44100 after running.
```bash
cd demos/bookstore
pnpm install
pnpm start
```
--------------------------------
### Install and Run UNPKG Demo
Source: https://github.com/remix-run/remix/blob/main/demos/unpkg/README.md
Commands to install dependencies and start the UNPKG demo. Visit http://localhost:44100 to access the demo.
```bash
cd demos/unpkg
pnpm install
pnpm start
```
--------------------------------
### Install and Run Timeboxer Demo
Source: https://github.com/remix-run/remix/blob/main/demos/timeboxer/README.md
Steps to install dependencies and start the Timeboxer demo application.
```sh
cd demos/timeboxer
cp .env.example .env
pnpm install
pnpm start
```
--------------------------------
### Install and Run Remix App Commands
Source: https://github.com/remix-run/remix/blob/main/template/AGENTS.md
Standard npm commands for installing dependencies, starting the development server, running tests, and performing type checks.
```sh
npm i
npm run start
npm test
npm run typecheck
```
--------------------------------
### Install Dependencies
Source: https://github.com/remix-run/remix/blob/main/packages/fetch-router/demos/cf-workers/README.md
Run this command to install the necessary project dependencies.
```sh
pnpm install
```
--------------------------------
### Track Window Resize Events
Source: https://github.com/remix-run/remix/blob/main/packages/ui/AGENTS.md
This example sets up global event listeners for window resize events within the setup scope. It captures the window's dimensions and updates them on resize, ensuring cleanup is handled automatically via `handle.signal`. Use this for responsive UI components.
```tsx
function WindowResizeTracker(handle: Handle) {
let width = window.innerWidth
let height = window.innerHeight
// Set up global listeners once
addEventListeners(window, handle.signal, {
resize() {
width = window.innerWidth
height = window.innerHeight
handle.update()
},
})
return () => (
Window size: {width} × {height}
)
}
```
--------------------------------
### Install and Run Demo
Source: https://github.com/remix-run/remix/blob/main/demos/social-auth/README.md
Steps to set up and run the social authentication demo locally.
```sh
cd demos/social-auth
cp .env.example .env
pnpm install
pnpm start
```
--------------------------------
### Install Remix Beta
Source: https://github.com/remix-run/remix/blob/main/README.md
Use this command to install the current beta version of Remix.
```sh
npm install remix@next
```
--------------------------------
### Run List Files Demo
Source: https://github.com/remix-run/remix/blob/main/packages/static-middleware/demos/list-files/README.md
Navigate to the demo directory and run the server script to start the demo.
```bash
cd packages/static-middleware/demos/list-files
node server.js
```
--------------------------------
### Install remix
Source: https://github.com/remix-run/remix/blob/main/packages/assert/README.md
Install the remix package to use the assert module.
```sh
npm i remix
```
--------------------------------
### Corrected Component with `setup` Prop
Source: https://github.com/remix-run/remix/blob/main/packages/ui/docs/component-changelog.md
Demonstrates the correct usage of the `setup` prop, preventing stale prop captures by separating setup-specific props from render props.
```tsx
function Counter(
handle: Handle,
// only the setup prop is passed here, no access to `label`
setup: { count: number },
) {
let count = setup.count
return ({ label }: { label: string }) => (
)
}
let el =
```
--------------------------------
### List and Create Users (Python)
Source: https://github.com/remix-run/remix/blob/main/docs/src/prerender/bench/fixtures/docs-page.html
Examples of using an API client to list users with a limit and create a new user.
```python
from example_api import ApiClient
client = ApiClient(api_key=os.environ['API_KEY'])
# List users
users = client.users.list(limit=10)
# Create a user
new_user = client.users.create(
email='user@example.com',
name='John Doe'
)
```
--------------------------------
### Session-Backed Browser Login Flow
Source: https://github.com/remix-run/remix/blob/main/packages/auth-middleware/README.md
This example demonstrates the request-time authentication setup for a session-backed browser login flow. It configures session management, defines an authentication scheme using session data, and protects a dashboard route using `requireAuth`.
```ts
import { auth, createSessionAuthScheme, requireAuth } from 'remix/middleware/auth'
import { createRouter } from 'remix/router'
import { route } from 'remix/routes'
import { session } from 'remix/middleware/session'
let routes = route({
app: {
dashboard: '/dashboard',
},
})
type User = { id: string; email: string }
let router = createRouter({
middleware: [
session(sessionCookie, sessionStorage),
auth({
schemes: [
createSessionAuthScheme({
read(session) {
return session.get('auth') as { userId: string } | null
},
verify(value) {
return users.getById(value.userId)
},
invalidate(session) {
session.unset('auth')
},
}),
],
}),
],
})
router.get(routes.app.dashboard, {
middleware: [requireAuth()],
handler(context) {
let auth = context.auth
if (!auth.ok) {
return new Response('Unauthorized', { status: 401 })
}
return Response.json({
id: auth.identity.id,
email: auth.identity.email,
method: auth.method,
})
},
})
```
--------------------------------
### Remix CLI Usage Examples
Source: https://github.com/remix-run/remix/blob/main/packages/cli/README.md
Common commands for managing Remix projects using the installed CLI.
```sh
remix new my-remix-app
```
```sh
remix completion bash >> ~/.bashrc
```
```sh
remix doctor
```
```sh
remix doctor --fix
```
```sh
remix routes
```
```sh
remix routes --table
```
```sh
remix routes --table --no-headers
```
```sh
remix test
```
```sh
remix version
```
```sh
remix --no-color doctor
```
--------------------------------
### Ruby SDK Example
Source: https://github.com/remix-run/remix/blob/main/docs/src/prerender/bench/fixtures/docs-page.html
Example usage of the API client library in Ruby.
```APIDOC
### Ruby
require 'example_api'
client = ExampleApi::Client.new(api_key: ENV['API_KEY'])
# List users
users = client.users.list(limit: 10)
# Create a user
new_user = client.users.create(
email: 'user@example.com',
name: 'John Doe'
)
```
--------------------------------
### Stale Prop Capture Example
Source: https://github.com/remix-run/remix/blob/main/packages/ui/docs/component-changelog.md
Illustrates how props could be accidentally captured with stale values in the setup scope before the `setup` prop was introduced.
```tsx
function Counter(
this: Handle,
// captured `label` in the wrong scope
props: { label: string; initialCount: number },
) {
let count = initialCount
return () => (
)
}
```
--------------------------------
### List and Create Users (Ruby)
Source: https://github.com/remix-run/remix/blob/main/docs/src/prerender/bench/fixtures/docs-page.html
Examples of using an API client to list users with a limit and create a new user.
```ruby
require 'example_api'
client = ExampleApi::Client.new(api_key: ENV['API_KEY'])
# List users
users = client.users.list(limit: 10)
# Create a user
new_user = client.users.create(
email: 'user@example.com',
name: 'John Doe'
)
```
--------------------------------
### Python SDK Example
Source: https://github.com/remix-run/remix/blob/main/docs/src/prerender/bench/fixtures/docs-page.html
Example usage of the API client library in Python.
```APIDOC
### Python
from example_api import ApiClient
client = ApiClient(api_key=os.environ['API_KEY'])
# List users
users = client.users.list(limit=10)
# Create a user
new_user = client.users.create(
email='user@example.com',
name='John Doe'
)
```
--------------------------------
### Install Remix Preview Build with pnpm
Source: https://github.com/remix-run/remix/blob/main/CONTRIBUTING.md
Use this command to install the latest `main` branch build of Remix directly from the `preview/main` branch using pnpm version 9 or higher. This is useful for testing unreleased features.
```sh
pnpm install "remix-run/remix#preview/main&path:packages/remix"
```
```sh
# Or, just install a single package
pnpm install "remix-run/remix#preview/main&path:packages/fetch-router"
```
--------------------------------
### Create a Standard File Object
Source: https://github.com/remix-run/remix/blob/main/packages/lazy-file/README.md
Example of creating a standard File object with content provided upfront.
```ts
let file = new File(['hello world'], 'hello.txt', { type: 'text/plain' })
```
--------------------------------
### Install Remix
Source: https://github.com/remix-run/remix/blob/main/packages/async-context-middleware/README.md
Install the Remix package to use its routing and middleware functionalities.
```sh
npm i remix
```
--------------------------------
### File System Storage Example
Source: https://github.com/remix-run/remix/blob/main/packages/file-storage/README.md
Demonstrates creating and using a filesystem-based file storage. Files are stored with their original metadata and can be streamed.
```ts
import { createFsFileStorage } from 'remix/file-storage/fs'
let storage = createFsFileStorage('./user/files')
let file = new File(['hello world'], 'hello.txt', { type: 'text/plain' })
let key = 'hello-key'
// Put the file in storage.
await storage.set(key, file)
// Then, sometime later...
let fileFromStorage = await storage.get(key)
if (fileFromStorage != null) {
// All of the original file's metadata is intact
fileFromStorage.name // 'hello.txt'
fileFromStorage.type // 'text/plain'
// The filesystem backend returns a LazyFile, so you can stream it directly.
let response = new Response(fileFromStorage.stream())
}
// To remove from storage
await storage.remove(key)
```
--------------------------------
### Run Assets Demo
Source: https://github.com/remix-run/remix/blob/main/demos/assets/README.md
Starts the Remix assets demo in watch-mode. Open the provided URL to view the demo.
```sh
pnpm -C demos/assets dev
```
--------------------------------
### JavaScript/TypeScript SDK Example
Source: https://github.com/remix-run/remix/blob/main/docs/src/prerender/bench/fixtures/docs-page.html
Example usage of the API client library in JavaScript/TypeScript.
```APIDOC
### JavaScript/TypeScript
import { ApiClient } from '@example/api-client'
let client = new ApiClient({
apiKey: process.env.API_KEY
})
// List users
let users = await client.users.list({ limit: 10 })
// Create a user
let newUser = await client.users.create({
email: 'user@example.com',
name: 'John Doe'
})
```
--------------------------------
### Define and Install Admin Routes
Source: https://github.com/remix-run/remix/blob/main/packages/fetch-router/README.md
Define route definitions and use a route installer function to map them under a mount prefix. This allows for modular route management.
```typescript
import { createRouter, type RouteBuilder } from 'remix/router'
import { get, route } from 'remix/routes'
const adminRouteDefs = {
index: get('/'),
users: {
show: get('/users/:id'),
},
}
// Use relative route groups inside installers. These routes are registered below
// the mount prefix when `installAdminRoutes()` runs.
const adminRouteGroup = route(adminRouteDefs)
// Use full app routes for links and redirects.
const routes = {
admin: route('/admin', adminRouteDefs),
}
function installAdminRoutes(router: RouteBuilder) {
router.map(adminRouteGroup, {
actions: {
index() {
return new Response('Admin')
},
},
})
router.map(adminRouteGroup.users, {
actions: {
show({ params, currentUser }) {
return new Response(`User ${params.id} for ${currentUser.id}`)
},
},
})
}
let router = createRouter({ middleware })
router.mount('/admin', installAdminRoutes)
```
--------------------------------
### Install Remix Main Branch Preview with pnpm
Source: https://github.com/remix-run/remix/blob/main/README.md
Install the latest development version from the main branch using pnpm. This is for users who want to test the bleeding edge.
```sh
pnpm install "remix-run/remix#preview/main&path:packages/remix"
```
--------------------------------
### Start Local MySQL Container
Source: https://github.com/remix-run/remix/blob/main/packages/data-table-mysql/README.md
Run a local MySQL container using Podman for integration testing.
```sh
podman run --name mysql \
-e MYSQL_ROOT_PASSWORD=root \
-e MYSQL_DATABASE=remix \
-p 3306:3306 \
-d mysql:8
```
--------------------------------
### Global Setup and Teardown Functions
Source: https://github.com/remix-run/remix/blob/main/packages/test/README.md
Define `globalSetup` and `globalTeardown` functions in a setup module (e.g., `./test/setup.ts`) to run code once before and after the entire test suite. This is useful for database migrations or cleanup operations.
```typescript
// ./test/setup.ts
export async function globalSetup() {
await db.migrate()
}
export async function globalTeardown() {
await db.close()
}
```
--------------------------------
### List and Create Users (JavaScript/TypeScript)
Source: https://github.com/remix-run/remix/blob/main/docs/src/prerender/bench/fixtures/docs-page.html
Examples of using an API client to list users with a limit and create a new user.
```javascript
import { ApiClient } from '@example/api-client'
let client = new ApiClient({
apiKey: process.env.API_KEY
})
// List users
let users = await client.users.list({ limit: 10 })
// Create a user
let newUser = await client.users.create({
email: 'user@example.com',
name: 'John Doe'
})
```
--------------------------------
### Migration Runner Command Line Examples
Source: https://github.com/remix-run/remix/blob/main/packages/data-table/README.md
Illustrates common command-line invocations for the migration runner script, including direction, target migration, and rollback.
```sh
node ./app/db/migrate.ts up
node ./app/db/migrate.ts up 20260301113000
node ./app/db/migrate.ts down
node ./app/db/migrate.ts down 20260228090000
```
--------------------------------
### Example TypeScript Migration (Old Method)
Source: https://github.com/remix-run/remix/blob/main/decisions/006-sql-migrations.md
Illustrates the previous approach of using TypeScript files for database migrations in Remix.
```typescript
import { column as c, table } from 'remix/data-table'
import { createMigration } from 'remix/data-table/migrations'
let users = table(/* ... */)
export default createMigration({
async up({ db, schema }) {
await schema.createTable(users)
},
async down({ schema }) {
await schema.dropTable(users, { ifExists: true })
},
})
```
--------------------------------
### Run the Demo App
Source: https://github.com/remix-run/remix/blob/main/packages/ui/demo/README.md
Use this command to start the local development server for the UI demo application. After running, access the demos at http://localhost:44100.
```sh
pnpm -C packages/ui/demo dev
```
--------------------------------
### Intentional Stale Prop Example (Discouraged)
Source: https://github.com/remix-run/remix/blob/main/packages/ui/docs/component-changelog.md
Shows an intentionally complex and ill-advised method of making a prop value static by moving props into the setup scope, highlighting the difficulty of achieving this now.
```tsx
// this is a bad example, showing the difficulty and ill-advised method of
// making a prop value static by moving props into the setup scope
function Counter(handle: Handle, setup: number) {
let count = setup
let initialLabel: string
return (props: { label: string }) => {
// what used to be an accident is now difficult to do on purpose
if (!initialLabel) {
initialLabel = props.label
}
return (
)
}
}
```
--------------------------------
### Setup PostgreSQL Database Adapter
Source: https://github.com/remix-run/remix/blob/main/packages/data-table/README.md
Define tables and create a database instance using the PostgreSQL adapter. This involves importing necessary functions, defining table schemas, and configuring the database connection.
```ts
import { Pool } from 'pg'
import { column as c, createDatabase, hasMany, query, table } from 'remix/data-table'
import { createPostgresDatabaseAdapter } from 'remix/data-table/postgres'
let users = table({
name: 'users',
columns: {
id: c.uuid(),
email: c.varchar(255),
role: c.enum(['customer', 'admin']),
created_at: c.integer(),
},
})
let orders = table({
name: 'orders',
columns: {
id: c.uuid(),
user_id: c.uuid(),
status: c.enum(['pending', 'processing', 'shipped', 'delivered']),
total: c.decimal(10, 2),
created_at: c.integer(),
},
})
let userOrders = hasMany(users, orders)
let pool = new Pool({ connectionString: process.env.DATABASE_URL })
let db = createDatabase(createPostgresDatabaseAdapter(pool))
```
--------------------------------
### Type-Safe Links and Form Actions with Remix Router
Source: https://github.com/remix-run/remix/blob/main/packages/fetch-router/README.md
Demonstrates generating type-safe links and form actions using the `href()` function on routes. Includes setup for a basic site with home and contact pages, and registers GET and POST actions for routes.
```typescript
import { route } from 'remix/routes'
import { createRouter } from 'remix/router'
import { html } from 'remix/html-template'
import { createHtmlResponse } from 'remix/response/html'
let routes = route({
home: '/',
contact: '/contact',
})
let router = createRouter()
// Register an action for `GET /`
router.get(routes.home, () => {
return createHtmlResponse(
)
})
// Register an action for `GET /contact`
router.get(routes.contact, () => {
return createHtmlResponse(
Contact Us
)
})
// Register an action for `POST /contact`
router.post(routes.contact, ({ get }) => {
// POST actions can read parsed FormData from request context using FormData
// as the context key after the formData middleware has run.
let formData = get(FormData)
let message = formData.get('message') as string
let body = html`
Thanks!
You said: ${message}
`
return createHtmlResponse(body)
})
```
--------------------------------
### Remix Test Configuration File
Source: https://github.com/remix-run/remix/blob/main/packages/test/README.md
Configure test runner behavior by creating a `remix-test.config.ts` file. This example shows default values for browser options, concurrency, coverage, glob patterns, Playwright configuration, reporter, setup path, test types, and watch mode.
```typescript
import type { RemixTestConfig } from 'remix/test'
export default {
// Browser options for E2E tests
browser: {
// Echo browser console output to the terminal
echo: false,
// Open browser (via playwright `headless:false`) and keep it open after tests
// complete (useful for debugging)
open: false,
},
// Max number of concurrent test workers (default `os.availableParallelism()`)
concurrency: 2,
// Pool for server and E2E test files ("forks", "threads")
pool: 'forks',
// Code coverage options
coverage: {
// Enable coverage reporting
enabled: true,
// Output directory (default: ".coverage")
dir: '.coverage',
// Glob pattern(s) to include/exclude
include: 'src/**',
exclude: 'src/**/*.test.ts',
// Minimum thresholds (%)
statements: 80,
lines: 80,
branches: 80,
functions: 80,
},
// Glob pattern(s) identifying test files
glob: {
// All test files (default: "**/*.test{,.browser,.e2e}.{ts,tsx}").
test: '**/*.test{,.browser,.e2e}.ts',
// Browser test files (default: "**/*.test.browser.{ts,tsx}")
browser: '**/*.test.browser.ts',
// E2E test files (default: "**/*.test.e2e.{ts,tsx}")
e2e: '**/*.test.e2e.ts',
},
// Playwright configuration for E2E tests, or string path to an existing
// config file on disk
playwrightConfig: {
projects: [
{ name: 'chromium', use: { browserName: 'chromium' } },
{ name: 'firefox', use: { browserName: 'firefox' } },
],
use: {
navigationTimeout: 5_000,
actionTimeout: 5_000,
},
},
// Playwright project(s) to run E2E tests for
project: 'chromium',
// Test reporter ("spec", "files", "tap", "dot")
reporter: 'spec',
// Path to a setup module (see Setup section below)
setup: './test/setup.ts',
// Test type(s) to run ("server", "browser", "e2e")
type: ['server', 'browser', 'e2e'],
// Watch for file changes and re-run
watch: false,
} satisfies RemixTestConfig
```
--------------------------------
### Initialize Database, Apply Migrations, and Seed Data
Source: https://github.com/remix-run/remix/blob/main/demos/bookstore/README.md
Data setup script (`app/data/setup.ts`) that initializes the SQLite database, applies migrations from `db/migrations/20260228090000_create_bookstore_schema.ts`, and seeds demo data.
```typescript
app/data/setup.ts
```
```typescript
db/migrations/20260228090000_create_bookstore_schema.ts
```
--------------------------------
### Initialize API client and list users (Python)
Source: https://github.com/remix-run/remix/blob/main/docs/src/prerender/bench/fixtures/docs-page.html
Initialize the API client with an API key from environment variables. Use the client to list users with an optional limit parameter.
```python
from example_api import ApiClient
client = ApiClient(api_key=os.environ['API_KEY'])
# List users
users = client.users.list(limit=10)
```
--------------------------------
### Initialize API client and list users (JavaScript/TypeScript)
Source: https://github.com/remix-run/remix/blob/main/docs/src/prerender/bench/fixtures/docs-page.html
Instantiate the API client with an API key from environment variables. Use the client to list users with optional limit parameter.
```javascript
import { ApiClient } from '@example/api-client'
let client = new ApiClient({
apiKey: process.env.API_KEY
})
// List users
let users = await client.users.list({ limit: 10 })
```
--------------------------------
### Initialize API client and list users (Ruby)
Source: https://github.com/remix-run/remix/blob/main/docs/src/prerender/bench/fixtures/docs-page.html
Initialize the API client with an API key from environment variables. Use the client to list users with an optional limit parameter.
```ruby
require 'example_api'
client = ExampleApi::Client.new(api_key: ENV['API_KEY'])
# List users
users = client.users.list(limit: 10)
```
--------------------------------
### Install Data Table and PostgreSQL Dependencies
Source: https://github.com/remix-run/remix/blob/main/packages/data-table-postgres/README.md
Install the necessary packages for data-table and PostgreSQL integration.
```sh
npm i remix pg
```
--------------------------------
### Install Dependencies
Source: https://github.com/remix-run/remix/blob/main/packages/data-table/README.md
Install the necessary dependencies for data-table, including the core package and a database adapter like 'pg' or 'mysql2'.
```sh
npm i remix
npm i pg
# or
npm i mysql2
# or
# use the SQLite client built into your runtime
```
--------------------------------
### Install Remix Data Table and MySQL2
Source: https://github.com/remix-run/remix/blob/main/packages/data-table-mysql/README.md
Install the necessary packages for using the MySQL adapter with Remix Data Table.
```sh
npm i remix mysql2
```
--------------------------------
### Create Asset Server with Basic Configuration
Source: https://github.com/remix-run/remix/blob/main/packages/assets/README.md
Initialize an asset server with a base path, file mapping, access control, and file extensions. This setup serves compiled browser assets from specified directories.
```typescript
import { createRouter } from 'remix/router'
import { createAssetServer } from 'remix/assets'
let assetServer = createAssetServer({
basePath: '/assets',
fileMap: {
'/app/*path': 'app/*path',
'/npm/*path': 'node_modules/*path',
},
allow: ['app/assets/**', 'node_modules/**'],
files: {
extensions: ['.svg', '.png', '.jpg', '.jpeg', '.woff2'],
},
})
let router = createRouter()
router.get('/assets/*', ({ request }) => {
return assetServer.fetch(request)
})
```
--------------------------------
### Start Development Server
Source: https://github.com/remix-run/remix/blob/main/packages/fetch-router/demos/cf-workers/README.md
Starts the local development server for the Cloudflare Worker application. The application will be accessible at http://localhost:44100.
```sh
pnpm run dev
```
--------------------------------
### Nested Route Map Controller Example
Source: https://github.com/remix-run/remix/blob/main/demos/bookstore/README.md
Demonstrates a controller for a nested route map, shown with the contact form example in `app/actions/contact/controller.tsx`.
```typescript
app/actions/contact/controller.tsx
```
--------------------------------
### Basic Router Setup and Usage
Source: https://github.com/remix-run/remix/blob/main/packages/fetch-router/README.md
Defines a router with middleware and maps controllers to different route groups. Demonstrates handling dynamic route parameters.
```ts
import { route } from 'remix/routes'
import { createRouter } from 'remix/router'
import { logger } from 'remix/middleware/logger'
// `route()` creates a "route map" that organizes routes by name. The keys
// of the map may be any name, and may be nested to group related routes.
let routes = route({
home: '/',
about: '/about',
blog: {
index: '/blog',
show: '/blog/:slug',
},
})
let router = createRouter({
// Middleware is used to run code before and/or after actions run.
// In this case, the `logger()` middleware logs the request to the console.
middleware: [logger()]
})
// Map a controller that supplies actions for the root routes.
// A controller is a plain object with an `actions` property that
// matches the direct route leaves in a route map.
router.map(routes, {
actions: {
home() {
return new Response('Home')
},
about() {
return new Response('About')
},
},
})
// Map another controller that supplies actions for the blog routes.
router.map(routes.blog, {
actions: {
index() {
return new Response('Blog')
},
show({ params }) {
// params is a type-safe object with the parameters from the route pattern
return new Response(`Post ${params.slug}`)
},
},
})
let response = await router.fetch('https://remix.run/blog/hello-remix')
console.log(await response.text()) // "Post hello-remix"
```
--------------------------------
### Install Single Package from Remix Main Branch
Source: https://github.com/remix-run/remix/blob/main/README.md
Install a specific package, like fetch-router, directly from the main branch of the Remix repository using pnpm.
```sh
pnpm install "remix-run/remix#preview/main&path:packages/fetch-router"
```
--------------------------------
### Boot the Client Runtime
Source: https://github.com/remix-run/remix/blob/main/packages/ui/docs/hydration.md
Use `run` to initialize the client-side hydration process. It requires a `loadModule` function to dynamically import components and optionally a `resolveFrame` function for handling frame content.
```tsx
import { run } from 'remix/ui'
let app = run({
async loadModule(moduleUrl, exportName) {
let mod = await import(moduleUrl)
return mod[exportName]
},
async resolveFrame(src, signal) {
let res = await fetch(src, { headers: { Accept: 'text/html' }, signal })
return res.body ?? (await res.text())
},
})
await app.ready()
```
--------------------------------
### Key Prop Usage Examples in Remix
Source: https://github.com/remix-run/remix/blob/main/packages/ui/docs/composition.md
Provides examples of correct and incorrect usage of the `key` prop for list items. Emphasizes using stable and unique identifiers.
```tsx
// Good: stable, unique IDs
{
items.map((item) => )
}
// Good: index can work if list never reorders
{
items.map((item, index) => )
}
// Bad: don't use random values or values that change
{
items.map((item) => )
}
```
--------------------------------
### Initialize API client and create a user (Python)
Source: https://github.com/remix-run/remix/blob/main/docs/src/prerender/bench/fixtures/docs-page.html
Use the API client to create a new user by providing their email and name in the request body.
```python
# Create a user
new_user = client.users.create(
email='user@example.com',
name='John Doe'
)
```
--------------------------------
### Install HTML Renderer Middleware
Source: https://github.com/remix-run/remix/blob/main/demos/bookstore/README.md
Middleware (`app/middleware/render.tsx`) that installs the request-scoped HTML renderer. This is used by actions via `context.render` and supports server-side frame resolution for fragment-based rendering.
```typescript
app/middleware/render.tsx
```
--------------------------------
### Basic Framework Listbox Example
Source: https://github.com/remix-run/remix/blob/main/packages/ui/src/listbox/README.md
Demonstrates how to use the listbox primitive to create a controlled list of selectable framework options. It manages selection and highlighting state externally.
```tsx
import type { Handle } from 'remix/ui'
import * as listbox from 'remix/ui/listbox'
import type { ListboxValue } from 'remix/ui/listbox'
import { listStyle, optionStyle } from './listbox.styles'
function FrameworkListbox(handle: Handle) {
let value: ListboxValue = 'remix'
let activeValue: ListboxValue = 'remix'
return () => (
{
value = nextValue
void handle.update()
}}
onHighlight={(nextValue) => {
activeValue = nextValue
void handle.update()
}}
>
{frameworks.map((option) => (
{option.label}
))}
)
}
let frameworks = [
{ label: 'Remix', value: 'remix' },
{ disabled: true, label: 'React Router', value: 'react-router' },
{ label: 'React', value: 'react' },
{ label: 'Preact', value: 'preact' },
]
```
--------------------------------
### Complete Product Card Example
Source: https://github.com/remix-run/remix/blob/main/packages/ui/docs/styling.md
A comprehensive example of a ProductCard component demonstrating parent hover effects on children, element-specific styles, element states, and responsive media queries.
```tsx
function ProductCard(handle: Handle<{ title: string; price: number; image: string }>) {
return () => (
{handle.props.title}
${handle.props.price}
)
}
```
--------------------------------
### Integrate with File Storage Library
Source: https://github.com/remix-run/remix/blob/main/packages/form-data-parser/README.md
Use the `file-storage` library for flexible storage of uploaded files. This example demonstrates setting up file storage and using it within the upload handler.
```ts
import { createFsFileStorage } from 'remix/file-storage/fs'
import type { FileUpload } from 'remix/form-data-parser'
import { parseFormData } from 'remix/form-data-parser'
// Set up storage for uploaded files
const fileStorage = createFsFileStorage('/uploads/user-avatars')
// Define how to handle incoming file uploads
async function uploadHandler(fileUpload: FileUpload) {
// Is this file upload from the field?
if (fileUpload.fieldName === 'user-avatar') {
let storageKey = `user-${user.id}-avatar`
// Put the file in storage and return the stored LazyFile
return fileStorage.put(storageKey, fileUpload)
}
// Ignore unrecognized fields
}
```
--------------------------------
### Complete Spring Animation Example in a React Component
Source: https://github.com/remix-run/remix/blob/main/packages/ui/docs/spring.md
A full example demonstrating a clickable card component that animates its size using Spring transitions. It utilizes `spring.transition` for defining the animation properties and `on('click')` for interactivity.
```tsx
function AnimatedCard(handle: Handle) {
let isExpanded = false
return () => (
)
}
```
--------------------------------
### Spring Presets and Custom Configuration
Source: https://github.com/remix-run/remix/blob/main/packages/ui/docs/spring.md
Demonstrates how to use predefined spring presets or configure a custom spring with specific parameters like duration and bounce.
```tsx
import { spring } from './spring.ts'
// Using a preset
spring('bouncy') // bouncy with overshoot
spring('snappy') // quick, no overshoot (default)
spring('smooth') // gentle, overdamped
// Custom spring
spring({ duration: 400, bounce: 0.3 })
```
```tsx
spring('bouncy', { duration: 300 }) // faster bouncy
spring('smooth', { duration: 800 }) // slower smooth
```
```tsx
spring({
duration: 500, // perceived duration in milliseconds
bounce: 0.3, // -1 to 1 (negative = overdamped, 0 = critical, positive = bouncy)
velocity: 0, // initial velocity in units per second
})
```
```tsx
spring({ bounce: -0.5 }) // very smooth, slow
spring({ bounce: 0 }) // snappy, no bounce
spring({ bounce: 0.3 }) // slight bounce
spring({ bounce: 0.7 }) // very bouncy
```
```tsx
spring('bouncy', { velocity: 2 }) // fast start
spring('bouncy', { velocity: -1 }) // initially going backward
```
```tsx
// velocity is in px/s, distance is in px
let normalizedVelocity = velocityTowardTarget / distanceToTarget
spring('bouncy', { velocity: normalizedVelocity })
```
--------------------------------
### Initialize PostgreSQL Database Adapter
Source: https://github.com/remix-run/remix/blob/main/packages/data-table-postgres/README.md
Set up the PostgreSQL adapter for use with the data-table API. Ensure your DATABASE_URL environment variable is set.
```ts
import { Pool } from 'pg'
import { createDatabase } from 'remix/data-table'
import { createPostgresDatabaseAdapter } from 'remix/data-table/postgres'
let pool = new Pool({
connectionString: process.env.DATABASE_URL,
})
let db = createDatabase(createPostgresDatabaseAdapter(pool))
```
--------------------------------
### Initial Data Loading in Setup Scope
Source: https://github.com/remix-run/remix/blob/main/packages/ui/docs/patterns.md
Load initial data within the setup scope using queueTask for components that require data before rendering. Note that changes to props like 'userId' won't automatically restart the request unless explicitly handled.
```tsx
function UserProfile(handle: Handle<{ userId: string; showEmail?: boolean }>) {
let user: User | null = null
let loading = true
// Load initial data in setup scope using queueTask
handle.queueTask(async (signal) => {
let response = await fetch(`/api/users/${handle.props.userId}`, { signal })
let data = await response.json()
if (signal.aborted) return
user = data
loading = false
handle.update()
})
return () => {
if (loading) return
Loading user...
return (
{user.name}
{handle.props.showEmail &&
{user.email}
}
)
}
}
```
--------------------------------
### Remix CLI Commands
Source: https://github.com/remix-run/remix/blob/main/packages/remix/README.md
Common commands available through the Remix CLI after installation.
```sh
remix new my-remix-app
```
```sh
remix completion bash >> ~/.bashrc
```
```sh
remix doctor
```
```sh
remix doctor --fix
```
```sh
remix routes
```
```sh
remix routes --table
```
```sh
remix routes --table --no-headers
```
```sh
remix skills install
```
```sh
remix test
```
```sh
remix version
```
```sh
remix --no-color doctor
```
--------------------------------
### Basic Context Implementation in Remix UI
Source: https://github.com/remix-run/remix/blob/main/packages/ui/AGENTS.md
Demonstrates a basic context setup where context changes require manual updates using `handle.update()`. Use this for simple context sharing when granular updates are not critical.
```tsx
function ThemeProvider(handle: Handle<{ children?: RemixNode }, { theme: 'light' | 'dark' }>)
{
let theme: 'light' | 'dark' = 'light'
handle.context.set({ theme })
return () => (
{handle.props.children}
)
}
function ThemedContent(handle: Handle)
{
let { theme } = handle.context.get(ThemeProvider)
return () => (
Current theme: {theme}
)
}
```
--------------------------------
### Create Patch Change File
Source: https://github.com/remix-run/remix/blob/main/CONTRIBUTING.md
Example of a change file for a bug fix.
```md
patch.fix-something.md
```
--------------------------------
### Basic Menu with Checkbox and Radio Items
Source: https://github.com/remix-run/remix/blob/main/packages/ui/src/menu/README.md
Demonstrates how to use the Menu, MenuItem, and Submenu components to create a menu with word wrap (checkbox) and density (radio) options. It also shows how to handle selection events using `onMenuSelect`.
```tsx
import type { Handle } from 'remix/ui'
import { css } from 'remix/ui'
import { Menu, MenuItem, Submenu } from 'remix/ui/menu'
import { onMenuSelect } from 'remix/ui/menu/primitives'
export function ViewMenu(handle: Handle) {
let wordWrap = false
let density = 'comfortable'
return () => (
)
}
let separatorStyle = css({
border: 0,
borderBlockStart: '1px solid #e5e7eb',
marginBlock: '4px',
})
```
--------------------------------
### Create New Feature Change File
Source: https://github.com/remix-run/remix/blob/main/CONTRIBUTING.md
Example of a change file for adding a new feature.
```md
minor.add-something.md
```
--------------------------------
### Initialize MySQL Database Adapter
Source: https://github.com/remix-run/remix/blob/main/packages/data-table-mysql/README.md
Create a MySQL database adapter instance using a mysql2/promise Pool and initialize the data table database.
```ts
import { createPool } from 'mysql2/promise'
import { createDatabase } from 'remix/data-table'
import { createMysqlDatabaseAdapter } from 'remix/data-table/mysql'
let pool = createPool(process.env.DATABASE_URL as string)
let db = createDatabase(createMysqlDatabaseAdapter(pool))
```
--------------------------------
### Color Interpolation with Spring
Source: https://github.com/remix-run/remix/blob/main/packages/ui/docs/spring.md
Example of interpolating between two RGB color values using the spring iterator.
```ts
let fromRGB = [255, 0, 0] // red
let toRGB = [0, 0, 255] // blue
for (let t of spring('smooth')) {
let r = Math.round(fromRGB[0] + (toRGB[0] - fromRGB[0]) * t)
let g = Math.round(fromRGB[1] + (toRGB[1] - fromRGB[1]) * t)
let b = Math.round(fromRGB[2] + (toRGB[2] - fromRGB[2]) * t)
element.style.backgroundColor = `rgb(${r}, ${g}, ${b})`
await nextFrame()
}
```