Skip to content

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 Xote
2
3let count = Signal.make(0)
4
5let increment = (_evt: Dom.event) => {
6 Signal.update(count, n => n + 1)
7}
8
9let 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}
20
21Node.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 xote
2# or
3yarn add xote
4# or
5pnpm add xote
1{
2 "bs-dependencies": ["xote"],
3 "jsx": {
4 "version": 4,
5 "module": "XoteJSX"
6 },
7 "compiler-flags": ["-open Xote"]
8}

Next Steps

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.