Component Overview
Remix Component is a minimal component system built on JavaScript and DOM primitives. Write components that render on the server, stream to the browser, and hydrate only where you need interactivity.Features
- JSX Runtime - Convenient JSX syntax for building UIs
- Component State - State managed with plain JavaScript variables
- Manual Updates - Explicit control over when components update via
handle.update() - Real DOM Events - Events are real DOM events using the
on()mixin - Inline CSS - CSS prop with pseudo-selectors and nested rules
- Server Rendering - Stream full pages or fragments with
renderToStream - Hydration - Mark interactive components with
clientEntryand hydrate them on the client - Frames - Stream partial server UI into the page and reload without full page navigation
Quick Start
A simple counter component demonstrates the core concepts:Component Structure
All components follow a two-phase structure:1. Setup Phase
Runs once when the component is first created. Use this for:- Initializing state from the
setupprop - Creating instances (event emitters, observers, etc.)
- Setting up cleanup with
handle.signal
2. Render Phase
Runs on initial render and every update. The returned render function:- Receives props (not the
setupprop) - Returns JSX to render
- Is called after
handle.update()completes
Setup Prop vs Props
Thesetup prop is special:
- Only available in the setup phase - Passed as the second parameter to the component function
- Not included in props - Automatically excluded from the props passed to the render function
- Used for initialization - Initialize state that persists for the component’s lifetime
The Handle API
Components receive aHandle as their first argument:
Key Methods
handle.update()- Schedule an update and re-render the componenthandle.queueTask(task)- Schedule work to run after the next updatehandle.signal- AbortSignal aborted when the component disconnectshandle.id- Stable identifier for the component instancehandle.context- Get/set context values for ancestor/descendant communication
State Management
State is managed with plain JavaScript variables:Best Practices
- Use minimal state - Only store what’s needed for rendering
- Derive computed values - Calculate values in the render function instead of storing them
- Do work in event handlers - Keep transient state in event handler scope
- Don’t store input state you don’t need - Read from the DOM when possible
Component Types
Client Entry Components
Components marked withclientEntry render on the server and hydrate on the client:
Server-Only Components
Components withoutclientEntry only render on the server:
Fragment Component
UseFragment (or <>) to group elements without adding extra DOM nodes:
Next Steps
- Rendering - Learn about component rendering and composition
- State Management - Master state management patterns
- Styling - Style components with the CSS prop
- Events - Handle user interactions with events