oxirast-core 1.0.1

A fast, fine-grained WebAssembly frontend framework for Rust.
Documentation

Oxirast

The fine-grained, lightning-fast WebAssembly framework for Rust.

Why Oxirast?

Most frontend frameworks rely on a Virtual DOM โ€” when state changes, they re-render your entire component, diff a new VDOM tree against the old one, and patch the real DOM. This diffing step is expensive and grows with your component tree.

Oxirast takes a fundamentally different approach: Fine-Grained Reactivity.

State lives in Signals. When a Signal mutates, Oxirast does not re-render the component. It reaches directly into the live browser DOM and surgically updates only the specific text node or attribute that depends on that Signal. The rest of your tree is never touched.

Virtual DOM (React) Fine-Grained (Oxirast)
State change triggers Full component re-render Targeted Signal update only
DOM update method Diff + patch VDOM tree Direct DOM mutation
Re-render overhead O(component size) O(1) per subscriber
Memory model GC-managed heap (JS) Rust ownership + Wasm GC
Language JavaScript / TypeScript Rust โ†’ WebAssembly

Features

  • ๐ŸŽฏ True Fine-Grained Reactivity โ€” Signals mutate, DOM updates. No re-renders. No diffing.
  • ๐Ÿฆ€ 100% Rust โ€” Write your entire frontend in one language with full type safety.
  • ๐Ÿ“ Declarative UI via rsx! โ€” HTML-like syntax compiled to optimised Wasm at build time.
  • ๐Ÿ”€ Built-in SPA Router โ€” History-based client-side routing with automatic memory cleanup.
  • โšก Zero-Config CLI โ€” Scaffold, compile, and hot-reload with a single command.
  • ๐Ÿงน Automatic Memory Management โ€” Wasm-to-JS garbage collector purges orphaned closures and Signals on page transitions, preventing memory leaks.

Workspace Structure

This repository is a Cargo workspace containing three crates:

oxirast/
โ”œโ”€โ”€ oxirast-core/      # Runtime engine โ€” Signals, VNode, Router, DOM bindings
โ”œโ”€โ”€ oxirast-parser/    # Compile-time procedural macro engine โ€” rsx! transformation
โ””โ”€โ”€ oxirast-cli/       # Developer CLI โ€” scaffold, serve with hot-reload

oxirast-core

The runtime engine. Contains the Virtual DOM, the Signal<T> reactivity system, the Router, async fetch hooks (use_fetch), the Context API (provide_context / use_context), and all wasm-bindgen DOM bindings.

oxirast-parser

The compile-time macro engine. Transforms your rsx! HTML-like syntax into optimised Rust/VNode instructions. Handles bind_text directive wiring and on_* event listener compilation.

oxirast-cli

The developer toolkit. A globally installed binary that scaffolds new projects and runs a hot-reloading development server at http://localhost:3000.


Quick Start

1. Install the CLI

cargo install oxirast-cli

2. Scaffold a new project

oxirast-cli init my_app
cd my_app

3. Start the dev server

oxirast-cli

Your app is now compiling to WebAssembly and running at http://localhost:3000 with hot-reloading enabled.


Usage

Components & the rsx! Macro

use oxirast_core::VNode;
use oxirast_parser::rsx;

#[allow(non_snake_case)]
pub fn WelcomeCard() -> VNode {
    rsx!(
        <div class="card">
            <h1>"Welcome to Oxirast"</h1>
            <p>"Compiled to WebAssembly."</p>
        </div>
    )
}

Reactivity with Signals

use oxirast_core::{use_state, VNode};
use oxirast_parser::rsx;

#[allow(non_snake_case)]
pub fn Counter() -> VNode {
    let count        = use_state(0);
    let display_text = use_state(String::from("Clicks: 0"));

    let btn_count = count.clone();
    let btn_text  = display_text.clone();

    let handle_click = move |_e| {
        let next = btn_count.get() + 1;
        btn_count.set(next);
        btn_text.set(format!("Clicks: {}", next));
    };

    rsx!(
        <div class="counter-box">
            <h2 bind_text={display_text}></h2>
            <button on_click={handle_click}>"Increment"</button>
        </div>
    )
}

Single Page Routing

use oxirast_core::{Router, Signal, VNode};
use oxirast_parser::rsx;

#[allow(non_snake_case)]
pub fn Home(nav: Signal<String>) -> VNode {
    let nav_clone = nav.clone();
    let go_about = move |_| nav_clone.set(String::from("/about"));

    rsx!(
        <div>
            <h1>"Home Page"</h1>
            <button on_click={go_about}>"Go to About"</button>
        </div>
    )
}

#[wasm_bindgen::prelude::wasm_bindgen(start)]
pub fn main() {
    Router::new("root")
        .route("/",      Home)
        .route("/about", About)
        .start();
}

Cargo.toml Dependencies

Add the following to your project's Cargo.toml:

[dependencies]
oxirast-core   = "0.1.1"
oxirast-parser = "0.1.1"
wasm-bindgen   = "0.2"

[lib]
crate-type = ["cdylib"]

Project Structure (Scaffolded App)

my_app/
โ”œโ”€โ”€ Cargo.toml
โ”œโ”€โ”€ Cargo.lock
โ”œโ”€โ”€ public/
โ”‚   โ”œโ”€โ”€ index.html     # HTML shell โ€” Oxirast mounts into <div id="root">
โ”‚   โ””โ”€โ”€ style.css      # Global styles
โ””โ”€โ”€ src/
    โ”œโ”€โ”€ lib.rs         # Entry point & Router configuration
    โ””โ”€โ”€ pages/
        โ”œโ”€โ”€ home.rs
        โ””โ”€โ”€ about.rs

Roadmap

  • Signal<T> fine-grained reactivity
  • rsx! macro โ€” HTML-like declarative UI
  • bind_text directive
  • on_* event listener attributes
  • Client-side SPA Router with History API
  • use_state / use_fetch hooks
  • Context API (provide_context / use_context)
  • Automatic Wasm-to-JS GC (memory reaper)
  • Zero-config CLI (init + serve)
  • oxirast-cli build โ€” optimised release builds with wasm-opt
  • oxirast-cli clean
  • --template flag for init
  • oxirast.toml project configuration
  • Server-Side Rendering (SSR)
  • Component hot-module replacement (HMR)
  • bind_attr directive for reactive HTML attributes

Contributing

Contributions are welcome. Please open an issue first to discuss any significant changes.

  1. Fork the repository
  2. Create a feature branch โ€” git checkout -b feat/your-feature
  3. Commit your changes โ€” git commit -m "feat: add your feature"
  4. Push to the branch โ€” git push origin feat/your-feature
  5. Open a Pull Request

License

MIT License ยฉ Michael (kinuthia)

See LICENSE for the full text.