Library / SDK
sycamore-rs/sycamore avatar
sycamore-rs/sycamore

Sycamore: a Rust and WebAssembly library built on fine-grained reactivity

A library for creating reactive web apps in Rust and WebAssembly

3,358 stars169 forksRustMIT

At a glance

What is it?
Sycamore renders reactive web UIs in Rust without a virtual DOM, and its repository ships a workspace of packages plus a large examples directory. Here is how the pieces fit, what installing it looks like, and where it stops being the right choice.
Who is it for?
Pick Sycamore if you already write Rust, want signals rather than a virtual DOM, and are willing to follow the Book and the examples directory rather than a large third-party ecosystem. Skip it if you need native or mobile targets, since the README points Dioxus at that role, or if your team will not accept a Rust toolchain in the front-end build.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 31 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What Sycamore is for, and who ends up using it

Sycamore is a reactive library for building web apps in Rust compiled to WebAssembly. The README states the goal plainly: create apps without touching a single line of JavaScript. The audience is therefore narrow and specific. You need to be comfortable in Rust, you need a WebAssembly target installed, and you need to accept that the browser bundle is produced by a Rust build rather than by a JavaScript bundler.

The library targets the browser. The README's alternatives section is explicit about the boundary: Dioxus, it notes, can target native and mobile because it uses a virtual DOM, while Sycamore does not. So if your roadmap includes an iOS or Android build from the same component tree, Sycamore is the wrong starting point. It is aimed at people who want a single-language front end for the web and who care about how the DOM is updated.

The repository layout confirms the scope. The Cargo.toml lists a workspace with packages for the core crate, macros, reactivity, futures, the router and its macro crate, a view parser, and a web layer. There is no desktop or mobile package in that list.

Fine-grained reactivity instead of a virtual DOM

The README describes the mechanism as reactive primitives without a cumbersome virtual DOM. In practice that means the view macro produces DOM nodes once, and state changes are wired to update those specific nodes rather than re-running a component function and diffing a tree of descriptions.

The topics on the repository name the same idea: fine-grained-reactivity, signals, wasm. A component in the README's example is a function annotated with the component attribute that returns a View, and the view macro builds that view from a Rust-like block syntax. There is no separate template language and no JSX.

The workspace split tells you where the work happens. sycamore-reactive holds the reactive core, sycamore-core and sycamore-web hold the platform and DOM layers, sycamore-macro and sycamore-view-parser handle the view and component macros at compile time, and sycamore-router plus sycamore-router-macro provide routing. Because the parsing happens in a macro crate, syntax errors in a view surface at compile time rather than in the browser console. That is a real difference from a runtime template compiler, and it is the main reason the compile step matters so much in this workflow.

Server rendering is part of the picture too. The examples directory contains ssr, ssr-suspense, ssr-streaming and hydrate, which is the pattern you would follow if you need HTML delivered before the WebAssembly bundle is ready.

Installing Sycamore and running a first component

The README does not give a cargo add line. It points at the Book for a guided introduction and at the examples directory for working code, and it says the examples build locally with Trunk. The todomvc example is the one the README uses to demonstrate the workflow, so start there rather than with a blank project.

From the repository root, change into an example and serve it:

bash
cd examples/todomvc
trunk serve

Trunk compiles the crate to WebAssembly and serves the result. The README says to open http://localhost:8080 to see the example running. If that page loads the todo list, your Rust WebAssembly toolchain and Trunk are both working, and you can move on to your own crate.

The smallest component in the README is the shape you will write most often:

rust
#[component]
fn Hello() -> View {
    view! {
        p { "Hello World!" }
    }
}

A component is a function returning View, marked with the component attribute, and the view macro contains markup that looks close to HTML. Note what is absent: no return type wrapper, no builder chain, no separate template file. If you prefer a builder-style construction, the examples directory has hello-builder alongside hello-world, which is worth reading if the macro syntax does not suit your taste.

For the crate itself, the workspace manifest pins the version at 0.9.3 and declares the licence as MIT, so a dependency entry should match that version. The workspace also declares edition 2024 and rust-version 1.94. Check your toolchain against that before you start debugging build failures, because an older compiler will fail in ways that have nothing to do with your code.

Where Sycamore gets in the way

The README is honest about one limitation: Leptos, it says, shares many similarities with Sycamore and as of now has a larger community. That is a maintenance consideration, not a technical defect. A smaller community means fewer third-party crates that already integrate, fewer answers when a macro expansion produces an error you cannot read, and more time spent in the source of the workspace packages.

The toolchain requirement is the second constraint. The workspace declares rust-version 1.94 and edition 2024. That is a recent baseline. Teams on an older pinned compiler, or on a CI image that lags, will need to upgrade before the first build succeeds, and that upgrade may pull in unrelated work across the rest of the repository.

