Most hybrid frameworks treat the WebView as a black box — you load a URL and hope for the best. When your frontend needs to read a file, query a database, or call an AI model, you're back to building HTTP APIs, managing ports, and serializing everything by hand.
Fulora takes a different approach: the web frontend and the native host share a typed contract layer that is enforced at compile time. The runtime handles serialization, routing, lifecycle, and error propagation — your code on both sides just calls methods and gets typed results back.
┌──────────────────────────────────────────────────────────┐
│ Your Application │
│ Avalonia UI + Web Frontend + Bridge Contracts │
└──────────────────────────────┬───────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────┐
│ Platform Kernel + Capability/Experience Planes │
│ Typed Bridge · Capability Gateway · Policy Engine │
│ Diagnostics Pipeline · Shell Experience · SPA Hosting │
└──────────────────────────────┬───────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────┐
│ Adapter Abstraction Layer │
│ IWebViewAdapter + Facets │
└──────────────────────────────┬───────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────┐
│ WebView2 (Win) · WKWebView (macOS/iOS) · Android WV │
│ WebKitGTK (Linux) │
└──────────────────────────────────────────────────────────┘
The key insight: your application code never touches the WebView engine directly. Fulora's four-layer model (product layer -> platform kernel -> capability/experience planes -> adapter layer) mediates bridge calls, capability requests, SPA hosting, and diagnostics through well-defined abstractions. This is what makes the same app code run on five platforms without #if blocks.
The bridge is the heart of Fulora. It turns C# interfaces into callable services on both sides of the boundary:
[JsExport]— a C# interface whose implementation lives in the native host, callable from JavaScript[JsImport]— a C# interface whose implementation lives in JavaScript, callable from C#
A Roslyn source generator produces all marshalling code at compile time. There is no reflection, no dynamic proxies, no runtime code generation — which means it works with Native AOT out of the box.
Under the hood, calls travel as JSON-RPC messages over the WebView's message channel. But you never see this — you write await GreeterService.greet("World") in JavaScript and get a typed result back.
Methods returning IAsyncEnumerable<T> in C# become AsyncIterable in JavaScript. This powers scenarios like AI token streaming, live sensor data, and file content streaming — with proper backpressure and cancellation (AbortSignal maps to CancellationToken).
Not every bridge call is a simple request-response. Some operations — file access, network requests, system notifications — need governance. The capability gateway provides this:
- A capability request enters through the typed gateway
- The policy engine evaluates authorization rules before any execution happens
- The provider executes only when policy permits
- A deterministic result is returned:
allow,deny, orfailure - A diagnostics event is emitted for observability
This means your app's security model is declarative and auditable, not scattered across if checks.
The IWindowShellService gives the web frontend control over native window properties:
- Theme — light, dark, or follow system
- Transparency — Mica (Windows 11), Acrylic, Blur, or None
- Custom chrome — drag regions, interactive exclusion zones
- State streaming —
streamWindowShellState()pushes theme changes, transparency changes, and chrome metrics to the frontend in real time
For apps that register OS protocol handlers:
OS Protocol Handler → DeepLinkPlatformEntrypoint
→ DeepLinkRegistrationService (normalize → policy → idempotency)
→ WebViewShellActivationCoordinator (primary/secondary dispatch)
→ Your handler
Secondary instances forward activation to the primary. Duplicate activations are suppressed via idempotency keys. Every lifecycle stage emits structured diagnostics.
- Origin policy — only declared origins can send bridge messages
- Capability policy — explicit evaluation before host operations execute
- Rate limiting — bounded request pressure on bridge and capability paths
- Explicit exposure — only registered contracts are reachable from web content
- Contract tests validate bridge behavior independent of any platform WebView engine
- Integration tests validate runtime wiring on real platform adapters
- Automation lanes validate governance and diagnostics expectations for release readiness
MockBridgeServiceenables unit testing without a real browser
- Getting Started — Build your first app
- Bridge Guide — Advanced bridge patterns
- Product Platform Roadmap — Product direction and capability tiers
- Platform Status — Governed status page and release-line snapshot publication location