What you can build

Gyral treats every interaction as data. That makes these easy. Each one is a short recording of an example in the Gyral repository: no code here, just what the interface does.

Undo, redo and replay

Undo, redo, a scrubbable timeline and replay in a few lines: every edit is a message kept as data, so history is a list and the picture is a fold over it.

The usual way: Undo is a feature you build: command objects, inverse operations and snapshots kept in sync with mutable state.

A heart is painted pixel by pixel. Six presses of Undo leave the removed pixels as dashed ghosts, Redo brings one back, the timeline slider scrubs back to an empty grid, and Replay repaints the whole session.

Type-ahead without stale results

Type-ahead that never shows results for something you are no longer typing: one word, concurrency: switch, cancels the request in flight.

The usual way: Each keystroke fires a fetch and whichever answer lands last wins; fixing it means AbortControllers, request ids and "is this still current?" checks.

One search box feeds two result panels backed by the same slow server. Typed slowly, both panels agree. Typed quickly, the panel without cancellation ends up showing results for "w" because that slow answer arrived last, while the panel using switch cancels the older requests and shows results for "work".

Works before JavaScript loads

One page that works completely with JavaScript off, then checks as you type and submits without a reload once JavaScript loads: same markup, same schema on both sides.

The usual way: You pick one: a server-rendered form, or a client app that is blank until its bundle runs, and validation rules written twice.

JavaScript off. With JavaScript disabled, an RSVP form is filled in and sent. The server answers with the error "Grace already replied with that email" and keeps the typed values; a second reply goes through and the page says "You're on the list".
JavaScript on. The same page with JavaScript: "Enter a valid email address" appears while the email is still being typed, disappears once it is valid, and the reply is sent without reloading the page.

Run them yourself

Every demo is an example with tests. Clone the repository, then pnpm install and pnpm examples.

Build your first component