rfw (Reactive Framework) is a Go-based reactive framework for building web applications with WebAssembly. The framework source code lives in versioned packages such as v1/core, while an example application can be found in docs/.
# install the CLI
curl -L https://github.com/rfwlab/rfw/releases/download/continuous/rfw -o ~/.local/bin/rfw && chmod +x ~/.local/bin/rfw
# ensure ~/.local/bin is in your PATH, if not, add it
export PATH=$PATH:~/.local/bin
# bootstrap a project
rfw init github.com/username/project-name
# run the development server
rfw dev
# build for production
rfw buildBy default the development server listens on port 8080. Override it with
the --port flag or the RFW_PORT environment variable:
RFW_PORT=3000 rfw devControl server log verbosity with the RFW_LOG_LEVEL environment variable.
Possible values are debug, info, warn, and error (default is info):
RFW_LOG_LEVEL=debug rfw dev
Enable the in-browser debugging overlay with the --debug flag:
rfw dev --debug
Use Ctrl+Shift+D in the browser to toggle the overlay that shows the
component tree and console logs with basic runtime metrics.
Read the documentation for a complete guide to the framework.
Run all tests with:
go test ./...Continuous Integration runs the same command on every push. See the testing guide for more details.
SSC mode runs most application logic on the server while the browser loads a lightweight Wasm bundle to hydrate server-rendered HTML. The server and client keep state synchronized through a persistent WebSocket connection. See the SSC guide for more details.
rfw exposes a simple plugin system for build-time tasks. The CLI
automatically detects PreBuild, Build and PostBuild methods on plugins
and invokes them when present. Each plugin must still provide a file-watcher
trigger via ShouldRebuild and a numeric Priority to determine execution
order.
rfw includes a build step for Tailwind CSS using the official standalone CLI.
Place an input.css file (commonly under static/) containing the @tailwind directives in your project. During development the server watches
template, stylesheet and configuration files and emits a trimmed tailwind.css
containing only the classes you use, without requiring Node or a CDN.
The built-in pages plugin scans a pages/ directory and automatically
registers routes based on its structure. Each Go file maps to a URL path:
pages/
index.go // -> /
about.go // -> /about
posts/[id].go // -> /posts/:id
Every file must expose a constructor using the PascalCase form of its path,
such as func About() core.Component. The plugin generates a temporary
routes_gen.go that calls router.RegisterRoute for each page during the
build. Import the generated package to execute the registrations, typically
via a blank import in your entrypoint:
import _ "your/module/pages"
A working example can be found under docs/examples/pages, which
contains index.go, about.go and posts/[id].go demonstrating the
generated routes /, /about and /posts/:id. The documentation site in
this repository uses the pages plugin for its home (/) and about (/about)
pages, while the docs plugin continues to power the documentation
content itself.
For more details and best practices, see the Pages Plugin guide.