Introduction
Get oriented around Xote's reactive model, UI primitives, and setup.
What is Xote?
Xote is a UI library for ReScript built around fine-grained reactivity. It re-exports rescript-signals for state, derived values, and effects, then adds the pieces you need to build applications: components, JSX support, routing, SSR, and hydration.
The design goal is simple: keep the reactive model small and explicit, then let updates flow directly to the DOM instead of re-running whole component trees.
- Signals for local and shared state
- Computed values for derived state
- Effects for external side effects
- Components and JSX for UI composition
- A built-in router, SSR, and hydration
Start Here
This counter shows the core model: a signal stores state, an event updates it, and a reactive text node reads it.
Using JSX Syntax
1open Xote23let count = Signal.make(0)45let increment = (_evt: Dom.event) => {6 Signal.update(count, n => n + 1)7}89let app = () => {10 <div>11 <h1> {Node.text("Counter")} </h1>12 <p>13 {Node.signalText(() => "Count: " ++ Int.toString(Signal.get(count)))}14 </p>15 <button onClick={increment}>16 {Node.text("Increment")}17 </button>18 </div>19}2021Node.mountById(app(), "app")When count changes, only the reactive text node updates. The component does not need a render loop or a dependency array.
How the Docs Are Organized
The docs make more sense if you move from the reactive core outward into UI, routing, and server rendering.
- Signals - state containers you can read and update
- Computeds - derived values that stay in sync
- Effects - side effects that react to state changes
- Components - component structure, JSX, attributes, events, and lists
- Router - client-side navigation and route matching
- Server-Side Rendering - rendering on the server and hydrating on the client
Installation
Install the package, then point ReScript's JSX transform at XoteJSX.
1npm install xote2# or3yarn add xote4# or5pnpm add xote1{2 "bs-dependencies": ["xote"],3 "jsx": {4 "version": 4,5 "module": "XoteJSX"6 },7 "compiler-flags": ["-open Xote"]8}Next Steps
- Read Signals first if you want the shortest path into the reactive model.
- Move to Components next once the state model feels clear.
- Keep the Signals API nearby while you are writing real code.
Philosophy
Xote keeps the runtime surface small and explicit. State lives in signals, derived state lives in computeds, and external work lives in effects. That separation makes update paths easier to follow and easier to debug.
Because Xote builds on rescript-signals, the reactive core stays close to the broader signals direction in JavaScript while exposing a UI API that feels natural in ReScript.