Sycamore Documentation
repository·main·Indexed 25 days ago
https://github.com/sycamore-rs/sycamoreSycamore is a reactive Rust library for building high-performance web applications via WebAssembly. It utilizes fine-grained reactivity instead of a virtual DOM to provide an ergonomic developer experience. Key features include the view! macro for components, a dedicated router for SPAs, Server-Side Rendering (SSR) support, and attribute passthrough for custom components.
What's inside Sycamore
- Sycamore is a reactive library for creating web applications using Rust and WebAssembly. It uses fine-grained reactivity instead of a virtual DOM, allowing for high performance and an ergonomic developer experience without requiring JavaScript.
Explore Sycamore example patterns
mainSycamore provides various examples demonstrating different features and patterns. Key examples include:
- Core UI & Logic:
counter(simple state),iteration(looping over data),components(UI abstraction), andhigher-order-components(functions that create components). - Data & Async:
http-requestandhttp-request-builder(Suspense + async components for HTTP),timer(using futures), andtransitions(Suspense + async transitions). - Routing & Navigation:
router(demonstratingsycamore-router). - Rendering Strategies:
ssr(Server-Side Rendering),ssr-suspense(SSR with suspense),ssr-streaming(SSR with streaming), andhydrate(making existing HTML reactive). - Advanced UI:
motion(animation frames and tweened signals),svg(creating SVGs with theview!macro), andattributes-passthrough(dynamic attributes).
- Core UI & Logic:
Build websites with Perseus
mainPerseus is a web framework built on top of Sycamore designed for building isomorphic web applications with Rust and WebAssembly. It provides features like static generation, server-side rendering (SSR), revalidation, and incremental regeneration without requiring JavaScript.Getting started with Sycamore
mainTo begin using Sycamore, you can either explore the official examples in the repository to see practical implementations, or read through the Sycamore Book for a structured learning path. For community support and quick questions, you can join the Discord server.Interpolate values in views
mainYou can interpolate any value that implements
Into<View>, such as strings, numbers, signals, or other views. When using complex expressions or signals, theview!macro automatically wraps them in a closure to create a dynamic view.let value = 123; let signal = create_signal(456); view! { p { "Value: " (value) } p { // Automatically becomes a dynamic view (signal.get() + 1) } }Set node refs with r#ref
mainUse the
r#refattribute to assign aNodeRefto an element, allowing you to access the underlying DOM node.let node = create_node_ref(); view! { button(r#ref=node) }Run Sycamore tests
mainYou can run tests for the entire workspace or for specific packages.
All tests:
cargo test --all-featuresPackage-specific tests (e.g., sycamore-reactive):
cd packages/sycamore-reactive cargo test --all-featurescargo test --all-featuresRun WASM tests with wasm-pack
mainTo run WASM-specific tests, ensure
wasm-packis installed. You can run tests in a visible browser (like Chrome) or in headless mode.Chrome tests:
cd packages/sycamore wasm-pack test --chrome --all-featuresHeadless tests: Add the
--headlessflag to the command above.cd packages/sycamore wasm-pack test --chrome --all-featuresHandle events in views
mainUse the
on:*directive in theview!macro to attach event handlers (e.g.,on:click).Example of an inline handler:
view! { button(on:click=move |_| counter.set(counter.get() + 1)) { "Increment" } }let mut counter = create_signal(1); let increment = move |_| counter += 1; view! { button(on:click=increment) { "Increment" } p { "Count: " (counter) } }Use CSS frameworks with Sycamore
mainYou can use any CSS framework with Sycamore. Serve the framework's CSS file using Trunk, and then apply the framework's classes directly within your Sycamore component code as you would in standard HTML.Use the new reactivity system in Sycamore v0.8
mainSycamore v0.8 introduced a major breaking change to the reactivity system. The reactive scope (
cx) is now explicitly passed to hooks and functions instead of being tracked globally. Additionally, closures no longer require'staticlifetimes, meaning you can access local variables directly without cloning signals into event handlers or effects.// New v0.8 syntax. let signal = create_signal(cx, 123); create_effect(cx, || { let _ = signal.get(); }); view! { cx, div {} }Add a new example to Sycamore
mainTo contribute a new example:
- Add your example to the
examples/folder. (Tip: Clone an existing example and update the folder name andCargo.toml). - Register the example in
examples/README.mdwith a brief description of its purpose.
- Add your example to the