Skip to main content

React Integration

The useSystem hook connects your React components to an Idyllic system. It establishes a WebSocket connection, subscribes to state updates, and returns typed state and actions. When server-side state changes, your component re-renders automatically.
The generic parameter <DocImprover> tells TypeScript which system you’re connecting to. This enables the framework to infer types for state and actions from your system definition—full autocompletion and type checking without client-side type definitions.

What useSystem Returns

The hook returns an object containing your system’s state properties and action methods, plus connection status:
State properties (count, tasks) are reactive—reading them causes re-renders when they change. Action methods (generate) forward calls to the server over WebSocket. The status property indicates connection state, and error contains failure details if applicable.

Reading State

State values read like regular JavaScript properties. The framework tracks which properties your component accesses and re-renders when they change:

Stream Values

For streaming content like LLM output, use the current property to display accumulated content and status to show indicators:
Each chunk appended on the server triggers a re-render, creating the characteristic effect of tokens appearing progressively.

Calling Actions

Actions are typed proxies that forward calls to the server. Call them like regular async functions:
Types for parameters and return values come from your system class. TypeScript catches mismatches at compile time.

Fire and Forget

For streaming operations, trigger the action without awaiting. The server streams chunks into state, and your component re-renders as that state updates:

Connection Options

Pass options to configure the connection:

Instance IDs

The id option determines which system instance you connect to. Each unique ID corresponds to a separate Durable Object with isolated state:
Use user IDs for per-user state, document IDs for per-document state, or any multi-tenant pattern.

Connection Status

Handle different connection states in your UI:
Status transitions: 'connecting''connected' on success. If connection drops, 'disconnected' while reconnecting. If reconnection fails, 'error'.

Multiple Systems

Connect to multiple systems in one component. Each creates an independent WebSocket:

Type Generation

Types generate automatically during development:
Generated types appear at .idyllic/types.ts. Import your system type and pass it to useSystem:
Types update as you modify your system class, keeping frontend and backend in sync.

FAQ

When does useSystem create vs connect?

The hook connects to an existing instance or creates one on-demand. There’s no explicit “create”—instances materialize when the first client connects with a given ID.

What happens when the component unmounts?

The WebSocket closes. If the user navigates back, a new connection opens and receives a fresh state snapshot. Server-side execution continues regardless of client connections.

How do I share state between components?

Two options: (1) Use the same instance ID in multiple components—each gets its own connection but sees identical state. (2) Lift useSystem to a parent and pass state via props or context.

How do I test components?

Mock the hook to provide controlled state and action spies:
For integration tests, run npx idyllic dev and use actual connections.

Guides

Learn patterns for building with Idyllic