Write reactive CLI applications in plain HTML.
See the code
Write your terminal UI in HTML files. Keep state and logic in Rust. No widget trees built by hand, and no markup inside Rust macros.
hypercmd is a terminal renderer for fusor. fusor compiles your HTML and Rust; hypercmd lays the result out in terminal cells, handles the keyboard and keeps the screen in sync. When a signal changes, the bindings that read it run again and the next frame shows the result.
In development · v0.1: this is experimental software. APIs will change; don't rely on it for production yet. See status and known limitations.
Get started · How it works · Examples · Documentation · Status · Contributing
The view is an HTML file. Bindings and event handlers are Rust expressions:
<!-- ui/app.html -->
<App state="{{ Counter::new() }}">
<main>
<h1>Counter</h1>
<p>Count: {{ state.count.get() }}</p>
<div class="actions">
<button on:click="state.increment()">Increment</button>
<button on:click="state.count.set(0)">Reset</button>
</div>
</main>
</App>
The Rust module owns the state, includes the HTML with template! and runs the app:
// src/main.rs
use fusor::{Signal, signal};
struct Counter {
count: Signal<i32>,
}
impl Counter {
fn new() -> Self {
Self { count: signal(0) }
}
fn increment(&self) {
self.count.update(|n| *n += 1);
}
}
fusor::template!(backend = "hypercmd", "ui/app.html");
fn main() -> Result<(), hypercmd::Error> {
hypercmd::native::run(hypercmd_app()?)
}
<App> makes the struct's fields and methods available as state and generates hypercmd_app(). Tab moves focus between the buttons; Enter or Space presses one. The paragraph reads the count signal, so its text updates when the count changes. The compiler checks the expressions in the HTML along with the rest of the module. A small stylesheet lays the buttons out in a row:
/* ui/terminal.css */
main { padding: 1ch; gap: 1ch; }
.actions { flex-direction: row; gap: 1ch; }
hypercmd runs on macOS and Linux. To build apps you need Rust 1.85 or newer, installed with rustup. Then install the CLI:
curl -fsSL https://raw.githubusercontent.com/fusor-rs/hypercmd/main/install.sh | sh
The installer downloads the latest release, verifies its checksum, and puts hypercmd in .hypercmd/bin under your home directory; it prints the line to add to your PATH. The script is install.sh if you want to read it first. With Rust installed, cargo install hypercmd-cli works too.
Run hypercmd upgrade to upgrade the CLI. Interactive commands warn when a newer
release is available, checking at most once a day. See CLI upgrades.
Create and run an app:
hypercmd new my-app
cd my-app
hypercmd run
hypercmd new writes the counter above and checks that it builds. Edit
ui/app.html for the screen and src/main.rs for its state, then hypercmd run
again. See the CLI reference for commands and options.
hypercmd new sets up an ordinary Cargo package. To add hypercmd to an existing one, depend on the runtime and the build helper, and declare the package's templates and styles:
[dependencies]
hypercmd = "=0.1.2"
fusor = { package = "fusor-core", version = "=0.1.5", default-features = false }
fusor-components = { version = "=0.1.5", default-features = false }
[build-dependencies]
hypercmd-build = "=0.1.2"
[package.metadata.hypercmd]
entry = "ui/app.html" # the <App> template
templates = ["ui"] # directories of component templates
styles = ["ui/terminal.css"]
Compile the templates from build.rs:
fn main() -> Result<(), Box<dyn std::error::Error>> {
hypercmd_build::compile_app()
}
Reusable components can also be mounted as a root with hypercmd::mount::<Component>(inputs).
To run the examples from a checkout, use just: just demo opens the file browser in the current folder.
ch and percentage sizes, padding, gaps, colors, emphasis and scrollable overflow. Unsupported markup or CSS fails at build time instead of rendering differently.The Markdown guides also power a site through
docs-base.
The landing page and docs share a browser workspace.
Run just site, then just preview to serve both on port 4187.
See the site guide.
| Guide | Covers |
|---|---|
| CLI reference | Installation, creating apps, checks, running and building |
| HTML and CSS reference | Supported HTML, CSS, layout, scrolling and Unicode policy |
| Controls | Keyboard, focus, buttons, text and checkbox bindings |
| Async views | Async/Await, coherent publication and cancellation |
| Routing | Screens, nested views and in-memory history |
| Services | Owner-scoped tasks, timers and background workers |
| Native execution | Terminal session, signals and resource limits |
| Consumption | Packaging, shared components and browser reuse |
hypercmd is v0.1 and experimental. Until 1.0, each minor release may change the HTML profile and the Rust APIs.
| Platform or capability | Status |
|---|---|
| macOS native | Automated OS PTY coverage |
| Linux native | CI gate |
| Windows native | Execution unavailable |
| Browser component reuse | Chromium acceptance gate |
| Non-browser Wasm host | Unimplemented |
| Accessibility | Keyboard operation and visible focus; screen-reader testing pending |
| Terminal emulators | Manual compatibility testing pending |
Not supported yet:
<Async> boundaries, and editable controls or router outlets inside an async view.Ratatui is an immediate-mode library: your code draws widgets into a buffer every frame and handles events itself. hypercmd retains a scene built from HTML templates, updates it through signals, and owns layout, focus and input. It uses Ratatui's buffer and styles for terminal output.
Ink renders React components in the terminal with flexbox layout, in JavaScript. Textual is a Python framework with widgets styled by its own CSS dialect. hypercmd shares their ideas of flexbox and CSS in the terminal, but components are HTML templates backed by Rust structs, compiled and type-checked ahead of time, with fine-grained signals updating individual nodes.
hypercmd is an open source project in early development. The contributing guide covers the setup, checks and workflow. The runtime and build helper live in crates/; runnable applications live in examples/.
hypercmd is built with the help of AI tools, mainly Claude Code, under the same rules the project asks of contributors: see Using AI tools.
Licensed under the MIT License.
Rust
83.2%
JavaScript
8.0%
HTML
4.6%
CSS
2.6%
Write reactive CLI applications in plain HTML.
See the code
Write your terminal UI in HTML files. Keep state and logic in Rust. No widget trees built by hand, and no markup inside Rust macros.
hypercmd is a terminal renderer for fusor. fusor compiles your HTML and Rust; hypercmd lays the result out in terminal cells, handles the keyboard and keeps the screen in sync. When a signal changes, the bindings that read it run again and the next frame shows the result.
In development · v0.1: this is experimental software. APIs will change; don't rely on it for production yet. See status and known limitations.
Get started · How it works · Examples · Documentation · Status · Contributing
The view is an HTML file. Bindings and event handlers are Rust expressions:
<!-- ui/app.html -->
<App state="{{ Counter::new() }}">
<main>
<h1>Counter</h1>
<p>Count: {{ state.count.get() }}</p>
<div class="actions">
<button on:click="state.increment()">Increment</button>
<button on:click="state.count.set(0)">Reset</button>
</div>
</main>
</App>
The Rust module owns the state, includes the HTML with template! and runs the app:
// src/main.rs
use fusor::{Signal, signal};
struct Counter {
count: Signal<i32>,
}
impl Counter {
fn new() -> Self {
Self { count: signal(0) }
}
fn increment(&self) {
self.count.update(|n| *n += 1);
}
}
fusor::template!(backend = "hypercmd", "ui/app.html");
fn main() -> Result<(), hypercmd::Error> {
hypercmd::native::run(hypercmd_app()?)
}
<App> makes the struct's fields and methods available as state and generates hypercmd_app(). Tab moves focus between the buttons; Enter or Space presses one. The paragraph reads the count signal, so its text updates when the count changes. The compiler checks the expressions in the HTML along with the rest of the module. A small stylesheet lays the buttons out in a row:
/* ui/terminal.css */
main { padding: 1ch; gap: 1ch; }
.actions { flex-direction: row; gap: 1ch; }
hypercmd runs on macOS and Linux. To build apps you need Rust 1.85 or newer, installed with rustup. Then install the CLI:
curl -fsSL https://raw.githubusercontent.com/fusor-rs/hypercmd/main/install.sh | sh
The installer downloads the latest release, verifies its checksum, and puts hypercmd in .hypercmd/bin under your home directory; it prints the line to add to your PATH. The script is install.sh if you want to read it first. With Rust installed, cargo install hypercmd-cli works too.
Run hypercmd upgrade to upgrade the CLI. Interactive commands warn when a newer
release is available, checking at most once a day. See CLI upgrades.
Create and run an app:
hypercmd new my-app
cd my-app
hypercmd run
hypercmd new writes the counter above and checks that it builds. Edit
ui/app.html for the screen and src/main.rs for its state, then hypercmd run
again. See the CLI reference for commands and options.
hypercmd new sets up an ordinary Cargo package. To add hypercmd to an existing one, depend on the runtime and the build helper, and declare the package's templates and styles:
[dependencies]
hypercmd = "=0.1.2"
fusor = { package = "fusor-core", version = "=0.1.5", default-features = false }
fusor-components = { version = "=0.1.5", default-features = false }
[build-dependencies]
hypercmd-build = "=0.1.2"
[package.metadata.hypercmd]
entry = "ui/app.html" # the <App> template
templates = ["ui"] # directories of component templates
styles = ["ui/terminal.css"]
Compile the templates from build.rs:
fn main() -> Result<(), Box<dyn std::error::Error>> {
hypercmd_build::compile_app()
}
Reusable components can also be mounted as a root with hypercmd::mount::<Component>(inputs).
To run the examples from a checkout, use just: just demo opens the file browser in the current folder.
ch and percentage sizes, padding, gaps, colors, emphasis and scrollable overflow. Unsupported markup or CSS fails at build time instead of rendering differently.The Markdown guides also power a site through
docs-base.
The landing page and docs share a browser workspace.
Run just site, then just preview to serve both on port 4187.
See the site guide.
| Guide | Covers |
|---|---|
| CLI reference | Installation, creating apps, checks, running and building |
| HTML and CSS reference | Supported HTML, CSS, layout, scrolling and Unicode policy |
| Controls | Keyboard, focus, buttons, text and checkbox bindings |
| Async views | Async/Await, coherent publication and cancellation |
| Routing | Screens, nested views and in-memory history |
| Services | Owner-scoped tasks, timers and background workers |
| Native execution | Terminal session, signals and resource limits |
| Consumption | Packaging, shared components and browser reuse |
hypercmd is v0.1 and experimental. Until 1.0, each minor release may change the HTML profile and the Rust APIs.
| Platform or capability | Status |
|---|---|
| macOS native | Automated OS PTY coverage |
| Linux native | CI gate |
| Windows native | Execution unavailable |
| Browser component reuse | Chromium acceptance gate |
| Non-browser Wasm host | Unimplemented |
| Accessibility | Keyboard operation and visible focus; screen-reader testing pending |
| Terminal emulators | Manual compatibility testing pending |
Not supported yet:
<Async> boundaries, and editable controls or router outlets inside an async view.Ratatui is an immediate-mode library: your code draws widgets into a buffer every frame and handles events itself. hypercmd retains a scene built from HTML templates, updates it through signals, and owns layout, focus and input. It uses Ratatui's buffer and styles for terminal output.
Ink renders React components in the terminal with flexbox layout, in JavaScript. Textual is a Python framework with widgets styled by its own CSS dialect. hypercmd shares their ideas of flexbox and CSS in the terminal, but components are HTML templates backed by Rust structs, compiled and type-checked ahead of time, with fine-grained signals updating individual nodes.
hypercmd is an open source project in early development. The contributing guide covers the setup, checks and workflow. The runtime and build helper live in crates/; runnable applications live in examples/.
hypercmd is built with the help of AI tools, mainly Claude Code, under the same rules the project asks of contributors: see Using AI tools.
Licensed under the MIT License.
Rust
83.2%
JavaScript
8.0%
HTML
4.6%
CSS
2.6%