Build reactive interfaces with fine-grained signals and sound types
Xote is a lightweight UI library for ReScript that combines signal-powered reactivity with a minimal component system. No virtual DOM, no diffing — just precise, efficient updates.
Everything you need for reactive UIs
Powerful reactive primitives, a declarative component system, and type safety — all in a focused package.
Fine-Grained Reactivity
Direct DOM updates without a virtual DOM. Automatic dependency tracking means only what changed gets updated.
Learn about SignalsBased on TC39 Signals
Aligned with the TC39 Signals proposal. Build with patterns that will become native to JavaScript.
Read the specType-Safe by Default
Built with ReScript's powerful type system. Catch bugs at compile time with sound types and pattern matching.
View API ReferenceLightweight & Fast
Minimal runtime overhead with no virtual DOM diffing. Components compile to efficient JavaScript.
JSX Support
Full ReScript JSX v4 support for declarative components. Familiar markup with type system safety.
Component docsClient-Side Router
Built-in signal-based router with pattern matching and dynamic routes — no extra dependencies.
Router guideServer-Side Rendering
Full SSR with hydration, state serialization, and environment-aware components — render on the server, hydrate on the client.
SSR guideSignals, Computeds, and Effects
Three powerful building blocks for seamless reactivity. Your mental model stays simple and predictable.
1open Xote23let make = () => {4 let count = Signal.make(0)56 let increment = (_evt) =>7 Signal.update(count, n => n + 1)89 let decrement = (_evt) =>10 Signal.update(count, n => n - 1)1112 <div class="counter-app">13 <div class="counter-display">14 {Node.signalText(() =>15 Signal.get(count)->Int.toString16 )}17 </div>18 <div class="counter-buttons">19 <button onClick={decrement}>20 {Node.text("-")}21 </button>22 <button onClick={increment}>23 {Node.text("+")}24 </button>25 </div>26 </div>27}