Expand description
§islands — umbrella crate for islands.rs
This is the single dependency users should add to consume the islands.rs framework.
All public APIs from the underlying sub-crates are re-exported here so a downstream
Cargo.toml looks like:
[dependencies]
islands = { path = "...", features = ["basecoat"] } # basecoat optionaland a downstream main.rs looks like:
use islands::prelude::*;§What’s in the box
The framework is a Rust SSR + island-hydration system with shared-core WASM code
splitting. The server emits plain HTML with labelled island markers; each island is
mounted independently on the client. No whole-page hydration, no virtual-DOM
reconciliation, no hydration-mismatch failure mode. See plan.md for the full
architectural rationale.
Modules at a glance:
| Re-export | What it provides |
|---|---|
island_marker, page_shell, [page_shell_streaming_head] | Server-side HTML markup helpers that emit island placeholders, the document shell, and the streaming-shell head fragment. |
[Suspense], [render_streaming], [render_streaming_with], [HtmlChunk], [StreamError], [REPLACE_SCRIPT] | Streaming SSR with Suspense boundaries — out-of-order chunk delivery, <template> + $ISLANDS_REPLACE script-based slot filling. |
Manifest, ManifestEntry | Content-hashed asset manifest loaded at startup; page_shell resolves URLs through it. |
cn | Tailwind class-string merger with shadcn-style conflict resolution. |
Signal, register_island, mount_all, init_panic_hook, on_click, on_event, set_class, text_binding, call_action, [navigate] | WASM page-author API (available on both wasm32-unknown-unknown and the host target — the rlib path is unconditional). [navigate] triggers client-side navigation programmatically (same path as a link click; full-load fallback on error). |
action_router, ActionContext, ActionError, ActionRegistry (non-wasm) | Server-side typed-action plumbing. |
cache_layer (non-wasm) | Tower middleware that sets Cache-Control by path pattern and honors If-None-Match for 304 responses on static assets. |
actions_shared | Re-exported sub-crate of pure types shared between server and WASM (request/response shapes). |
basecoat_core, basecoat_components, basecoat_css (behind the basecoat feature) | shadcn-style UI components and rsx macros, opt-in. |
§Suspense — API shape
[Suspense] is invoked through rsx interpolation rather than as a literal tag,
because the basecoat-macros rsx! macro auto-routes PascalCase tags to
::basecoat_components::<snake>. (Consumers that want rsx! add basecoat-macros
as their own direct dependency — islands does not pull it for them; see “The
basecoat feature” below.)
rsx! {
section class="page" {
{ islands::Suspense::new(
rsx! { div class="skeleton h-9 w-32" {} },
async move { island_marker("Counter", &props, body) }
).render() }
}
}Suspense is streaming-only — it is valid only inside [render_streaming] /
[render_streaming_with]. Using it from a non-streaming render path panics at runtime
with RenderStreamContext not active. Non-streaming pages should call
island_marker directly.
§The basecoat feature
basecoat is off by default. Enabling it pulls in the basecoat UI component layer
(basecoat-core / basecoat-components / basecoat-css). The proc-macro layer
(basecoat-macros + basecoat-macros-rt) is not pulled by islands or
islands-core at all — a consumer that wants rsx! adds those two crates as direct
dependencies themselves. This keeps the islands.rs dep tree zero-cost for consumers
that only need the SSR primitives and write their HTML another way.
When the feature is on, cargo xtask materializes assets/css/basecoat.css with
the full basecoat utility classes; when off, the same file is written as a 2-line
disabled stub so the @import "./basecoat.css"; in base.css always resolves but
contributes no rules. Toggle at build time via the ISLANDS_FEATURES env var.
§Prelude
See the prelude module for a curated subset of the above suitable for
use islands::prelude::*; in most pages and server modules.
Re-exports§
Modules§
- prelude
- Curated re-exports for
use islands::prelude::*;.
Structs§
- Action
Context - Context passed to every action invocation.
- Action
Registry - Registry mapping action names to their handlers.
- Manifest
- Asset manifest mapping bundle names to their hashed file paths.
- Manifest
Entry - A single entry in the asset manifest for one page bundle.
- Route
Entry - One page route: the URL
path, the asset-manifestbundlekey ("<example>/<page>", e.g."counter/page-about"), and the Axummethod_routerthat serves it. - Route
Table - An ordered table of page routes. The one declaration that builds the router AND emits the nav manifest (AC-N1).
- Signal
Enums§
- Action
Error - Typed error enum for server actions.
- Core
Error
Functions§
- action_
router - Build an Axum router that exposes all registered actions at
/_action/:name. - cache_
layer - Returns a
tower::Layerthat performs three jobs on every response: - call_
action - cn
- Merge Tailwind class strings, with later classes winning on conflicts.
- init_
panic_ hook - island_
marker - Renders an island marker with serialized props and initial server-rendered HTML.
- mount_
all - on_
click - on_
event - page_
shell - Renders a complete HTML page shell for an interactive (island-bearing) page: base + page stylesheets, the shared core module, and the page’s WASM module.
- page_
shell_ static - Renders a complete HTML page shell for a non-interactive page that has no island, hence no page WASM bundle.
- register_
island - set_
class - text_
binding