Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
659 changes: 390 additions & 269 deletions Cargo.lock

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ members = [
resolver = "2"

[workspace.package]
version = "0.1.0"
version = "0.0.1"
edition = "2021"
authors = ["Microsoft Edge"]
license = "MIT"
Expand All @@ -24,12 +24,12 @@ env_logger = "0.11.9"
async-trait = "0.1.89"
tokio = { version = "1.49.0", features = ["full"] }
clap = { version = "4", features = ["derive", "color"] }
console = "0.15"
console = "0.16.2"
ctrlc = "3.4"
prost = "0.13"
prost = "0.14.3"
napi = { version = "3", features = ["napi4"] }
napi-derive = "3"
wasm-bindgen = "0.2"
wasm-bindgen = "=0.2.100"
serde-wasm-bindgen = "0.6"
actix-web = "4.11.0"
expand-tilde = "0.6.1"
Expand All @@ -41,7 +41,7 @@ tree-sitter-html = "0.23.2"
tree-sitter-css = "0.25.0"
walkdir = "2.5.0"
libc = "0.2.182"
which = "7"
which = "8.0.1"
windows = { version = "0.62.2", features = [
"Win32_Foundation",
"Win32_System_LibraryLoader",
Expand All @@ -55,7 +55,7 @@ tempfile = "3.25.0"
tokio-test = "0.4.5"

# Build dependencies
prost-build = "0.13"
prost-build = "0.14.3"
napi-build = "2"
cbindgen = "0.29.2"

Expand Down
47 changes: 42 additions & 5 deletions DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -466,14 +466,14 @@ pub struct HtmlParser {
/// Strategy for how component CSS is delivered in rendered output.
pub enum CssStrategy {
/// Emit `<link rel="stylesheet" href="./component.css">` tags (default).
External,
Link,
/// Embed CSS content inline in `<style>` tags within the shadow DOM template.
Inline,
Style,
}
```

- **External** (default): Emits `<link>` tags referencing external `.css` files. Used by the CLI for production builds where CSS files are served separately.
- **Inline**: Embeds the full CSS content in `<style>` tags inside the shadow DOM template. Used when all files are needed in-memory.
- **Link** (default): Emits `<link>` tags referencing external `.css` files. Used by the CLI for production builds where CSS files are served separately.
- **Style**: Embeds the full CSS content in `<style>` tags inside the shadow DOM template. Used when all files are needed in-memory.

Set via `parser.set_css_strategy(CssStrategy::Inline)`.

Expand Down Expand Up @@ -518,7 +518,7 @@ parser.parse("index.html", &html)?;
**CLI integration:**
```bash
webui build ./templates --out ./dist --plugin=fast
webui start ./templates --state ./data/state.json --plugin=fast
webui serve ./templates --state ./data/state.json --plugin=fast
```
#### Content Processing

Expand Down Expand Up @@ -678,6 +678,7 @@ pub enum ParserError {
```
webui/
├── crates/
│ ├── webui/ # Programmatic library API (build, inspect, re-exports)
│ ├── webui-cli/ # CLI build tool (binary: "webui")
│ ├── webui-discovery/ # External component discovery (npm, paths)
│ ├── webui-expressions/ # Expression evaluation engine
Expand All @@ -689,11 +690,47 @@ webui/
│ ├── webui-state/ # State management
│ ├── webui-test-utils/ # Testing utilities
│ └── webui-wasm/ # WebAssembly bindings
├── packages/
│ └── @microsoft/
│ ├── webui/ # npm package (CLI + programmatic JS API)
│ ├── webui-darwin-arm64/ # Platform binary (macOS ARM64)
│ ├── webui-darwin-x64/ # Platform binary (macOS x64)
│ ├── webui-linux-x64/ # Platform binary (Linux x64)
│ ├── webui-linux-arm64/ # Platform binary (Linux ARM64)
│ ├── webui-win32-x64/ # Platform binary (Windows x64)
│ └── webui-win32-arm64/ # Platform binary (Windows ARM64)
├── examples/ # Example applications
├── docs/ # Documentation
├── tests/ # Integration tests
└── benchmarks/ # Performance benchmarks
```

### Crate Dependency Graph

```
webui-cli ──────► webui (library) ◄────── webui-node
│ │
├── webui-parser ├── webui-handler
├── webui-handler ├── webui-protocol
├── webui-protocol └── serde_json
└── webui-discovery

webui-ffi ──────► webui-handler ◄────── webui-wasm
webui-parser webui-parser
webui-protocol webui-protocol
```

The `webui` library crate is the primary API surface for programmatic use.
It re-exports `WebUIHandler`, `ResponseWriter`, and `WebUIProtocol` from their
respective crates and provides `build()`, `build_to_disk()`, and `inspect()`
functions with `BuildStats` (duration, fragment/component/CSS counts, protocol size).

### npm Distribution

The `@microsoft/webui` npm package follows the esbuild single-package model:
- `bin: { "webui": "bin/webui" }` — CLI binary via platform-specific `optionalDependencies`
- `main: "lib/main.js"` — Programmatic API that loads the `.node` native addon directly
- WASM fallback for render when native addon is unavailable (one-time warning logged)
### Documentation Guidelines
- Using `vitepress` in `docs/`
- API documentation for all public interfaces
Expand Down
145 changes: 48 additions & 97 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,121 +1,72 @@
# WebUI

A high-performance, truly cross-platform web framework leveraging native web technologies, built with Rust.
A high-performance server-side rendering framework built with Rust. No JavaScript runtime required.

## Overview
**📖 Documentation & Usage → [microsoft.github.io/webui](https://microsoft.github.io/webui)**

WebUI is a framework that transforms standard HTML/CSS templates into a platform-agnostic protocol that can be rendered natively across any environment - without JavaScript runtime dependencies. Dynamic Server Side Rendering without Node.js.

The framework represents a paradigm shift in web development:

- **Truly Cross-Platform**: Run identical templates in Rust, Go, .NET, and other environments without requiring Node.js or any JavaScript runtime
- **Native Performance**: Built with Rust for unparalleled efficiency and minimal overhead compared to JavaScript-based frameworks
- **Familiar Developer Experience**: Uses standard HTML templates, web components, and CSS you already know
- **Zero Runtime Dependencies**: No need for Node.js, npm modules, or browser polyfills - templates run directly on native code
- **Type Safety**: Strongly typed interfaces ensure reliable component integration across language boundaries
- **Small Footprint**: Minimal binary size with no bloated dependencies

WebUI enables you to write web-based UIs once and deploy them anywhere - from cloud servers to embedded devices - with consistent rendering and superior performance.

## Core Architecture
WebUI follows a modular architecture with four primary components:

- **Protocol:** Defines the structural representation of UI components using a serializable format
- **Parser:** Processes HTML/CSS templates into protocol structures at build time
- **Expression Evaluation:** Handles conditional logic for dynamic rendering
- **Handler:** Renders protocol with state data into final HTML output at runtime
- **Plugin System:** Extensible hooks for framework-specific behavior (parsing + rendering) without modifying core logic

## How It Works
- **Write Standard HTML/CSS:** Create templates with familiar syntax plus WebUI directives (`<for>`, `<if>`, `{{signals}}`)
- **Parse to WebUIProtocol:** Templates compile to a lightweight, language-agnostic protocol at build time
- **Native Rendering:** The protocol is rendered with your data using a platform-specific handler in your language of choice
- **Efficient Output:** The handler produces optimized HTML with Web Component support
- **Framework Plugins:** Optional plugins (e.g., `--plugin=fast`) inject hydration markers for client-side frameworks like FAST-HTML

## Getting Started

### Prerequisites

- Rust toolchain (1.80+)
- Node.js (22+) with pnpm
- Go (1.18+) - optional
- .NET SDK (8.0+) - optional

### Building
## Install

```bash
# Clone the repository
git clone https://github.com/microsoft/webui.git
cd webui

# Build Rust components
cargo build --release
npm install @microsoft/webui
```

### Using the CLI

The `webui` CLI builds your app folder into the WebUI protocol format:

```bash
# Build an app (outputs protocol.bin and component CSS to the out folder)
cargo run -p webui-cli -- build ./my-app --out ./dist
Or with Rust: `cargo install webui-cli`

# Build with the FAST plugin for hydration support
cargo run -p webui-cli -- build ./my-app --out ./dist --plugin=fast
## Development

# Specify a custom entry file
cargo run -p webui-cli -- build ./my-app --out ./dist --entry page.html

# Build the hello-world example
cargo run -p webui-cli -- build examples/app/hello-world/src --out ./dist
```

After building with `--release`, use the binary directly:

```bash
webui build ./my-app --out ./dist
```
### Prerequisites

### Building the WASM Playground
- Rust 1.93+ with `clippy` and `rustfmt`
- Node.js 22+ with pnpm

The interactive playground runs WebUI in the browser via WebAssembly. The WASM output is committed to the repo — most developers don't need to rebuild it. Only rebuild when you change Rust code in the core crates:
### Commands

```bash
cargo xtask build-wasm
```
All development tasks go through `cargo xtask`:

### Running Benchmarks
| Command | Description |
|---------|-------------|
| `cargo xtask check` | **Run before every commit.** Runs fmt → clippy → deny → test → build → docs |
| `cargo xtask fmt` | Check formatting |
| `cargo xtask clippy` | Run clippy lints |
| `cargo xtask deny` | License & advisory audit |
| `cargo xtask test` | Run all tests |
| `cargo xtask build` | Build the workspace + examples |
| `cargo xtask build-wasm` | Build WASM playground module |
| `cargo xtask docs` | Build the documentation site |
| `cargo xtask bench <crate>` | Run benchmarks (parser, handler, protocol, expressions, state, all) |
| `cargo xtask dev <app>` | Run example app in dev mode |
| `cargo xtask version <semver>` | Update version across all Cargo.toml and package.json files |

WebUI includes [Criterion](https://github.com/bheisler/criterion.rs) benchmarks for all core crates. Run them in release mode for accurate results:
### Project Structure

```bash
# Run benchmarks for a specific crate
cargo bench -p webui-parser
cargo bench -p webui-handler
cargo bench -p webui-protocol
cargo bench -p webui-expressions
cargo bench -p webui-state

# Run all benchmarks across the workspace
cargo bench --workspace
```

### Development Server

Preview your app using the built-in dev server. Add `--watch` to enable live reload:

```bash
webui-cli start examples/app/hello-world/templates --state examples/app/hello-world/data/state.json --servedir examples/app/hello-world/assets --watch
crates/
├── webui/ # Library API (build, inspect, re-exports)
├── webui-cli/ # CLI binary
├── webui-node/ # Node.js native addon (napi-rs)
├── webui-ffi/ # C-compatible FFI bindings
├── webui-wasm/ # WebAssembly bindings
├── webui-parser/ # HTML/CSS parser
├── webui-protocol/ # Protocol definition (protobuf)
├── webui-handler/ # Rendering engine
├── webui-expressions/ # Expression evaluator
├── webui-state/ # State management
├── webui-discovery/ # Component discovery
└── webui-test-utils/ # Shared test helpers
packages/
└── webui/ # @microsoft/webui npm package
docs/ # VitePress documentation site
```

This builds, renders, and serves the app at `http://127.0.0.1:3000/`. With `--watch`, file changes trigger automatic reload.
### Key Files

For runnable sample apps and integration walkthroughs, see [examples/README.md](examples/README.md).
- [`DESIGN.md`](DESIGN.md) — Technical specification (the source of truth)
- [`clippy.toml`](clippy.toml) — Lint policy (no `unwrap`/`expect`, complexity ≤ 20)
- [`deny.toml`](deny.toml) — License allowlist & advisory audit

## Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a
This project welcomes contributions and suggestions. Most contributions require you to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.

Expand All @@ -129,8 +80,8 @@ contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additio

## Trademarks

This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft
trademarks or logos is subject to and must follow
This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft
trademarks or logos is subject to and must follow
[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general).
Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship.
Any use of third-party trademarks or logos are subject to those third-party's policies.
Expand Down
3 changes: 1 addition & 2 deletions crates/webui-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ name = "webui"
path = "src/main.rs"

[dependencies]
webui-parser = { path = "../webui-parser" }
webui-protocol = { path = "../webui-protocol" }
webui = { path = "../webui", features = ["cli"] }
webui-handler = { path = "../webui-handler" }
webui-discovery = { path = "../webui-discovery" }
clap = { workspace = true }
Expand Down
6 changes: 3 additions & 3 deletions crates/webui-cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ Example:
webui inspect ./dist/protocol.bin
```

### `webui start`
### `webui serve`

Starts a dev server with build+render. Live reload/HMR is optional via `--watch`.

```bash
webui-cli start [APP] --state <FILE> [--servedir <DIR>] [--watch] [--port <PORT>] [--entry <FILE>] [--css <MODE>]
webui-cli serve [APP] --state <FILE> [--servedir <DIR>] [--watch] [--port <PORT>] [--entry <FILE>] [--css <MODE>]
```

- `APP`: template/component directory (default `.`)
Expand All @@ -79,7 +79,7 @@ Behavior:
Example:

```bash
webui-cli start ./examples/app/hello-world/templates \
webui-cli serve ./examples/app/hello-world/templates \
--state ./examples/app/hello-world/data/state.json \
--servedir ./examples/app/hello-world/assets \
--watch \
Expand Down
Loading
Loading