Third, the WebAssembly boundary is real. Anything that only exists as a JavaScript library has to be reached through the wasm interop layer. The repository acknowledges this by shipping a js-snippets example, which is the mechanism for embedding JavaScript where you need it. If your application is mostly a thin wrapper around several JavaScript SDKs, the interop code will outweigh the Rust you write, and a JavaScript framework would be the more direct choice.

Finally, the README does not document a rollback or downgrade path for the toolchain or the crate. If you need to pin to an older Sycamore release, that is something to work out from the changelog and the release tags rather than from a documented procedure.

How it compares with Leptos, Dioxus and SolidJS

The README names three alternatives, and the differences it draws are worth taking at face value. SolidJS is a JavaScript library that, in the README's words, greatly inspired Sycamore: fine-grained reactivity and components as factory functions were borrowed from it. If your team is fluent in TypeScript and the only reason you were considering Sycamore is the reactivity model, SolidJS gives you the same model without a WebAssembly build step or a Rust toolchain in the front-end pipeline. The trade is that you are back in JavaScript.

Leptos is the closest comparison, since it is also Rust and also built on fine-grained reactivity. The README's stated difference is community size, not architecture. That distinction matters more than it sounds: with a similar programming model, the deciding factor is often which one has an existing answer for the problem you hit at 2am.

Dioxus takes a different route entirely. It uses a virtual DOM to update the DOM, though it uses fine-grained reactivity for state management, and that choice is what lets it target desktop, mobile and web from one codebase. Sycamore's no-virtual-DOM design is the reason it stays browser-focused. If a single codebase across platforms is a requirement, Dioxus is the one in this list that addresses it.

Releases, licence and the cost of staying current

Sycamore is MIT licensed, and the workspace manifest carries that identifier for the packages. MIT is permissive: you can use the crate in closed-source products, and the obligation is essentially to keep the copyright and licence notice with the distribution. That is a summary of the licence's usual terms, not legal advice, and the LICENSE file at the repository root is the text that governs.

The release cadence is visible in the tags. 0.9.1 was tagged on 2024-11-17, 0.9.2 on 2025-09-23, and 0.9.3 on 2026-08-31, which is also the most recent push to the main branch. The pattern is roughly one minor release a year with a long gap between the first two. For a project at 0.9, that means pre-1.0 semantics: expect the occasional breaking change between minor versions, and read CHANGELOG.md before bumping, because the README does not describe a migration process.

Upgrade cost is mostly toolchain cost. Because the workspace pins rust-version and edition centrally, a Sycamore upgrade and a compiler upgrade tend to arrive together. Budget for that rather than treating the crate bump as a one-line change. The packages are versioned in lockstep at 0.9.3, so you will not be resolving a mix of independently versioned sub-crates.

Editorial conclusion

Pick Sycamore if you already write Rust, want signals rather than a virtual DOM, and are willing to follow the Book and the examples directory rather than a large third-party ecosystem. Skip it if you need native or mobile targets, since the README points Dioxus at that role, or if your team will not accept a Rust toolchain in the front-end build. Before committing, verify that the crate version in your Cargo.toml matches the workspace version 0.9.3, that your toolchain satisfies the rust-version 1.94 declared in the workspace manifest, and that you have a Trunk-based build working on one example.

Frequently asked questions

What is Sycamore?

Sycamore is a reactive library for creating web apps in Rust and WebAssembly, published under the MIT licence. It is built on reactive primitives and signals rather than a virtual DOM, and the repository ships the core crate plus macros, a router and a web layer.

How do you use Sycamore?

You write components as Rust functions annotated with the component attribute, returning a View built with the view macro, then compile to WebAssembly. The README points at the Book for a guided introduction and at the examples directory for working code, and it says the examples can be built locally with Trunk.

How do I run a Sycamore example locally?

The README gives the todomvc example: change into examples/todomvc, run trunk serve, and open http://localhost:8080 in your browser. Trunk compiles and serves the example.

Does Sycamore require writing any JavaScript?

The README states that you can create apps using Sycamore without touching a single line of JS. The repository does include a js-snippets example for cases where you need to embed JavaScript anyway.

Can Sycamore target desktop or mobile apps?

No. The README notes that Dioxus uses a virtual DOM, which allows it to target native and mobile platforms, while Sycamore's fine-grained approach keeps it focused on the browser.

What Rust version does Sycamore need?

The workspace manifest declares rust-version 1.94 and edition 2024, with the packages versioned at 0.9.3. Check your toolchain against that before debugging a build failure.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. sycamore-rs/sycamore on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/sycamore-rs-sycamore.svg)](https://hysenlabs.com/projects/sycamore-rs-sycamore)