Write frontend apps in Rust. The solid-rs CLI parses your Rust source and
transpiles it to plain JavaScript that runs on the
SolidJS 2.0 runtime. No WASM on the
mainline — the browser runs generated JS.
Status: work in progress. This is an early, moving target: it compiles against Solid 2.0 release candidates (
solid-js@2.0.0-rc.1, pinned), the API surface grows frequently, and nothing here is stable. Expect breakage.
Your Rust is source, not something rustc compiles for the browser. The
framework reads the Rust AST with syn, type-checks it against a conservative
model of the Solid API, and emits JSX modules that esbuild bundles against the
Solid 2.0 runtime:
use solid_rs::prelude::*;
#[component]
fn Counter() -> Jsx {
let (count, set_count) = create_signal(0);
let double = create_memo(move || count() * 2);
html! {
<div class="counter">
<p>Count: {count()}</p>
<p>Double: {double()}</p>
<button onclick=move || set_count(count() + 1)>+</button>
{if count() > 5 { <span>big</span> } else { <span>small</span> }}
</div>
}
}The transpiler is the compiler: the Rust is never type-checked by rustc, so
solid-rs build is the source of truth for what your code means.
Requirements: Rust (nightly) and Node.js ≥ 18 with npm on PATH.
cargo install solid-rs
solid-rs init my-app # scaffold a project
cd my-app
solid-rs install # npm packages declared in solid-rs.toml
solid-rs dev # build, serve on :3000, rebuild on changesCLI subcommands:
| Command | What it does |
|---|---|
solid-rs init <dir> |
Scaffold a new project |
solid-rs install |
Install [dependencies] from solid-rs.toml into node_modules/ |
solid-rs build |
Parse src/*.rs, emit dist/js/*.jsx, bundle with esbuild |
solid-rs check |
Parse + codegen only; print or write the emitted JSX |
solid-rs dev |
Build, serve dist/, rebuild on src/ changes |
solid-rs preview |
Serve dist/ (per-request SSR when the build produced one) |
solid-rs bindings |
Regenerate bindings/<pkg>.rs from installed dependencies |
solid-rs wasm new/build |
Scaffold / build optional wasm-bindgen crates under wasm/ |
A project is a directory with solid-rs.toml (entry, mode, output, npm
dependencies) and src/*.rs — one module per file, #[component] functions
become components, module-level consts become shared bindings.
solid-rs/
├── crates/
│ ├── solid-rs-core/ # IR types + syn-based parser + type validation
│ ├── solid-rs-codegen/ # IR → JavaScript/JSX emitter
│ └── solid-rs/ # the `solid-rs` CLI binary
├── examples/ # runnable apps, each with e2e tests
├── SPEC.md # the design document (architecture, semantics, constraints)
└── comparison.md # API-by-API parity table vs SolidJS 2.0
Each example builds with solid-rs build and has jsdom-based e2e tests under
e2e/.
| Example | What it shows |
|---|---|
comparison |
The feature lab: one section per group of Solid 2.0 APIs |
ssr |
Server-side rendering, #[server_state], async memos, lazy!, server components and a hand-built frame |
tasks |
"Momentum" — a client-side task manager (store, fetch, Portal, lazy loading) |
blog |
"Dispatch" — a server-rendered blog with routing and a newsletter form |
deps |
npm packages from solid-rs.toml via #[js(…)] extern blocks (router, Kobalte, timer) |
compute |
The WASM escape hatch: Rust that is compiled, not transpiled |
flight |
Single-flight mutations: a mutation and the data it invalidated, in one round trip |
- SPEC.md — the design document: vision, architecture, the Rust API surface, transpilation semantics, and known constraints.
- comparison.md — parity table: every Solid 2.0 API, whether solid-rs supports it, and how.
cargo test --workspace # parser, codegen, and validation unit testsExample e2e suites run against the built bundles:
cd examples/tasks && solid-rs build && node e2e/render.mjs && node e2e/reactivity.mjsTBD — see individual crates.