diff --git a/package-lock.json b/package-lock.json
index 8677ff8..87ecc00 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,7 +9,7 @@
"version": "0.1.0",
"dependencies": {
"astro": "^5.0.0",
- "traverse-embedder-web": "^0.9.0"
+ "traverse-embedder-web": "0.9.0"
},
"devDependencies": {
"@playwright/test": "^1.63.0"
diff --git a/src/components/DocsSidebar.astro b/src/components/DocsSidebar.astro
index d124f35..b557d5f 100644
--- a/src/components/DocsSidebar.astro
+++ b/src/components/DocsSidebar.astro
@@ -21,6 +21,7 @@ const sections = [
title: 'Guides',
links: [
{ href: '/docs/guides.html', label: 'All Guides' },
+ { href: '/docs/guides/cross-os-capability.html', label: 'Cross-OS Capability' },
{ href: '/docs/guides/mcp-setup.html', label: 'MCP Setup' },
{ href: '/docs/guides/react-integration.html', label: 'React Integration' },
],
diff --git a/src/pages/blog/cross-platform-rarely-means-what-it-sounds-like.astro b/src/pages/blog/cross-platform-rarely-means-what-it-sounds-like.astro
new file mode 100644
index 0000000..e60c2a8
--- /dev/null
+++ b/src/pages/blog/cross-platform-rarely-means-what-it-sounds-like.astro
@@ -0,0 +1,129 @@
+---
+import SubpageLayout from '@layouts/SubpageLayout.astro';
+
+const _body = `
+
+
+
+
← Blog
+
September 10, 2026
+
Industry
+
Portability
+
+
Why "cross-platform" rarely means what it sounds like
+
+ By Enrico Piovesan
+ 7 min read
+
+
+
+
+
+
+
Comparison
+
Traverse vs. Cross-Platform App Frameworks
+
Flutter, Electron, Tauri, React Native, and .NET MAUI solve UI portability: one codebase, one native-feeling app across operating systems. Traverse solves a layer underneath that — one governed business-logic binary that behaves identically no matter which UI framework, backend, or AI agent is calling it. They're not really competing, and you can use them together.
+
+
+
+
+
+
+
+
What cross-platform UI frameworks solve
+
Flutter, Electron, Tauri, React Native, and .NET MAUI all attack the same problem from different angles: write your UI once, ship a native-feeling app on Windows, macOS, Linux, iOS, and Android without hand-building five separate front ends. Flutter and React Native compile or interpret down to native widgets. Electron and Tauri wrap a web view (Electron ships its own Chromium; Tauri uses the OS's own web renderer, which is why its binaries are smaller). .NET MAUI shares one XAML-based UI layer across desktop and mobile.
+
All of them are genuinely good at this. It's a hard, well-understood problem, and each one has years of tooling, hot-reload workflows, and platform-specific escape hatches built up around it.
+
What none of them do is govern what happens once your button's onPressed handler fires. The business logic behind that tap — the pricing rule, the eligibility check, the discount calculation — is just more Dart, JavaScript, or C#, living inside that one app. If your backend, your web dashboard, and your AI agent need the exact same rule, you're re-implementing it in each of their languages and hoping the copies don't drift.
+
+
+
+
What Traverse solves
+
Traverse doesn't compete for the UI layer at all — it has none. What it governs is the rule itself. You write a capability once in Rust, compile it to WebAssembly, and attach a contract that declares its inputs, outputs, preconditions, and postconditions. The runtime validates all of that before and after execution, and produces a structured trace artifact every time the capability runs.
+
That WASM binary is device-independent: it executes locally by default, on whatever client loaded it, and the client can heuristically delegate part of the work to a server when its own context calls for it — not because someone chose "server" as a fixed deployment target ahead of time. The two shipped hosts for that binary today are native (Windows, macOS, Linux, through traverse-runtime's Wasmtime-backed executor) and the browser (through the public Web embedder SDK). Android and .NET/WinUI embedders are real, working code without a public release yet; iOS is blocked on the WASM-engine ecosystem lacking a certifiable resource-control API — see Platforms for the evidence.
+
The distinction: a UI framework decides how your app looks and behaves on each OS. Traverse decides whether a specific rule inside that app is consistent, governed, and auditable everywhere it's called from — including places that have no UI at all, like a batch job or an MCP-connected AI agent.
+
+
+
+
Key differences
+
+ | Dimension | Flutter / Electron / Tauri / MAUI | Traverse |
+
+
+ | Primary unit |
+ A widget tree or DOM — the thing the user sees and touches |
+ A governed WASM capability — the rule the app calls into, with no UI of its own |
+
+
+ | OS reach, shipped today |
+ Windows, macOS, Linux, iOS, and Android are all shipped and mature for every framework in this group |
+ Windows, macOS, Linux (native) and browser are shipped. Android and .NET/WinUI embedders are in progress, unreleased. iOS is blocked on the WASM engine ecosystem — see Platforms. |
+
+
+ | Contract enforcement |
+ None built in — your logic runs as written, with whatever validation you hand-code |
+ Preconditions and postconditions are declared in a machine-readable contract and enforced by the runtime, not by convention |
+
+
+ | Execution record |
+ Whatever logging you add yourself |
+ A structured trace artifact on every execution — capability, version, inputs validated, outputs validated, timing |
+
+
+ | Reuse outside the app |
+ The logic is Dart, JS, or C# inside that app; using it from a backend or AI pipeline means porting it to another language |
+ The same WASM binary and contract are callable from the CLI, an MCP-connected AI agent, or another app, unmodified |
+
+
+ | Primary use |
+ Ship one native-feeling UI across operating systems and devices |
+ Keep one business rule byte-for-byte identical everywhere it's invoked, UI or not |
+
+
+
+
+
+
+
When to use which
+
+
+
Use a cross-platform UI framework when
+
+ - Users need a real native or native-feeling app on desktop and mobile
+ - You want one team shipping UI once instead of five native codebases
+ - The business logic behind the UI is simple enough to live in one place, in one language
+ - You don't need that logic callable from outside this one app
+
+
+
+
Use Traverse when
+
+ - A rule has to produce the same result in the app, the backend, and an AI pipeline
+ - Compliance requires a reproducible, auditable record of what ran and why
+ - Logic drift between rewritten copies is already causing production bugs
+ - You want contracts enforced before execution, not hoped for in code review
+
+
+
+
+
+
+
Running Traverse inside a Tauri app
+
Tauri is the most natural pairing here, because its backend is Rust — the same language Traverse capabilities compile from. The UI stays exactly what Tauri already gives you (a native window rendering your web frontend); a Tauri command just calls into the same governed capability your web dashboard and your AI agent call, through the public traverse-embedder crate.
+
+
+
use traverse_embedder::{BundleEmbedder, EmbedderConfig, TraverseEmbedderApi};
+use tauri::State;
+
+
+pub struct AppState {
+ pub embedder: BundleEmbedder,
+}
+
+#[tauri::command]
+async fn check_discount_eligibility(
+ state: State<'_, AppState>,
+ customer_id: String,
+ cart_total: f64,
+) -> Result<serde_json::Value, String> {
+ let input = serde_json::json!({
+ "customer_id": customer_id,
+ "cart_total": cart_total,
+ });
+
+
+ state.embedder
+ .submit_and_await("promotions.check-eligibility", &input)
+ .await
+ .map_err(|e| e.to_string())
+}
+
+
Tauri's frontend calls check_discount_eligibility like any other Tauri command — it has no idea the answer came from a governed WASM capability instead of hand-written Rust. The window renders whatever Tauri already renders. The rule underneath it is the exact same binary running in your web app and your CI pipeline.
+
+
+
+
The verdict
+
These aren't competitors, because they're not solving the same problem. A UI framework decides how your app looks and feels on five different operating systems. Traverse decides whether one specific rule inside that app is trustworthy, auditable, and identical everywhere it runs — including the places that never had a UI to begin with.
+
If your app's logic is simple, lives in one place, and never needs to run outside that app, you probably don't need Traverse — the UI framework you already picked is enough. If a rule inside that app is load-bearing enough that drift between copies would actually hurt (pricing, eligibility, compliance, anything an AI agent also needs to call), that's the rule worth pulling into a governed capability, while the framework you already chose keeps doing what it's good at.
+
+
+
+
+
+
+
+
+
+
Keep your UI framework. Govern the logic underneath it.
+
See the exact platform matrix, or start with the quickstart.
+
+
+
+
+`;
+---
+
+
+
+
diff --git a/src/pages/compare/vs-wasm-runtimes.astro b/src/pages/compare/vs-wasm-runtimes.astro
new file mode 100644
index 0000000..1e7a5e5
--- /dev/null
+++ b/src/pages/compare/vs-wasm-runtimes.astro
@@ -0,0 +1,167 @@
+---
+import SubpageLayout from '@layouts/SubpageLayout.astro';
+
+const _body = `
+
+
+
Comparison
+
Traverse vs. Raw WASM Runtimes (Wasmtime, WasmEdge, Wasmer)
+
Wasmtime, WasmEdge, and Wasmer execute WASM binaries fast and portably across operating systems. Traverse isn't a competitor to them — it's built on top of Wasmtime specifically, adding the contract, registry, and trace layer a raw runtime deliberately doesn't provide.
+
+
+
+
+
+
+
+
What a WASM runtime solves
+
Wasmtime, WasmEdge, and Wasmer all solve the same core problem: take a .wasm binary and execute it, fast, safely, and identically regardless of the host OS. They differ in focus — Wasmtime is the Bytecode Alliance's reference-grade, standards-first implementation; WasmEdge targets edge and cloud-native workloads with extensions for AI inference; Wasmer emphasizes broad language embedding and its own package registry. All three are genuinely excellent at running a WASM binary correctly and quickly.
+
None of them, by design, know or care what the binary they're running is supposed to do, what inputs are valid, or what should be true when it finishes. That's out of scope for a runtime — it's an execution engine, not a governance layer.
+
+
+
+
What Traverse adds on top
+
Traverse doesn't replace a WASM runtime — traverse-runtime's native executor is built on Wasmtime specifically. What Traverse adds sits above that execution layer: a machine-readable contract describing a capability's inputs, outputs, preconditions, and postconditions; a registry that makes capabilities discoverable by contract rather than by hardcoded import; and a trace artifact recording what happened on every single execution — what ran, what was validated, what the result was.
+
Where Wasmtime answers "run this binary correctly," Traverse answers "was this specific execution allowed, valid, and auditable." Different layer, same underlying binary.
+
The distinction: a raw runtime is infrastructure. Traverse is what you'd build on top of that infrastructure if you needed enforced correctness and an audit trail — which most direct wasmtime run use cases don't need, and most governed business-logic systems do.
+
+
+
+
Key differences
+
+ | Dimension | Raw WASM runtime | Traverse |
+
+
+ | What it is |
+ An execution engine for WASM binaries |
+ A governance layer built on top of a WASM execution engine (Wasmtime) |
+
+
+ | Input/output validation |
+ None — the runtime executes whatever the binary's exported functions accept |
+ Enforced against a declared JSON Schema contract before and after execution |
+
+
+ | Discovery |
+ You call a known module by file path or handle |
+ Capabilities are discoverable through a queryable registry by contract, not hardcoded reference |
+
+
+ | Execution record |
+ None built in — whatever your own code logs |
+ A structured trace artifact per execution: capability, version, validation results, timing |
+
+
+ | Cross-OS behavior |
+ Identical, by the WASM spec itself |
+ Identical, inherited from the underlying runtime, plus contract enforcement identical everywhere too |
+
+
+ | Primary use |
+ Embed WASM execution into any application, with full control over the surrounding logic |
+ Govern business logic that needs enforced correctness and an audit trail across multiple callers |
+
+
+
+
+
+
+
When to use which
+
+
+
Use a raw WASM runtime directly when
+
+ - You're building your own governance or plugin system from scratch
+ - You need fine-grained control over host imports and resource limits that a higher-level layer would abstract away
+ - The workload doesn't need a contract, a registry, or a trace — just fast, sandboxed execution
+
+
+
+
Use Traverse when
+
+ - You want contract enforcement and traces without building that layer yourself on top of Wasmtime
+ - Multiple callers (an app, a backend, an AI agent) need to discover and invoke the same governed capability
+ - A rule needs to be auditable — what ran, with what inputs, under which contract version
+
+
+
+
+
+
+
The verdict
+
This isn't really a choice between alternatives — it's a choice about which layer of the stack you're working at. If you're building infrastructure and want direct control over WASM execution, use Wasmtime, WasmEdge, or Wasmer directly; they're excellent at exactly that. If you're building a business system and want contracts, discovery, and audit trails without reimplementing that layer yourself, Traverse gives you that on top of Wasmtime rather than instead of it.
+
+
+
+
+
+
+
+
+
+
See the governance layer in action.
+
Build and inspect a governed bundle in the quickstart.
+
+
+
+
+`;
+---
+
+
+
+
diff --git a/src/pages/docs/guides/cross-os-capability.astro b/src/pages/docs/guides/cross-os-capability.astro
new file mode 100644
index 0000000..c5b5d46
--- /dev/null
+++ b/src/pages/docs/guides/cross-os-capability.astro
@@ -0,0 +1,162 @@
+---
+import SubpageLayout from '@layouts/SubpageLayout.astro';
+import DocsSidebar from '@components/DocsSidebar.astro';
+
+const _docsBefore = ``;
+const _docsAfter = `
+
+
+
Guide
+
Write one capability, run it on Windows, macOS, Linux, and the browser
+
A hands-on walkthrough of the actual mechanism behind "any OS": one contract, one WASM binary, no per-platform branch. You'll inspect the shipped example bundle, understand why the same commands work on every native OS, and see the same capability load in a browser.
+
+ v0.10.1
+ ~15 minutes
+ Rust 1.94+
+
+
+
+
+
+
Build the runtime and the example bundle
+
These are the exact same three commands regardless of whether you're on Windows, macOS, or Linux. Nothing here branches on OS — there's no separate quickstart per platform, because there's nothing platform-specific to instruct.
+
+
+
+
$ git clone https://github.com/traverse-framework/traverse.git
+
$ cd traverse
+
$ cargo build
+
+
Compiling traverse-contracts v0.10.1
+
Compiling traverse-registry v0.10.1
+
Compiling traverse-runtime v0.10.1
+
Finished dev profile
+
+
+
Cargo and rustc are cross-platform build tooling by design — this is the same reason your Rust host binary doesn't need a Windows-specific or Linux-specific variant. The interesting part isn't this step; it's what happens next.
+
+
+
+
+
02
+
Inspect the bundle
+
+
Inspect the shipped capability bundle
+
The expedition example ships as a registry bundle: a manifest, contracts, and WASM modules. Inspecting it shows you exactly what the runtime will load — the same output on every OS, because it's reading the same files.
+
+
+
+
$ cargo run -p traverse-cli-rs -- bundle inspect examples/expedition/registry-bundle/manifest.json
+
+
Bundle: expedition-planning
+
capabilities: 6
+
events: 5
+
workflows: 1
+
plan-expedition v1.0.0 ... valid
+
+
+
Nothing here is OS-conditional. The manifest, the contracts, and the compiled WASM modules are plain files with no embedded platform assumptions — that's what makes step 3 unremarkable instead of requiring a rewrite.
+
+
+
+
+
Run it through the native executor
+
The native executor is Wasmtime-backed, and Wasmtime compiles the WASM module to native machine code for whichever host it's running on — a step that happens transparently, with no action required from you regardless of which OS you're on.
+
+
Your terminal (Windows, macOS, or Linux)
+
↓
+
traverse-runtime · NativeExecutor · WasmExecutor (Wasmtime)
+
↓
+
plan-expedition.wasm — same binary on every host
+
+
Follow the maintained repository quickstart for the exact run command for your setup — the point to notice is that the command itself doesn't fork by OS. If you have access to more than one operating system, running the identical command against the identical bundle is the fastest way to see this claim verified rather than asserted.
+
+
+
+
+
04
+
Run in the browser
+
+
Load the same bundle in a browser
+
The Web embedder SDK loads the same bundle — not a rebuilt or re-exported version of it — and executes the WASM module directly in the browser's own WebAssembly host. This is the same digest-verified artifact the native executor ran in step 3.
+
+
+
import { TraverseEmbedder } from 'traverse-embedder-web';
+
+
+const embedder = await TraverseEmbedder.init('./bundles/expedition');
+const result = await embedder.submit('plan-expedition', { destination: 'kilimanjaro' });
+
+
Scope note: this in-browser path handles linear, directly-triggered pipelines — conditional and event-driven workflow edges aren't executed in-browser yet. See the
React integration guide for the fuller, request/response pattern via the local browser adapter, which has no such scope limit.
+
+
+
+
+
05
+
Confirm identical behavior
+
+
Confirm it with the trace, not by eye
+
Don't take "identical behavior" on faith — the trace artifact from each run tells you exactly what executed. Compare the capability, version, and output fields from a native run against a browser run with the same input; they should match exactly, because it's the same binary either way.
+
+
+
{
+ "capability": "expedition.planning.plan-expedition",
+ "version": "1.0.0",
+ "contract_validated": true,
+ "preconditions_met": true,
+ "postconditions_met": true
+}
+
+
+
+
+
+
+`;
+---
+
+
+
+
+
+
diff --git a/src/pages/docs/guides/index.astro b/src/pages/docs/guides/index.astro
index 51c3afe..d5d6fa9 100644
--- a/src/pages/docs/guides/index.astro
+++ b/src/pages/docs/guides/index.astro
@@ -3,6 +3,7 @@ import SubpageLayout from '@layouts/SubpageLayout.astro';
import DocsSidebar from '@components/DocsSidebar.astro';
const guides = [
+ { href: '/docs/guides/cross-os-capability.html', title: 'Write once, run on Windows, macOS, Linux, and the browser', desc: 'Inspect a real bundle, run it natively, load it in a browser, and confirm the match from the trace.' },
{ href: '/docs/guides/mcp-setup.html', title: 'MCP Server Setup', desc: 'Expose your capability registry to Claude and other MCP-compatible agents.' },
{ href: '/docs/guides/react-integration.html', title: 'React Integration', desc: 'Call Traverse capabilities from a React app.' },
];
diff --git a/src/pages/questions/can-ai-agents-call-the-same-capability-regardless-of-os.astro b/src/pages/questions/can-ai-agents-call-the-same-capability-regardless-of-os.astro
new file mode 100644
index 0000000..aa44d64
--- /dev/null
+++ b/src/pages/questions/can-ai-agents-call-the-same-capability-regardless-of-os.astro
@@ -0,0 +1,38 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'Can an AI agent call the same capability my app uses, regardless of OS?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: 'Yes. An MCP-connected agent discovers and invokes a capability through traverse-mcp against the registry, which is the same capability and contract your native or browser-hosted app calls directly. The agent gets the identical enforced behavior and trace as any other caller, independent of which OS is hosting the runtime the agent is talking to.',
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/questions/how-does-the-mcp-server-work.html', label: 'How does the Traverse MCP server work?' },
+ { href: '/questions/how-do-ai-agents-discover-capabilities.html', label: 'How do AI agents discover capabilities?' },
+ { href: '/questions/what-framework-runs-business-logic-on-any-os.html', label: 'What framework lets me write business logic once and run it on any OS?' },
+ { href: '/docs/guides/mcp-setup.html', label: 'MCP Server Setup' },
+];
+---
+
+ Yes, and this is one of the more concrete payoffs of the whole "one binary, one contract" model. traverse-mcp exposes capabilities from your registry as tools over the Model Context Protocol. When an AI agent — Claude or another MCP-compatible client — discovers and calls a capability, it's invoking the identical contract-governed WASM binary your web app, your native backend, or your CLI would call. Not a reimplementation exposed as a tool description; the same execution path, producing the same trace.
+
+ Because that binary is device-independent to begin with, the OS hosting the MCP server itself is beside the point — the agent's call goes through the registry and the runtime, and the underlying execution behaves the same way whether that host happens to be Windows, macOS, or Linux.
+
+ Why that matters more for agents than for a typical app
+ An AI agent calling a capability is exactly the situation where "the agent got a slightly different answer than the human-facing app because they're calling two different implementations" is a genuinely bad failure mode — invisible until it causes a wrong decision. Because the agent and the app are calling the same binary under the same contract, that specific failure mode is structurally ruled out rather than something you have to test for. See the MCP setup guide to wire this up directly.
+
diff --git a/src/pages/questions/can-i-migrate-existing-business-logic-to-traverse.astro b/src/pages/questions/can-i-migrate-existing-business-logic-to-traverse.astro
new file mode 100644
index 0000000..c85edb4
--- /dev/null
+++ b/src/pages/questions/can-i-migrate-existing-business-logic-to-traverse.astro
@@ -0,0 +1,40 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'Can I migrate existing business logic into Traverse?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: "Yes, in the sense that you re-express the logic as a Rust capability compiled to WASM with a contract — Traverse doesn't ingest existing code from another language automatically. The practical path is picking one duplicated, drifting, or hard-to-audit rule, rewriting just that rule as a governed capability, and pointing your existing callers at it, rather than migrating an entire codebase at once.",
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/blog/logic-duplication.html', label: 'Why I stopped writing the same business logic four times' },
+ { href: '/questions/how-do-i-write-a-capability-contract.html', label: 'How do I write a capability contract?' },
+ { href: '/questions/do-i-need-rust.html', label: 'Do I need to know Rust to use Traverse?' },
+ { href: '/docs/quickstart.html', label: 'Quickstart' },
+];
+---
+
+ There's no automatic converter that takes your existing JavaScript, Python, or C# business rule and produces a Traverse capability — you re-implement the rule in Rust, compile it to WASM, and write the contract that describes it. That's real, deliberate work, not a checkbox migration, and it's worth being upfront about that instead of implying otherwise.
+
+ Where it pays off is when you're not migrating "the codebase" but one specific rule that's currently duplicated, drifting, or hard to audit — a pricing calculation reimplemented in three services, an eligibility check nobody's fully sure is consistent across the app and the backend. You rewrite that one rule as a governed capability, define its contract precisely (including the edge cases the old scattered copies probably handled inconsistently), and update your existing callers to invoke the capability instead of their own local implementation.
+
+ A reasonable order of operations
+ Start with the rule that's causing the most actual pain from drift, not the most complex one. Write its contract first — inputs, outputs, preconditions, postconditions — since that step alone often surfaces inconsistencies between the existing copies that nobody had written down before. Then implement it once in Rust, compile it, and swap one caller over at a time, verifying the trace output matches what you expect before removing the old implementation it replaced.
+
+ You don't need to know Rust deeply to consume a capability once it exists — see do I need to know Rust to use Traverse — but writing the capability itself does require it, since that's the language capabilities compile from today.
+
diff --git a/src/pages/questions/can-i-run-the-same-business-logic-in-browser-and-native-apps.astro b/src/pages/questions/can-i-run-the-same-business-logic-in-browser-and-native-apps.astro
new file mode 100644
index 0000000..5ae9235
--- /dev/null
+++ b/src/pages/questions/can-i-run-the-same-business-logic-in-browser-and-native-apps.astro
@@ -0,0 +1,38 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'Can I run the same business logic in a browser app and a native app?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: 'Yes — this is the combination with the most complete, shipped Traverse support today. The same WASM capability and contract are loaded by the native executor (Windows, macOS, Linux) and by the Web embedder SDK in the browser, with no separate implementation or build for either.',
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/questions/what-framework-runs-business-logic-on-any-os.html', label: 'What framework lets me write business logic once and run it on any OS?' },
+ { href: '/questions/what-is-the-browser-adapter.html', label: 'What is the browser adapter?' },
+ { href: '/docs/guides/react-integration.html', label: 'React Integration guide' },
+ { href: '/questions/how-do-i-share-business-logic-between-web-and-desktop.html', label: 'How do I share business logic between a web app and a desktop app?' },
+];
+---
+
+ Yes, and out of every platform combination people ask about, this is the one with the most mature, complete support today — more so even than native-to-native across different desktop OSes, because it's the pairing the project has spent the most shipped effort on. Native execution (Windows, macOS, Linux) through traverse-runtime's Wasmtime-backed executor and browser execution through the Web embedder SDK both load the identical WASM binary and contract. Nothing about the capability changes between the two.
+
+ What differs is only the transport getting a request to the capability. A native host calls it in-process through an embedder. A browser page either talks to a local browser adapter over HTTP (the pattern the React integration guide walks through) or, as of the more recent releases, executes a single verified capability directly in the browser's own WASM host and gets back a signed trace receipt. Either way, the capability itself — and critically, its result for a given input — is unchanged.
+
+ Where this is genuinely useful
+ The common case: a validation or pricing rule needs to run instantly in a web form for UX (no round trip to a server) and also needs to run identically in your native backend or CLI tooling for the authoritative check. With a shared capability, both are guaranteed to agree, because they're executing the same binary — there's no "the frontend's copy of the rule is slightly out of date" failure mode to debug, because there's no second copy.
+
diff --git a/src/pages/questions/can-i-run-traverse-capabilities-in-a-docker-container.astro b/src/pages/questions/can-i-run-traverse-capabilities-in-a-docker-container.astro
new file mode 100644
index 0000000..3873d64
--- /dev/null
+++ b/src/pages/questions/can-i-run-traverse-capabilities-in-a-docker-container.astro
@@ -0,0 +1,37 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'Can I run Traverse capabilities inside a Docker container?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: "Yes. A Traverse capability's WASM binary runs on the native Linux executor, so packaging that host process in a container is unremarkable — it's the same native target running inside a Linux container as running directly on a Linux host, just with the usual containerization benefits layered on top for deployment and orchestration.",
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/questions/how-is-traverse-different-from-docker.html', label: 'How is Traverse different from Docker?' },
+ { href: '/compare/vs-serverless.html', label: 'Traverse vs Serverless Functions' },
+ { href: '/questions/does-traverse-support-windows-macos-and-linux.html', label: 'Does Traverse support Windows, macOS, and Linux?' },
+ { href: '/docs/quickstart.html', label: 'Quickstart' },
+];
+---
+
+ Yes, and there's nothing special about it. A Traverse capability's WASM binary runs through the native executor, which is a Rust process using Wasmtime under the hood — the same kind of process you'd containerize for any other Rust service. Build your host application (the one embedding traverse-runtime or traverse-embedder and loading your registry bundle), put it in a minimal base image, and run it the way you'd run any containerized Rust binary.
+
+ This is, in fact, exactly the pattern shown in the Traverse vs. Serverless Functions comparison: the same traverse-embedder-based host that runs on your desktop or in a container also runs inside an AWS Lambda function, because none of those hosts require anything Traverse-specific to accommodate it. WASM execution, contract validation, and trace generation all happen the same way regardless of whether the process is bare-metal, containerized, or serverless — the container just answers "how does this process get deployed," which is orthogonal to what's running inside it.
+
+ One thing containerizing doesn't change: the capability's own sandbox permissions (network, filesystem, host calls) are still governed by its contract, not by whatever the container's own permissions happen to allow. A container with broad filesystem access doesn't loosen what a capability inside it is allowed to touch — the WASM sandbox boundary is enforced independently of the container boundary around it.
+
diff --git a/src/pages/questions/can-i-share-logic-between-ios-and-android-apps.astro b/src/pages/questions/can-i-share-logic-between-ios-and-android-apps.astro
new file mode 100644
index 0000000..81c9854
--- /dev/null
+++ b/src/pages/questions/can-i-share-logic-between-ios-and-android-apps.astro
@@ -0,0 +1,40 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'Can I share business logic between an iOS app and an Android app with Traverse?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: 'Not through a shipped Traverse SDK on both sides today. Android has a working, unreleased Kotlin runtime bridge. iOS is blocked on the WASM engine ecosystem lacking a certifiable resource-control API, though a feasibility spike proved a workaround runs on a physical iPhone. The capability and contract you write today carry over unchanged once both embedders ship — the logic-sharing goal is real, just not deliverable across both mobile OSes yet.',
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/questions/can-traverse-build-mobile-apps.html', label: 'Can I build a mobile app with Traverse?' },
+ { href: '/blog/native-ios-runtime-foundation.html', label: 'Native iOS without a JIT: a hands-on feasibility proof' },
+ { href: '/platforms.html', label: 'Where Traverse actually runs (platform status)' },
+ { href: '/questions/what-framework-runs-business-logic-on-any-os.html', label: 'What framework lets me write business logic once and run it on any OS?' },
+];
+---
+
+ This is exactly the problem Traverse is built to eventually solve for mobile, and it's worth being precise about the word "eventually," because it isn't there yet for both platforms simultaneously.
+
+ On Android, packages/kotlin/TraverseEmbedder has a working runtime bridge built on Chicory, with bundle validation and lifecycle handling done. What's left is Compose reference-app integration and a public release — real, tracked, in-progress work, not a stalled idea.
+
+ On iOS, the situation is different in kind, not just degree: it's blocked, not just unfinished. As of the last engine screen, none of the major WASM runtimes (WasmKit, WAMR, Wasmtime, Wasmer) expose the resource-control APIs a certified native embedder needs to clear App Store review. A separate feasibility spike found a workaround — embedding the wasmi interpreter through a Rust static library with host-enforced memory and fuel limits — and it runs clean on a physical iPhone, which is a real result. It's not a shipped SDK you can add to an Xcode project today, though.
+
+ What you can do about it now
+ Write the shared rule as a well-scoped Traverse capability today, targeting the platforms that are already shipped — native desktop and the browser, for testing and for any web-based surface your product has. The contract doesn't change when a mobile embedder ships; the work isn't wasted, it's just not deployable to both phones yet. Watch Platforms for exactly when that changes, rather than guessing from a roadmap date.
+
diff --git a/src/pages/questions/can-i-use-traverse-for-a-saas-product-on-multiple-operating-systems.astro b/src/pages/questions/can-i-use-traverse-for-a-saas-product-on-multiple-operating-systems.astro
new file mode 100644
index 0000000..3c60d43
--- /dev/null
+++ b/src/pages/questions/can-i-use-traverse-for-a-saas-product-on-multiple-operating-systems.astro
@@ -0,0 +1,38 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'Can I use Traverse for a SaaS product that needs to run on multiple operating systems?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: "Yes, for the pattern most SaaS products actually need: a web-hosted app plus an optional native companion (a CLI tool, a desktop menu-bar app, an on-prem agent) that both need to enforce the exact same business rules — billing logic, entitlement checks, usage limits. The web frontend and the native companion load the same governed capability instead of maintaining two implementations.",
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/examples.html', label: 'Traverse examples' },
+ { href: '/questions/can-i-run-the-same-business-logic-in-browser-and-native-apps.html', label: 'Can I run the same business logic in a browser app and a native app?' },
+ { href: '/questions/can-i-use-traverse-for-pricing-logic.html', label: 'Can I use Traverse for pricing logic?' },
+ { href: '/questions/what-framework-runs-business-logic-on-any-os.html', label: 'What framework lets me write business logic once and run it on any OS?' },
+];
+---
+
+ Yes, and the shape this usually takes for a SaaS product is narrower than "the whole product runs everywhere" — it's specifically the handful of rules that have to stay consistent between a web-hosted app and some native companion surface: a CLI tool for power users, a desktop menu-bar utility, an on-prem agent installed at a customer site. Entitlement checks, usage-limit enforcement, and billing calculations are the classic candidates, because getting them inconsistent between the web app and the native tool is a support and revenue problem, not just a code-quality one.
+
+ The pattern: write the entitlement or pricing rule once as a Traverse capability. Your web app's backend calls it through the native executor (since backends run natively). Any native companion tool — a CLI, a desktop agent — embeds the same capability through traverse-embedder. Both get the identical enforced result from the identical contract, so a customer can't end up in a state where the web dashboard says they're over their limit and the CLI tool disagrees.
+
+ Where the honest limits still apply
+ If your SaaS product's "multiple operating systems" requirement is specifically a mobile app, the same mobile-embedder status covered elsewhere on this site applies — Android and .NET are in-progress, unreleased; iOS is blocked. For desktop and web, which is where most SaaS entitlement logic actually needs to be consistent, this is solid, shipped ground today. See the Traverse examples for the fuller worked walkthroughs.
+
diff --git a/src/pages/questions/can-i-use-traverse-in-a-monorepo-with-multiple-apps.astro b/src/pages/questions/can-i-use-traverse-in-a-monorepo-with-multiple-apps.astro
new file mode 100644
index 0000000..40e4995
--- /dev/null
+++ b/src/pages/questions/can-i-use-traverse-in-a-monorepo-with-multiple-apps.astro
@@ -0,0 +1,38 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'Can I use Traverse in a monorepo with multiple apps targeting different platforms?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: "Yes — that's a common shape for this to fit well, since a shared registry bundle sitting alongside a web app, a native CLI, and a desktop shell in one repo means every app pulls from the same capabilities and contracts rather than each maintaining its own copy or import path.",
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/questions/what-is-the-capability-registry.html', label: 'What is the capability registry?' },
+ { href: '/questions/how-do-i-package-a-capability-for-multiple-platforms.html', label: 'How do I package a capability for multiple platforms?' },
+ { href: '/questions/how-do-i-share-business-logic-between-web-and-desktop.html', label: 'How do I share business logic between a web app and a desktop app?' },
+ { href: '/docs/quickstart.html', label: 'Quickstart' },
+];
+---
+
+ Yes, and it's one of the more natural places for this pattern to pay off quickly. Put your registry bundle — the capabilities, their contracts, and any events or workflows — in a shared location in the monorepo, and have your web app, native tooling, and desktop shell each depend on it through whichever executor matches their platform (the Web embedder SDK for the web app, traverse-embedder for the native and desktop targets).
+
+ The practical benefit inside a monorepo specifically: a change to a capability's contract is one commit, reviewed once, and every app in the repo picks it up the next time it builds against the updated bundle. There's no separate PR per app to keep three reimplementations in sync, because there aren't three reimplementations — there's one bundle multiple apps reference.
+
+ What to actually structure
+ A reasonable layout: a top-level capabilities/ or bundles/ directory holding your registry bundle(s), separate from each app's own directory. Each app's build or dev script points its executor at that shared path rather than vendoring a copy. CI can validate the bundle once, independent of which apps happen to consume it, using the same bundle inspect/validate commands shown in the quickstart.
+
diff --git a/src/pages/questions/can-i-use-traverse-with-dotnet-maui.astro b/src/pages/questions/can-i-use-traverse-with-dotnet-maui.astro
new file mode 100644
index 0000000..14db213
--- /dev/null
+++ b/src/pages/questions/can-i-use-traverse-with-dotnet-maui.astro
@@ -0,0 +1,37 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'Can I use Traverse with .NET MAUI today?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: "Partially. Traverse's .NET embedder uses a working Wasmtime .NET-backed bridge targeting WinUI, which covers MAUI's Windows target. Request marshalling, event subscriptions, and reference-app integration for the rest of the .NET embedder are still open work, and there's no public release yet, so treat this as close but not a drop-in dependency for a shipping MAUI app across all four of its platforms.",
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/questions/how-is-traverse-different-from-dotnet-maui.html', label: 'How is Traverse different from .NET MAUI?' },
+ { href: '/questions/can-traverse-build-mobile-apps.html', label: 'Can I build a mobile app with Traverse?' },
+ { href: '/platforms.html', label: 'Where Traverse actually runs (platform status)' },
+ { href: '/questions/what-is-traverse-roadmap.html', label: 'What is the Traverse roadmap?' },
+];
+---
+
+ Partially, and worth being precise about which part. packages/dotnet/TraverseEmbedder has a working runtime bridge backed by Wasmtime .NET, targeting WinUI — which is MAUI's Windows rendering target specifically, not the cross-platform MAUI runtime as a whole. Request marshalling, event subscriptions, evidence publication, and the shared cross-SDK conformance suite are still open work, and there's no public release of the package yet.
+
+ So if your MAUI app's Windows build is what you care about pairing with Traverse right now, the underlying pieces exist and are progressing. If you need the same integration working identically on MAUI's iOS and Android targets, that runs into the same mobile-embedder status as any other approach: iOS is blocked on the WASM engine ecosystem, and Android has its own separate, also-unreleased Kotlin bridge that isn't specifically wired for MAUI's Android target.
+
+ The honest recommendation: if you're starting a MAUI project today and want Traverse in it eventually, structure your business logic as a well-scoped capability with a clean contract now. That work carries forward unchanged once the embedder ships — the contract doesn't change when the host does. Track exactly when it does on the Platforms page rather than guessing from a roadmap date.
+
diff --git a/src/pages/questions/can-i-use-traverse-with-electron.astro b/src/pages/questions/can-i-use-traverse-with-electron.astro
new file mode 100644
index 0000000..580de63
--- /dev/null
+++ b/src/pages/questions/can-i-use-traverse-with-electron.astro
@@ -0,0 +1,38 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'Can I use Traverse with Electron?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: "Yes. An Electron app's renderer process is a Chromium web page, so it can call a Traverse capability the same way any browser page does — through the Web embedder SDK or the local browser adapter. Electron's main process, being a Node.js process, can also shell out to or bind against a native traverse-embedder host if you want the capability running outside the renderer.",
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/questions/can-i-use-traverse-with-tauri.html', label: 'Can I use Traverse with Tauri?' },
+ { href: '/questions/how-is-traverse-different-from-electron.html', label: 'How is Traverse different from Electron?' },
+ { href: '/questions/what-is-the-browser-adapter.html', label: 'What is the browser adapter?' },
+ { href: '/docs/guides/react-integration.html', label: 'React Integration guide' },
+];
+---
+
+ Yes. Electron's renderer process is, under the hood, a Chromium browser page rendering your web frontend — which means it's already a real WASM host. A Traverse capability loaded through the Web embedder SDK runs there exactly the way it would in a plain browser tab: no Electron-specific adaptation needed. The React integration guide applies directly if your Electron app's renderer is a React app, since the pattern (talk to the local browser adapter over HTTP, or load the embedder SDK directly) doesn't care that Chromium happens to be wrapped in a desktop shell.
+
+ If you'd rather run the capability outside the renderer — say, in Electron's Node.js-based main process, closer to the OS — that process can shell out to a native host running traverse-embedder, or communicate with a locally running traverse-cli adapter over IPC, the same pattern the Lambda and Tauri integration examples use elsewhere on this site.
+
+ Why you'd bother, instead of just writing the rule in JavaScript
+ The same reason as any other host: a plain JS function in your renderer has no enforced contract and produces no trace. If the rule behind that Electron app's UI also needs to run identically in your backend or be callable by an AI agent, wrapping it as a governed capability means all of those callers get the same binary and the same enforced result — instead of a JS copy in the app and a second implementation everywhere else.
+
diff --git a/src/pages/questions/can-i-use-traverse-with-tauri.astro b/src/pages/questions/can-i-use-traverse-with-tauri.astro
new file mode 100644
index 0000000..3909d1b
--- /dev/null
+++ b/src/pages/questions/can-i-use-traverse-with-tauri.astro
@@ -0,0 +1,39 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'Can I use Traverse with Tauri?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: "Yes, and it's a particularly natural pairing since Tauri's backend is Rust, the same language Traverse capabilities compile from. A Tauri command calls into a governed capability through the public traverse-embedder crate, so the desktop window Tauri renders is backed by the same contract-enforced logic your web app and backend already call.",
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/compare/vs-cross-platform-frameworks.html', label: 'Traverse vs Flutter, Electron, and Tauri (full comparison)' },
+ { href: '/questions/how-is-traverse-different-from-electron.html', label: 'How is Traverse different from Electron?' },
+ { href: '/platforms.html', label: 'Where Traverse actually runs (platform status)' },
+ { href: '/docs/quickstart.html', label: 'Quickstart' },
+];
+---
+
+ Yes — of the cross-platform desktop frameworks, Tauri is the most natural fit, because its backend is already Rust. There's no FFI boundary or language bridge to cross: a Tauri command function can call the public traverse-embedder crate directly, the same way a native CLI tool would, and return the result to the frontend like any other Tauri command.
+
+ The practical shape: initialize a BundleEmbedder once at app startup, hold it in Tauri's shared state, and call submit_and_await (or the async equivalent your embedder version exposes) from inside a #[tauri::command] handler. Your Tauri frontend never knows the difference — it just gets a JSON result back — but the logic behind that result is the same governed, contract-enforced WASM binary your web dashboard, backend, or AI agent calls.
+
+ Why bother, instead of just writing the rule in Rust directly inside the Tauri command? Because a plain function has no contract, no enforced pre/postconditions, and no trace artifact. If that rule needs to be provably identical across your desktop app and three other callers — or if it's the kind of rule (pricing, eligibility, compliance) where drift between copies would actually cost you — wrapping it as a Traverse capability gets you the governance for free everywhere it's called, Tauri included.
+
+ For the full worked example, including the actual command code, see the Traverse vs. cross-platform app frameworks comparison.
+
diff --git a/src/pages/questions/can-non-rust-teams-use-traverse.astro b/src/pages/questions/can-non-rust-teams-use-traverse.astro
new file mode 100644
index 0000000..9ed313e
--- /dev/null
+++ b/src/pages/questions/can-non-rust-teams-use-traverse.astro
@@ -0,0 +1,40 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'Can a team that does not write Rust still use Traverse?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: "Yes, as a consumer of capabilities — calling a capability over HTTP through the browser adapter, or via an embedder, requires no Rust at all, just JSON in and out. Authoring a new capability currently does require Rust, since that's the language capabilities compile from. A Python SDK is on the roadmap as planned, not yet shipped.",
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/questions/do-i-need-rust.html', label: 'Do I need to know Rust to use Traverse?' },
+ { href: '/questions/can-i-use-traverse-with-python.html', label: 'Can I use Traverse with Python?' },
+ { href: '/docs/guides/react-integration.html', label: 'React Integration guide' },
+ { href: '/questions/what-is-traverse-roadmap.html', label: 'What is the Traverse roadmap?' },
+];
+---
+
+ Depends whether your team is consuming capabilities or authoring them, and those have very different Rust requirements.
+
+ Consuming a capability requires no Rust whatsoever. If you're calling into a capability from a React app, you're sending a plain JSON request to the local browser adapter and reading a JSON response back — the React integration guide covers this in full and never touches Rust or WASM directly. The same is true from any language that can make an HTTP request or bind against an embedder's API.
+
+ Authoring a new capability is a different story today: capabilities compile from Rust to WebAssembly, so writing a new one currently means writing Rust. There isn't yet a path to author a capability directly in Python, JavaScript, or another language and have Traverse compile it — a Python SDK is explicitly on the roadmap as a planned, not-yet-shipped item, aimed specifically at teams that don't write Rust and want to call existing capabilities more idiomatically, or eventually contribute to them.
+
+ A practical split for a mixed team
+ A common shape: one or two people comfortable with Rust write and maintain the capabilities and their contracts, while the rest of the team — frontend, data, ML — consumes them as a plain API. That's not a workaround; it matches how the contract boundary is meant to work. The contract is the interface a non-Rust consumer needs to understand; the Rust implementation behind it is an internal detail they don't have to touch.
+
diff --git a/src/pages/questions/can-traverse-build-mobile-apps.astro b/src/pages/questions/can-traverse-build-mobile-apps.astro
new file mode 100644
index 0000000..c661075
--- /dev/null
+++ b/src/pages/questions/can-traverse-build-mobile-apps.astro
@@ -0,0 +1,45 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'Can I build a mobile app with Traverse?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: 'Not as a shipped, public path yet, and we would rather say that plainly than let you find out mid-project. Android has a working runtime bridge (Chicory-based) with no public release. iOS is blocked: no WASM engine currently exposes the resource-control APIs a certified native embedder needs for App Store distribution, though a separate wasmi feasibility spike proved a workaround runs on a physical iPhone. Neither is a shipped SDK today.',
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/questions/does-traverse-support-windows-macos-and-linux.html', label: 'Does Traverse support Windows, macOS, and Linux?' },
+ { href: '/questions/what-framework-runs-business-logic-on-any-os.html', label: 'What framework lets me write business logic once and run it on any OS?' },
+ { href: '/blog/native-ios-runtime-foundation.html', label: 'Native iOS without a JIT: a hands-on feasibility proof' },
+ { href: '/questions/what-is-traverse-roadmap.html', label: 'What is the Traverse roadmap?' },
+];
+---
+
+ Not as a shipped, public path today — and we'd rather tell you that up front than have you find out after committing to it. Traverse's mature, shipped targets are native (Windows, macOS, Linux) and the browser. Mobile is genuinely being worked on, but "in progress" and "blocked" mean different things, and it matters which one applies to which platform.
+
+ Android — in progress, unreleased
+ packages/kotlin/TraverseEmbedder has a working ChicoryRuntimeBridge pinned to a specific Chicory version. Bundle validation and lifecycle types are in place. What's missing is Compose reference-app integration, which is tracked by its own open issue, and a public release. If you want to help move it forward, that issue is the place to look.
+
+ iOS — blocked, not just unfinished
+ This one is stuck on something outside the project's control, not a backlog item waiting its turn. As of the last candidate engine screen, none of WasmKit, WAMR, Wasmtime, or Wasmer exposed the public, documented resource-control APIs a certified native embedder baseline requires — for reasons ranging from missing resource-control APIs to no supported iOS profile to JIT/entitlement conflicts with App Store distribution.
+ A separate feasibility spike found a workaround: embedding the wasmi interpreter directly through a Rust static library and a narrow C-compatible bridge, with the host enforcing memory and fuel limits, verified running on a physical iPhone. That's a real, working proof — we wrote up the full technical detail — but it's a foundation for a future runtime path, not a shipped SDK you can npm-install or add via Swift Package Manager today.
+
+ .NET / WinUI — in progress, unreleased
+ The same shape as Android: packages/dotnet/TraverseEmbedder has a working Wasmtime .NET-backed bridge. Request marshalling, event subscriptions, evidence publication, and the shared conformance suite are still open work.
+
+ If your app's core problem is mobile UI, Traverse isn't that tool yet. If you're building a desktop or browser app today and want the same governed business logic ready to extend to mobile once these ship, the contract you write now doesn't change when the mobile embedder does. Track live status on the Platforms page — it's the same page we link internally, not a separate marketing version.
+
diff --git a/src/pages/questions/can-traverse-capabilities-call-native-os-apis.astro b/src/pages/questions/can-traverse-capabilities-call-native-os-apis.astro
new file mode 100644
index 0000000..5e6f7a1
--- /dev/null
+++ b/src/pages/questions/can-traverse-capabilities-call-native-os-apis.astro
@@ -0,0 +1,38 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'Can Traverse capabilities call native OS APIs?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: "Not directly, and that's by design — it's what keeps a capability portable. A capability can only reach outside the WASM sandbox through host calls the contract explicitly declares and the host explicitly implements. If you need OS-level access, you declare the specific host call in the contract, implement it once in your host application, and the capability's own code stays exactly as portable as before.",
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/questions/what-is-the-wasm-sandbox.html', label: 'What is the WASM sandbox?' },
+ { href: '/questions/what-is-a-contract-in-traverse.html', label: 'What is a contract in Traverse?' },
+ { href: '/questions/what-framework-runs-business-logic-on-any-os.html', label: 'What framework lets me write business logic once and run it on any OS?' },
+ { href: '/questions/what-is-traverse-security-model.html', label: "What is Traverse's security model?" },
+];
+---
+
+ Not directly, and it's worth understanding why that's a feature rather than a limitation someone forgot to fix. A capability runs inside the WASM sandbox, which by default has no visibility into the host operating system at all — no raw filesystem calls, no OS-specific APIs, nothing. If it could call native OS functions directly, the whole reason it can move between Windows, macOS, and Linux without changes would disappear, because now its behavior would depend on which OS's API surface it happened to call.
+
+ What a capability can do is declare, in its contract, that it needs a specific host call — a named function the host application implements and exposes across the sandbox boundary. The capability calls that named function; it has no idea (and doesn't need to know) whether the host implements it using a Windows API, a POSIX call, or something else entirely on each platform. The OS-specific branching, if any exists at all, lives in the host application's implementation of that one host call, not scattered through the capability's logic.
+
+ An example of where this matters
+ Say a capability genuinely needs the current system time zone. Rather than reaching for an OS-specific time API, its contract declares a host_calls entry like "system.timezone". The host application — which does know what OS it's running on — implements that one function however is appropriate per platform. The capability's code, and its portability, never changes.
+
diff --git a/src/pages/questions/do-different-operating-systems-see-different-behavior-from-the-same-capability.astro b/src/pages/questions/do-different-operating-systems-see-different-behavior-from-the-same-capability.astro
new file mode 100644
index 0000000..13b5b14
--- /dev/null
+++ b/src/pages/questions/do-different-operating-systems-see-different-behavior-from-the-same-capability.astro
@@ -0,0 +1,38 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'Can different operating systems see different behavior from the same capability?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: "Not from the capability's own logic, which is sandboxed WASM with no OS-visible branching. The one place behavior can legitimately differ is in a host-implemented call the capability's contract declares — if the host implements that call differently per OS, that's a property of the host's implementation, not of the capability, and it's visible in the contract as a named dependency rather than hidden.",
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/questions/can-traverse-capabilities-call-native-os-apis.html', label: 'Can Traverse capabilities call native OS APIs?' },
+ { href: '/questions/what-is-the-wasm-sandbox.html', label: 'What is the WASM sandbox?' },
+ { href: '/questions/how-do-ci-pipelines-test-traverse-across-operating-systems.html', label: 'How does Traverse verify cross-OS behavior actually matches?' },
+ { href: '/questions/what-is-a-contract-in-traverse.html', label: 'What is a contract in Traverse?' },
+];
+---
+
+ The capability's own code can't see which OS it's running on, so it structurally can't branch on it — there's no API inside the WASM sandbox that exposes "what operating system is this," and nothing to condition behavior on even if a developer wanted to. Given the same input and the same contract, a capability's own logic produces the same output regardless of host OS, because that logic has no OS-dependent path to take.
+
+ The one legitimate exception
+ If a capability's contract declares a host call — something like a system clock read or a lookup the host implements — then the behavior of that specific call depends on how the host application implements it, and a host implementation genuinely could differ across operating systems (a timezone lookup implemented one way on Windows and another on Linux, say). That's not the capability behaving inconsistently; it's a declared external dependency whose implementation is the host's responsibility, and it's visible in the contract's host_calls list rather than buried invisibly in the capability's logic.
+
+ In practice, most well-scoped capabilities (pricing rules, eligibility checks, validation logic) have no legitimate reason to declare any host calls at all, which is exactly what keeps them behaviorally identical everywhere. If you're seeing inconsistent results across operating systems for the same capability and the same input, the contract's declared dependencies — not the capability's own logic — are the first place to look.
+
diff --git a/src/pages/questions/does-traverse-support-windows-macos-and-linux.astro b/src/pages/questions/does-traverse-support-windows-macos-and-linux.astro
new file mode 100644
index 0000000..17f7899
--- /dev/null
+++ b/src/pages/questions/does-traverse-support-windows-macos-and-linux.astro
@@ -0,0 +1,43 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'Does Traverse support Windows, macOS, and Linux?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: "Yes. Native — Linux, macOS, and Windows — is Traverse's default and most mature target. traverse-runtime's NativeExecutor, ThreadPoolExecutor, and Wasmtime-backed WasmExecutor all run the same way on each OS, and a capability's WASM binary needs no OS-specific code or build flag to move between them.",
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/questions/what-framework-runs-business-logic-on-any-os.html', label: 'What framework lets me write business logic once and run it on any OS?' },
+ { href: '/questions/can-traverse-run-without-wasm.html', label: 'Can Traverse run without WASM?' },
+ { href: '/questions/what-is-the-traverse-cli.html', label: 'What is the Traverse CLI?' },
+ { href: '/platforms.html', label: 'Where Traverse actually runs (platform status)' },
+];
+---
+
+ Yes, and it's the target Traverse is built around first. traverse-runtime ships a NativeExecutor, a ThreadPoolExecutor, and a Wasmtime-backed WasmExecutor for sandboxed capability execution — all of it running identically whether the host is Linux, macOS, or Windows. There's no OS-specific branch in your capability code and no separate build target per operating system; you compile the capability to WASM once, and the same binary is what every native host executes.
+
+ This is also what the CLI itself runs on, and what every quickstart walks through. If you clone the traverse repo and run cargo build on any of the three, you're building and exercising the exact same code path.
+
+ What "supports" means here specifically
+ Native support covers full orchestration: registering capabilities into the registry, discovering them by contract, validating inputs and outputs, executing the WASM binary in a sandbox, emitting declared events, and writing a trace artifact. None of that is stubbed or partial on any of the three operating systems — it's the same crate, the same code, the same behavior.
+
+ What native support does not mean is a native GUI toolkit. Traverse governs the logic layer; it doesn't paint windows. If you're pairing it with a UI, you'll bring your own — the Traverse vs. cross-platform app frameworks comparison walks through what that pairing looks like with Tauri specifically.
+
+ Where the story is different
+ Mobile is not the same shipped status as desktop. Android and .NET/WinUI have real, working runtime bridges in progress with no public release yet, and iOS is currently blocked on the WASM engine ecosystem lacking a certifiable resource-control API for App Store distribution. See the Platforms page for the full breakdown with links to the actual blocking issues.
+
diff --git a/src/pages/questions/does-traverse-work-offline.astro b/src/pages/questions/does-traverse-work-offline.astro
new file mode 100644
index 0000000..a65c9e7
--- /dev/null
+++ b/src/pages/questions/does-traverse-work-offline.astro
@@ -0,0 +1,40 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'Does Traverse work offline?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: 'Yes, for the capability execution itself — a capability executes locally by default, on whatever client loaded it, with no network round trip required to run the WASM binary, validate its contract, or produce a trace. Native and browser executors both run entirely on-device unless a capability specifically declares and is granted network access.',
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/questions/what-does-device-independent-mean-in-traverse.html', label: 'What does "device-independent" mean in Traverse?' },
+ { href: '/questions/what-is-the-wasm-sandbox.html', label: 'What is the WASM sandbox?' },
+ { href: '/questions/how-do-placement-targets-work.html', label: 'How do placement targets work in Traverse?' },
+ { href: '/questions/what-framework-runs-business-logic-on-any-os.html', label: 'What framework lets me write business logic once and run it on any OS?' },
+];
+---
+
+ Yes, and this follows directly from how execution is modeled, not as a special offline mode bolted on afterward. A Traverse capability is device-independent: it executes locally, on whatever client loaded it, by default. There's no built-in requirement to phone home to a server to run the WASM binary, validate its contract, or generate a trace artifact — all of that happens in-process, on the machine that's already holding the bundle.
+
+ Concretely: the native executor runs entirely on the host it's installed on. The browser embedder, once it's loaded a bundle and its WASM module, executes that capability directly in the browser's own WebAssembly host — no request leaves the machine unless the capability's own logic makes one.
+
+ The one place network involvement is real
+ If a capability's contract declares network_access as required — because the rule genuinely needs to call out to something, a tax rate table or an external lookup — then yes, that specific capability needs connectivity for that specific call. That's a property of the capability, not of the runtime generally, and it's visible in the contract before you ever run it, rather than a surprise at execution time. Most capabilities, especially the pricing/eligibility/validation category this project is built around, have no legitimate reason to need network access at all, and their contracts reflect that with network_access: forbidden.
+
+ Worth noting separately: the client's ability to heuristically delegate part of a capability's work to a server (covered in what "device-independent" means) is an optional decision the client can make based on its own context — not a requirement. Offline, that heuristic simply doesn't fire, and execution stays local.
+
diff --git a/src/pages/questions/how-do-ci-pipelines-test-traverse-across-operating-systems.astro b/src/pages/questions/how-do-ci-pipelines-test-traverse-across-operating-systems.astro
new file mode 100644
index 0000000..9b0b02c
--- /dev/null
+++ b/src/pages/questions/how-do-ci-pipelines-test-traverse-across-operating-systems.astro
@@ -0,0 +1,38 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'How does Traverse verify a capability actually behaves the same across operating systems?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: 'The v1.0 milestone gates explicitly require a five-platform CI stress matrix, alongside 100% coverage on governed paths and zero open P0/P1 bugs, before that claim is considered fully proven rather than architecturally expected. As of the current release, core crates are coverage-gated, but the full cross-platform CI matrix is one of the gates not yet met as a complete set.',
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/questions/is-traverse-production-ready.html', label: 'Is Traverse production ready?' },
+ { href: '/questions/what-is-traverse-roadmap.html', label: 'What is the Traverse roadmap?' },
+ { href: '/questions/does-traverse-support-windows-macos-and-linux.html', label: 'Does Traverse support Windows, macOS, and Linux?' },
+ { href: '/security-audit.html', label: 'Security audit' },
+];
+---
+
+ It's a fair thing to be skeptical about: "the same binary runs identically everywhere" is an architectural claim, and architectural claims are exactly the kind of thing that should be verified rather than asserted. Traverse's own v1.0 milestone treats it that way — a five-platform CI stress matrix is one of ten explicit, named gates the project has set for calling itself v1.0, alongside every crate published on crates.io, an MCP library surface beyond the stdio subprocess, 100% coverage on governed paths, and zero open P0/P1 bugs.
+
+ As of the current release, the honest state is partial: traverse-contracts, traverse-registry, and traverse-runtime are coverage-gated in CI, meaning their core logic can't merge without passing tests. The full five-platform stress matrix is not yet in place as a complete gate — it's tracked, named, and required before v1.0, not silently assumed to already be true.
+
+ Why this matters more than it might seem
+ A framework that claims cross-platform consistency without a CI matrix actually exercising every claimed platform is trusting the architecture to hold, not proving it does on every release. Naming the gap explicitly — as the v1.0 milestone does — is different from pretending it's already closed. If cross-platform reliability is load-bearing for your decision, that's a real, fair thing to weigh, and the roadmap is where to watch it close rather than assume it already has.
+
diff --git a/src/pages/questions/how-do-i-avoid-rewriting-business-logic-for-every-platform.astro b/src/pages/questions/how-do-i-avoid-rewriting-business-logic-for-every-platform.astro
new file mode 100644
index 0000000..81520e3
--- /dev/null
+++ b/src/pages/questions/how-do-i-avoid-rewriting-business-logic-for-every-platform.astro
@@ -0,0 +1,43 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'How do I avoid rewriting business logic for every platform?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: 'Compile the logic once to a WASM binary, attach a machine-readable contract describing its inputs, outputs, and required conditions, and let a runtime that understands that contract execute the same binary on every platform instead of reimplementing the logic in each platform’s native language.',
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/blog/logic-duplication.html', label: 'Why I stopped writing the same business logic four times' },
+ { href: '/blog/wasm-business-logic.html', label: 'What WASM actually gives you for business logic' },
+ { href: '/questions/what-framework-runs-business-logic-on-any-os.html', label: 'What framework lets me write business logic once and run it on any OS?' },
+ { href: '/questions/what-is-a-contract-in-traverse.html', label: 'What is a contract in Traverse?' },
+];
+---
+
+ The usual failure mode looks like this: a pricing rule starts in the backend. Someone needs it in the frontend for instant feedback, so it gets reimplemented in JavaScript. Then the mobile app needs it, so it's rewritten again in Swift or Kotlin. Then an AI agent or a data pipeline needs it, and now there are four copies of the same rule, in four languages, maintained by however many people remembered to update all four when the tax rate changed. They drift. Bugs show up in one copy and not another. Nobody's entirely sure which copy is the real one.
+
+ The structural fix isn't discipline or documentation — it's removing the possibility of a second copy existing. Compile the rule once, to a format that isn't tied to any single host language, and make every caller execute that same artifact instead of their own reimplementation.
+
+ What that looks like concretely
+ WebAssembly is the format that makes this practical: it's a binary instruction format any conformant runtime can execute, independent of the language it was compiled from or the host it runs in. Traverse adds the two pieces raw WASM doesn't give you — a contract (what the capability needs, what it guarantees, what must be true before and after it runs) and a runtime that enforces that contract on every single execution, not just the first one someone tested.
+
+ Concretely: you write the rule once in Rust, compile it to a WASM capability, and register it. From then on, your web app, your backend, your mobile app (where a shipped embedder exists), and an AI agent over MCP all call the same binary and get the same enforced result. There's no second implementation to drift, because there's no second implementation.
+
+ What this doesn't solve
+ It doesn't remove the need for platform-specific UI — you still build a native-feeling frontend for each platform if that's what your product needs. And it isn't free: writing a contract and thinking through preconditions and postconditions is more upfront work than just calling a function. It's worth it specifically for the logic that's genuinely shared, genuinely important, and genuinely getting reimplemented right now. If a rule only ever lives in one place, none of this applies — see why I stopped writing the same business logic four times for the fuller version of this argument.
+
diff --git a/src/pages/questions/how-do-i-choose-between-a-progressive-web-app-and-traverse.astro b/src/pages/questions/how-do-i-choose-between-a-progressive-web-app-and-traverse.astro
new file mode 100644
index 0000000..cb305e8
--- /dev/null
+++ b/src/pages/questions/how-do-i-choose-between-a-progressive-web-app-and-traverse.astro
@@ -0,0 +1,38 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'Should I build a Progressive Web App or use Traverse?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: "They're not alternatives — a PWA is a delivery model for your UI (any device with a browser, installable, offline-capable to varying degrees), while Traverse governs the business logic underneath any UI, PWA included. A PWA's frontend can call a Traverse capability through the Web embedder SDK the same way any browser-hosted app does.",
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/blog/cross-platform-rarely-means-what-it-sounds-like.html', label: 'Why "cross-platform" rarely means what it sounds like' },
+ { href: '/questions/does-traverse-work-offline.html', label: 'Does Traverse work offline?' },
+ { href: '/questions/what-is-the-browser-adapter.html', label: 'What is the browser adapter?' },
+ { href: '/compare/vs-cross-platform-frameworks.html', label: 'Traverse vs Flutter, Electron, and Tauri' },
+];
+---
+
+ This isn't really an either/or, because a PWA and Traverse answer different questions. A Progressive Web App is a delivery and packaging model: your web app becomes installable, gets an app icon, and can work offline to whatever degree the specific browser and OS combination supports — with real, honestly-should-be-mentioned variance, since PWA capability support (background sync, push notifications, install prompts) differs meaningfully between, say, desktop Chrome and iOS Safari.
+
+ Traverse doesn't compete with any of that — it has no opinion on how your app gets installed or delivered. What it governs is the logic your PWA's frontend calls into. That logic is a WASM capability with an enforced contract, loadable directly through the Web embedder SDK, which is exactly the same mechanism any browser-hosted app uses — a PWA is still, under the hood, a web page, so nothing about "progressive" changes how it talks to a Traverse capability.
+
+ Where this actually helps a PWA specifically
+ PWAs lean hard on working offline, and Traverse capabilities execute locally by default with no network round trip required — see does Traverse work offline. That's a natural fit: a PWA's offline-first UI calling a capability that's also, by construction, offline-capable, rather than a UI promising offline behavior undermined by logic that secretly needs a server round trip.
+
diff --git a/src/pages/questions/how-do-i-package-a-capability-for-multiple-platforms.astro b/src/pages/questions/how-do-i-package-a-capability-for-multiple-platforms.astro
new file mode 100644
index 0000000..56ec9c7
--- /dev/null
+++ b/src/pages/questions/how-do-i-package-a-capability-for-multiple-platforms.astro
@@ -0,0 +1,40 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'How do I package a capability for multiple platforms?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: "You don't package it differently per platform — that's the point of compiling to WASM. You build the capability once into a registry bundle (a manifest plus its contract, WASM module, and any events or workflows it participates in), and the same bundle is what every executor — native or browser — loads. Platform-specific packaging only exists one layer up, in the host application that embeds Traverse.",
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/questions/what-is-the-capability-registry.html', label: 'What is the capability registry?' },
+ { href: '/docs/quickstart.html', label: 'Quickstart' },
+ { href: '/questions/what-framework-runs-business-logic-on-any-os.html', label: 'What framework lets me write business logic once and run it on any OS?' },
+ { href: '/docs/concepts.html', label: 'Core Concepts: Traverse Docs' },
+];
+---
+
+ You don't, in the sense of maintaining separate build outputs per target — and that's a deliberate design choice, not an oversight. A capability's WASM binary and its contract are compiled once and grouped, along with any events or workflows it participates in, into a registry bundle: a manifest plus a capabilities/ directory holding each capability's contract and module. That bundle is what gets loaded, unchanged, by whichever executor is running it — the native WasmExecutor or the browser's Web embedder SDK.
+
+ The CLI validates a bundle before it's registered, and that validation doesn't vary by target platform either, because the bundle itself has no platform-specific content to validate differently.
+
+ Where platform-specific packaging actually happens
+ It exists, just one layer up — in the host application, not in the capability. A native desktop app embedding traverse-embedder gets built and distributed the normal way for Windows, macOS, or Linux (an installer, a container image, a plain binary). A web app loads the same bundle through the Web embedder SDK as a static asset served alongside the rest of your frontend. Neither of those steps touches or duplicates the bundle itself — they just point their respective executor at the same file.
+
+ Practically: build your bundle once with cargo run -p traverse-cli-rs -- bundle inspect (or the equivalent build step for your capability), confirm it validates, and treat "does this run on platform X" as a question about whether an executor for X exists yet — see Platforms — not a question about whether you need a platform-specific build of your own capability.
+
diff --git a/src/pages/questions/how-do-i-share-business-logic-between-web-and-desktop.astro b/src/pages/questions/how-do-i-share-business-logic-between-web-and-desktop.astro
new file mode 100644
index 0000000..7bbe20c
--- /dev/null
+++ b/src/pages/questions/how-do-i-share-business-logic-between-web-and-desktop.astro
@@ -0,0 +1,41 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'How do I share business logic between a web app and a desktop app?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: "Write the rule once as a Traverse capability, compile it to WASM with a contract, and let your web app load it through the Web embedder SDK or local browser adapter while your desktop app loads the identical bundle through a native embedder — most naturally traverse-embedder inside a Tauri app if you want both in Rust end to end.",
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/questions/can-i-run-the-same-business-logic-in-browser-and-native-apps.html', label: 'Can I run the same business logic in a browser app and a native app?' },
+ { href: '/questions/can-i-use-traverse-with-tauri.html', label: 'Can I use Traverse with Tauri?' },
+ { href: '/compare/vs-cross-platform-frameworks.html', label: 'Traverse vs Flutter, Electron, and Tauri' },
+ { href: '/docs/guides/react-integration.html', label: 'React Integration guide' },
+];
+---
+
+ This is the exact shape of problem Traverse was built around, so the answer is fairly direct: write the rule once as a Rust capability, compile it to a WASM binary, attach a contract, and register it into a bundle. From there, your web app and your desktop app each load that one bundle through whichever executor matches their host — they're not two implementations that happen to agree, they're one implementation two hosts both call.
+
+ The web side
+ Your web frontend talks to the capability either through the local browser adapter over a simple HTTP request (the pattern the React integration guide covers step by step) or, for a single pre-published capability, directly through the Web embedder SDK's verified execution path in the browser's native WASM host.
+
+ The desktop side
+ Your desktop app embeds the same bundle through a native host. If you're building that desktop app in Tauri, this is close to seamless — Tauri's backend is already Rust, so a Tauri command calls straight into the public traverse-embedder crate with no bridge in between (see the worked example in the Traverse vs. cross-platform frameworks comparison). If your desktop app is Electron, its renderer is a Chromium page and can use the same Web embedder path the browser app uses.
+
+ Either way, the guarantee you get is structural, not procedural: the web app and the desktop app can't drift apart on this rule, because there's no second copy of it to drift.
+
diff --git a/src/pages/questions/how-do-i-test-a-capability-before-shipping-it-to-multiple-platforms.astro b/src/pages/questions/how-do-i-test-a-capability-before-shipping-it-to-multiple-platforms.astro
new file mode 100644
index 0000000..bd4689d
--- /dev/null
+++ b/src/pages/questions/how-do-i-test-a-capability-before-shipping-it-to-multiple-platforms.astro
@@ -0,0 +1,43 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'How do I test a capability before shipping it to multiple platforms?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: "Test the capability once, against its contract, independent of any platform — since the sandboxed WASM binary has no OS-dependent behavior to test per platform in the first place. Validate the bundle with the CLI, exercise it through the native executor with representative inputs, and check the trace output; a capability with no declared host calls needs no further per-OS test pass beyond confirming the executor itself works on that host.",
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/questions/how-do-ci-pipelines-test-traverse-across-operating-systems.html', label: 'How does Traverse verify cross-OS behavior actually matches?' },
+ { href: '/questions/do-different-operating-systems-see-different-behavior-from-the-same-capability.html', label: 'Can different operating systems see different behavior from the same capability?' },
+ { href: '/questions/what-is-a-trace-artifact.html', label: 'What is a trace artifact in Traverse?' },
+ { href: '/docs/guides/cross-os-capability.html', label: 'Write once, run on Windows, macOS, Linux, and the browser' },
+];
+---
+
+ The reassuring answer is that "test it for each platform" mostly collapses into "test it once," because a capability with no declared host calls has no OS-dependent code path for a platform-specific test to catch. Your test plan should center on the contract, not the target.
+
+ What to actually test
+
+ - Validate the bundle. The CLI's bundle inspection checks that contracts are well-formed and referenced modules exist — run this before anything else.
+ - Exercise the contract's edge cases. Valid inputs at the boundary of your preconditions, invalid inputs that should be rejected, and the postconditions you expect on success. This is testing the capability's logic, and it's identical regardless of which executor eventually runs it.
+ - Read the trace, don't just check the output. A trace artifact confirms
contract_validated, preconditions_met, and postconditions_met explicitly — catching a case where the output happened to look right but a precondition was silently skipped.
+
+
+ What's left to test per platform
+ Realistically, very little: that the executor itself is correctly installed and configured on that host (a native binary that runs, a browser embedder that loads), and — if the capability's contract declares any host calls — that the specific host implementation of those calls behaves correctly on that platform, since that's the one place OS-specific code could legitimately exist. For a capability with an empty host_calls list, there's genuinely nothing else to test per OS beyond confirming the runtime environment itself is set up. The cross-OS capability guide shows this in practice, comparing trace output from a native run against a browser run of the same bundle.
+
diff --git a/src/pages/questions/how-does-versioning-work-across-platforms.astro b/src/pages/questions/how-does-versioning-work-across-platforms.astro
new file mode 100644
index 0000000..143fdab
--- /dev/null
+++ b/src/pages/questions/how-does-versioning-work-across-platforms.astro
@@ -0,0 +1,38 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'How does capability versioning work when it runs on multiple platforms?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: 'Versioning belongs to the capability and its contract, not to any particular host platform — there is exactly one version number, tracked in the registry, regardless of how many executors (native, browser) load that version. A native host and a browser host can be pinned to different versions of the same capability id if they update on different schedules, but neither host maintains its own separate version history.',
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/questions/what-is-contract-versioning.html', label: 'What is contract versioning in Traverse?' },
+ { href: '/questions/what-is-the-capability-registry.html', label: 'What is the capability registry?' },
+ { href: '/questions/what-is-the-contract-lifecycle.html', label: 'What is the contract lifecycle in Traverse?' },
+ { href: '/questions/can-i-run-the-same-business-logic-in-browser-and-native-apps.html', label: 'Can I run the same business logic in a browser app and a native app?' },
+];
+---
+
+ Versioning is a property of the capability and the registry entry that tracks it — namespace.name plus a semantic version — not something each host platform tracks independently. There's one version history for a given capability id, whether it's ever loaded by a native executor, a browser embedder, both, or eventually a mobile one.
+
+ What can legitimately differ between hosts is which version each one has currently pinned. A native backend might already be running pricing.eligibility-check@2.1.0 while a browser deployment is still serving 2.0.0, if the rollout schedules haven't caught up with each other. That's a normal, visible fact about your deployment — the trace artifact for each execution records exactly which version ran — not a hidden inconsistency.
+
+ Why this matters for cross-platform rollout
+ Because versioning lives with the capability, not the platform, a breaking contract change is a single decision with a single new version number, applied everywhere at once conceptually — you then choose, per host, when to actually adopt it. There's no scenario where "the Windows version of this rule" and "the browser version of this rule" silently diverge into separately-numbered lineages; if they're both running capability X, they're both running some version of the same tracked history, and you can always tell which one from the trace.
+
diff --git a/src/pages/questions/how-is-traverse-different-from-a-shared-rust-library.astro b/src/pages/questions/how-is-traverse-different-from-a-shared-rust-library.astro
new file mode 100644
index 0000000..7b17a11
--- /dev/null
+++ b/src/pages/questions/how-is-traverse-different-from-a-shared-rust-library.astro
@@ -0,0 +1,40 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: "Why not just put the business logic in a shared Rust library instead of using Traverse?",
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: "A shared Rust crate gets you code reuse across Rust callers, but every non-Rust host still needs an FFI binding, there's no enforced contract, and there's no execution trace. A Traverse capability compiles to WASM instead of a native library, so any WASM-hosting caller — Rust, JavaScript, an AI agent over MCP — invokes the exact same binary through one interface, with preconditions and postconditions enforced and every execution recorded.",
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/questions/how-do-i-avoid-rewriting-business-logic-for-every-platform.html', label: 'How do I avoid rewriting business logic for every platform?' },
+ { href: '/questions/what-is-a-contract-in-traverse.html', label: 'What is a contract in Traverse?' },
+ { href: '/questions/what-is-a-trace-artifact.html', label: 'What is a trace artifact in Traverse?' },
+ { href: '/questions/what-framework-runs-business-logic-on-any-os.html', label: 'What framework lets me write business logic once and run it on any OS?' },
+];
+---
+
+ It's a fair question, because a plain shared library is the simpler-sounding answer to "stop duplicating this logic." Put the pricing rule in a crate, publish it internally, have every Rust service depend on it. For a team that's 100% Rust and never needs the rule outside that ecosystem, that's a reasonable, lighter-weight choice — genuinely, don't reach for Traverse if that's your whole situation.
+
+ The gap shows up at the edges. A shared crate is native code: your JavaScript frontend, your Python data pipeline, and your AI agent can't call it directly. Each of those needs its own FFI binding, a WASM build of the crate compiled separately, or a network hop to a service that wraps it — and now you're maintaining integration surface for every non-Rust caller. A crate also has no built-in contract: nothing stops a caller from passing invalid input, and nothing records what actually happened when it ran, beyond whatever logging you added yourself.
+
+ What a Traverse capability does differently
+ A capability compiles to WebAssembly instead of a native library, so it's not Rust-caller-only — any WASM-hosting environment can load it: a browser, a native host through traverse-embedder, an AI agent through MCP, all through the same interface. The contract attached to it declares preconditions and postconditions the runtime actually enforces, not just documents. And every execution produces a trace artifact — what ran, with what inputs, validated against which contract, with what result.
+
+ The honest tradeoff: a contract is more upfront work than a public function signature, and there's real WASM sandboxing overhead compared to a direct native call. Worth it specifically when the rule needs to be called from outside Rust, needs enforced correctness, or needs an audit trail. Not worth it for logic that's genuinely internal to one Rust service.
+
diff --git a/src/pages/questions/how-is-traverse-different-from-docker.astro b/src/pages/questions/how-is-traverse-different-from-docker.astro
new file mode 100644
index 0000000..20f822f
--- /dev/null
+++ b/src/pages/questions/how-is-traverse-different-from-docker.astro
@@ -0,0 +1,40 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'How is Traverse different from Docker?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: "Docker packages an entire environment — OS layer, dependencies, runtime — so a service behaves consistently across hosts, at the cost of shipping megabytes to gigabytes per image and needing a container runtime everywhere it runs. Traverse capabilities are WASM binaries, typically kilobytes, with no OS layer at all, governed by a contract instead of an image manifest, and able to run inside a browser tab — somewhere a container fundamentally cannot.",
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/compare/vs-serverless.html', label: 'Traverse vs Serverless Functions' },
+ { href: '/compare/vs-microservices.html', label: 'Traverse vs Microservices' },
+ { href: '/questions/what-is-the-wasm-sandbox.html', label: 'What is the WASM sandbox?' },
+ { href: '/questions/what-framework-runs-business-logic-on-any-os.html', label: 'What framework lets me write business logic once and run it on any OS?' },
+];
+---
+
+ Both Docker and Traverse are answers to "make this run consistently somewhere else," but they solve it at completely different layers. Docker packages an entire environment — the OS userland, your dependencies, your runtime, your app — into an image, so the same image behaves the same way on any host with a compatible container runtime installed. That's a heavyweight but very general solution: it works for basically any application, regardless of language or architecture.
+
+ A Traverse capability doesn't package an environment at all — it doesn't need one. It's a WASM binary, sandboxed by the WASM spec itself rather than by container namespaces, with no OS layer, no base image, and typically no dependency footprint beyond what the sandbox already provides. Where a minimal container image is tens of megabytes, a Traverse capability is usually kilobytes.
+
+ The one Docker structurally cannot do
+ A container needs a container runtime — Docker Engine, containerd, something implementing the OCI spec — running on the host. That rules out running a container inside a browser tab, full stop. A Traverse capability runs there today, through the Web embedder SDK, because a WASM binary only needs a WASM host, and every modern browser already is one.
+
+ They're also governed differently: a container's contract with the world is effectively "this image, this entrypoint, these exposed ports" — no built-in enforcement of what the code inside actually does to its inputs. A Traverse capability's contract declares preconditions, postconditions, and permissions, and the runtime checks all of it on every execution, producing a trace. If you need "runs the same everywhere, including places without a container runtime, with enforced input/output guarantees," that's the Traverse case. If you need "package this entire arbitrary service so ops can deploy it anywhere," that's still Docker's job — and the two aren't mutually exclusive; a Traverse-embedding service can absolutely ship inside a container.
+
diff --git a/src/pages/questions/how-is-traverse-different-from-dotnet-maui.astro b/src/pages/questions/how-is-traverse-different-from-dotnet-maui.astro
new file mode 100644
index 0000000..5c7f499
--- /dev/null
+++ b/src/pages/questions/how-is-traverse-different-from-dotnet-maui.astro
@@ -0,0 +1,38 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'How is Traverse different from .NET MAUI?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: ".NET MAUI shares one XAML-based UI layer across Windows, macOS, iOS, and Android, all shipped and mature. Traverse has no UI layer — it governs the business logic underneath, as a WASM capability callable from a MAUI app, a backend, or an AI agent alike. Traverse's own .NET/WinUI embedder is real, working code, but unreleased, which is worth knowing if you're specifically looking to pair the two today.",
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/compare/vs-cross-platform-frameworks.html', label: 'Traverse vs Flutter, Electron, and Tauri (full comparison)' },
+ { href: '/questions/can-i-use-traverse-with-dotnet-maui.html', label: 'Can I use Traverse with .NET MAUI today?' },
+ { href: '/questions/how-is-traverse-different-from-flutter.html', label: 'How is Traverse different from Flutter?' },
+ { href: '/platforms.html', label: 'Where Traverse actually runs (platform status)' },
+];
+---
+
+ .NET MAUI is Microsoft's answer to shipping one UI codebase across Windows, macOS, iOS, and Android, using a shared XAML-based layer over each platform's native controls. It's a mature, shipped UI framework, with all four of those platforms genuinely supported today.
+
+ Traverse doesn't have a UI layer to compare against MAUI's at all. What it governs is the logic behind whatever UI you're using — the rule that runs when a MAUI page's button is tapped. That logic compiles once to a WASM capability with an enforced contract, callable identically from the MAUI app, a backend service, or an AI agent, rather than being C# code that only exists inside that one app.
+
+ The honest caveat if you want to pair them today
+ Calling a Traverse capability directly from a MAUI app on iOS or Android runs into the same mobile-embedder status covered elsewhere on this site: the .NET/WinUI embedder (built on a Wasmtime .NET bridge) is real, working code, but it's unreleased, and it's specifically the Windows/WinUI side of .NET — not yet the cross-platform MAUI runtime targeting iOS and Android. So pairing the two cleanly on Windows desktop is closer than pairing them on MAUI's mobile targets today. See Platforms for the exact, current state before you plan around it.
+
diff --git a/src/pages/questions/how-is-traverse-different-from-electron.astro b/src/pages/questions/how-is-traverse-different-from-electron.astro
new file mode 100644
index 0000000..6a9bb08
--- /dev/null
+++ b/src/pages/questions/how-is-traverse-different-from-electron.astro
@@ -0,0 +1,40 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'How is Traverse different from Electron?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: "Electron ships a desktop app by bundling Chromium and Node.js, so your JavaScript logic and your UI both live inside that one packaged app. Traverse has no UI or app-shell layer — it's a contract-governed WASM runtime for the logic behind whatever shell you use, whether that's Electron, a web app, a CLI, or an AI agent, all calling the same binary.",
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/compare/vs-cross-platform-frameworks.html', label: 'Traverse vs Flutter, Electron, and Tauri (full comparison)' },
+ { href: '/questions/how-is-traverse-different-from-flutter.html', label: 'How is Traverse different from Flutter?' },
+ { href: '/questions/what-is-the-browser-adapter.html', label: 'What is the browser adapter?' },
+ { href: '/blog/wasm-business-logic.html', label: 'What WASM actually gives you for business logic' },
+];
+---
+
+ Electron solves desktop packaging: it bundles Chromium and Node.js so a web app can ship as a native-feeling Windows, macOS, or Linux application, with your JavaScript running the UI and the logic behind it in the same process. That's a genuinely useful, mature approach, and it's why so many desktop tools (VS Code among them) are built on it.
+
+ Traverse isn't a packaging tool and doesn't produce an app shell at all. It's a runtime for one specific layer: business logic that needs to behave identically no matter what's calling it. You write a capability in Rust, compile it to WASM, attach a contract, and the runtime enforces that contract before and after every execution — whether the caller is an Electron app, a plain web page, a CLI, or an AI agent over MCP.
+
+ The practical difference
+ In Electron, your business logic is just more JavaScript inside the bundle — no separate enforcement, no built-in trace of what ran and why, and no path to reuse that logic from a non-Electron caller without copying the code. In Traverse, the logic is a WASM binary with a machine-readable contract, discoverable through a registry, producing a structured trace on every execution, and callable identically from Electron or from anywhere else.
+
+ They're not mutually exclusive. An Electron app can call into a Traverse capability the same way a browser tab does — through the browser adapter or an embedder — for the specific rules where consistency and auditability actually matter, while Electron keeps doing the packaging and windowing work it's built for. The full comparison covers the pattern in more depth, with a concrete example using Tauri (Electron's Rust-based sibling).
+
diff --git a/src/pages/questions/how-is-traverse-different-from-flutter.astro b/src/pages/questions/how-is-traverse-different-from-flutter.astro
new file mode 100644
index 0000000..fe59add
--- /dev/null
+++ b/src/pages/questions/how-is-traverse-different-from-flutter.astro
@@ -0,0 +1,41 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'How is Traverse different from Flutter?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: "Flutter is a UI framework: it renders a widget tree to native-feeling screens on Windows, macOS, Linux, iOS, Android, and the web from one Dart codebase. Traverse has no UI layer at all — it governs the business logic underneath any UI, as a contract-enforced WASM capability that's also callable from a backend, a CLI, or an AI agent, not just from inside one Flutter app.",
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/compare/vs-cross-platform-frameworks.html', label: 'Traverse vs Flutter, Electron, and Tauri (full comparison)' },
+ { href: '/questions/what-framework-runs-business-logic-on-any-os.html', label: 'What framework lets me write business logic once and run it on any OS?' },
+ { href: '/questions/how-is-traverse-different-from-a-plugin-system.html', label: 'How is Traverse different from a plugin system?' },
+ { href: '/questions/what-is-a-wasm-capability.html', label: 'What is a WASM capability in Traverse?' },
+];
+---
+
+ Flutter and Traverse aren't really in the same category, even though they both get pulled into "cross-platform" conversations. Flutter is a UI framework: you write widgets in Dart, and Flutter's engine renders them consistently on Windows, macOS, Linux, iOS, Android, and the web. It's shipped, mature, and genuinely good at exactly that.
+
+ Traverse has no rendering engine and no widget system. What it governs is what happens behind the UI — the pricing calculation, the eligibility check, the validation rule your Flutter app's button press eventually calls into. That logic compiles once to WebAssembly with a machine-readable contract, and the same binary is callable from your Flutter app, your backend, your CLI, or an MCP-connected AI agent, all getting the identical result because it's the identical binary — not a Dart implementation and a separate server-side reimplementation that can drift apart.
+
+ Where the OS-reach honestly differs
+ Worth saying directly: Flutter's OS coverage is broader today. It ships on desktop, mobile, and web, all mature. Traverse's device-independent WASM capabilities run natively on Windows, macOS, and Linux and in the browser today; Android and .NET/WinUI embedders are in progress without a public release, and iOS is blocked on the WASM engine ecosystem. See Platforms for the specifics.
+
+ Using them together
+ A Flutter app can call into a Traverse capability the same way any other host does — through an embedder or an HTTP adapter, depending on the target. The Flutter shell keeps rendering the UI it's good at; the rule underneath gets a contract, an enforcement point, and a trace artifact it wouldn't otherwise have. The full breakdown, including a concrete integration example, is on the Traverse vs. cross-platform app frameworks comparison page.
+
diff --git a/src/pages/questions/index.astro b/src/pages/questions/index.astro
index ca49212..2fd466b 100644
--- a/src/pages/questions/index.astro
+++ b/src/pages/questions/index.astro
@@ -59,6 +59,53 @@ const groups = [
['what-is-contract-driven-ai-development.html', 'What is contract-driven AI development?'],
],
},
+ {
+ label: 'Platforms and portability',
+ items: [
+ ['what-framework-runs-business-logic-on-any-os.html', 'What framework lets me write business logic once and run it on any OS?'],
+ ['does-traverse-support-windows-macos-and-linux.html', 'Does Traverse support Windows, macOS, and Linux?'],
+ ['what-operating-systems-does-traverse-support.html', 'What operating systems does Traverse support?'],
+ ['can-traverse-build-mobile-apps.html', 'Can I build a mobile app with Traverse?'],
+ ['what-does-device-independent-mean-in-traverse.html', 'What does "device-independent" mean in Traverse?'],
+ ['how-do-i-avoid-rewriting-business-logic-for-every-platform.html', 'How do I avoid rewriting business logic for every platform?'],
+ ['how-is-traverse-different-from-flutter.html', 'How is Traverse different from Flutter?'],
+ ['how-is-traverse-different-from-electron.html', 'How is Traverse different from Electron?'],
+ ['can-i-use-traverse-with-tauri.html', 'Can I use Traverse with Tauri?'],
+ ['can-i-use-traverse-with-electron.html', 'Can I use Traverse with Electron?'],
+ ['how-is-traverse-different-from-dotnet-maui.html', 'How is Traverse different from .NET MAUI?'],
+ ['can-i-use-traverse-with-dotnet-maui.html', 'Can I use Traverse with .NET MAUI today?'],
+ ['can-i-share-logic-between-ios-and-android-apps.html', 'Can I share business logic between an iOS app and an Android app?'],
+ ['what-happens-if-traverse-doesnt-support-my-platform-yet.html', "What happens if Traverse doesn't support my platform yet?"],
+ ['is-traverse-a-cross-platform-framework.html', 'Is Traverse a cross-platform framework?'],
+ ['is-traverse-suitable-for-a-cross-platform-desktop-app.html', 'Is Traverse suitable for a cross-platform desktop app?'],
+ ['what-is-the-difference-between-portable-and-cross-platform.html', 'What is the difference between "portable" and "cross-platform"?'],
+ ['can-i-migrate-existing-business-logic-to-traverse.html', 'Can I migrate existing business logic into Traverse?'],
+ ['how-do-ci-pipelines-test-traverse-across-operating-systems.html', 'How does Traverse verify cross-OS behavior actually matches?'],
+ ['can-i-run-the-same-business-logic-in-browser-and-native-apps.html', 'Can I run the same business logic in a browser app and a native app?'],
+ ['how-do-i-share-business-logic-between-web-and-desktop.html', 'How do I share business logic between a web app and a desktop app?'],
+ ['does-traverse-work-offline.html', 'Does Traverse work offline?'],
+ ['is-webassembly-cross-platform.html', 'Is WebAssembly cross-platform?'],
+ ['what-is-the-wasm-sandbox.html', 'What is the WASM sandbox?'],
+ ['how-is-traverse-different-from-a-shared-rust-library.html', 'Why not just use a shared Rust library instead of Traverse?'],
+ ['how-is-traverse-different-from-docker.html', 'How is Traverse different from Docker?'],
+ ['can-i-run-traverse-capabilities-in-a-docker-container.html', 'Can I run Traverse capabilities inside a Docker container?'],
+ ['how-do-i-package-a-capability-for-multiple-platforms.html', 'How do I package a capability for multiple platforms?'],
+ ['can-traverse-capabilities-call-native-os-apis.html', 'Can Traverse capabilities call native OS APIs?'],
+ ['can-non-rust-teams-use-traverse.html', "Can a team that doesn't write Rust still use Traverse?"],
+ ['is-there-a-performance-cost-to-running-the-same-binary-on-every-os.html', 'Is there a performance cost to running the same binary on every OS?'],
+ ['what-teams-should-not-use-traverse-for-cross-platform-apps.html', 'When should a team NOT use Traverse for a cross-platform app?'],
+ ['what-questions-should-i-ask-before-picking-a-cross-platform-approach.html', 'What should I ask before picking a cross-platform approach?'],
+ ['do-different-operating-systems-see-different-behavior-from-the-same-capability.html', 'Can different operating systems see different behavior from the same capability?'],
+ ['how-does-versioning-work-across-platforms.html', 'How does capability versioning work across multiple platforms?'],
+ ['can-i-use-traverse-in-a-monorepo-with-multiple-apps.html', 'Can I use Traverse in a monorepo with multiple apps?'],
+ ['what-is-a-registry-bundle-and-does-it-work-on-every-os.html', 'What is a registry bundle, and does it work on every OS?'],
+ ['how-do-i-choose-between-a-progressive-web-app-and-traverse.html', 'Should I build a Progressive Web App or use Traverse?'],
+ ['can-ai-agents-call-the-same-capability-regardless-of-os.html', 'Can an AI agent call the same capability my app uses, regardless of OS?'],
+ ['how-do-i-test-a-capability-before-shipping-it-to-multiple-platforms.html', 'How do I test a capability before shipping it to multiple platforms?'],
+ ['what-is-the-smallest-possible-traverse-capability.html', 'What is the smallest possible Traverse capability?'],
+ ['can-i-use-traverse-for-a-saas-product-on-multiple-operating-systems.html', 'Can I use Traverse for a SaaS product on multiple operating systems?'],
+ ],
+ },
{
label: 'How Traverse compares',
items: [
diff --git a/src/pages/questions/is-there-a-performance-cost-to-running-the-same-binary-on-every-os.astro b/src/pages/questions/is-there-a-performance-cost-to-running-the-same-binary-on-every-os.astro
new file mode 100644
index 0000000..a95a4d8
--- /dev/null
+++ b/src/pages/questions/is-there-a-performance-cost-to-running-the-same-binary-on-every-os.astro
@@ -0,0 +1,40 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'Is there a performance cost to running the same binary on every OS?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: "There's a real, non-zero WASM sandboxing and contract-validation overhead compared to calling a native function directly in-process — that's the price of the sandbox and the governance, not of cross-OS portability specifically. The execution itself, once compiled, runs at near-native speed under Wasmtime; the overhead is at the boundary (input/output validation, contract checks, trace writing), not in the computation.",
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/questions/what-is-traverse-performance.html', label: "What is Traverse's performance like?" },
+ { href: '/questions/what-is-the-wasm-sandbox.html', label: 'What is the WASM sandbox?' },
+ { href: '/questions/what-is-a-trace-artifact.html', label: 'What is a trace artifact in Traverse?' },
+ { href: '/questions/how-is-traverse-different-from-a-shared-rust-library.html', label: 'Why not just use a shared Rust library instead of Traverse?' },
+];
+---
+
+ Worth separating two different costs that get conflated under "performance overhead," because only one of them has anything to do with cross-OS portability.
+
+ Cross-OS portability itself is essentially free. Wasmtime compiles WASM to native machine code ahead of execution and runs it at close to native speed, on Windows, macOS, or Linux alike — there's no interpretation layer or per-OS translation step slowing things down because the binary happens to be portable. The "same binary everywhere" property doesn't trade away raw execution speed.
+
+ The governance layer has a real, separate cost. Contract validation on the way in, postcondition checks on the way out, and writing a structured trace artifact for every execution are actual work the runtime does that a bare function call wouldn't. That cost exists whether you're running on one OS or five — it's the price of getting enforced correctness and an audit trail, not the price of portability.
+
+ Whether that tradeoff is worth it
+ For a capability called occasionally — a pricing calculation, an eligibility check — the governance overhead is very unlikely to be the bottleneck in your system. For something called in an extremely tight hot loop at very high frequency, the validation and tracing cost is worth actually measuring against your latency budget before committing. There's no substitute for benchmarking your specific capability and call pattern; see Traverse's performance page for what's measured today, and treat anything not measured there as genuinely unmeasured rather than assumed fine.
+
diff --git a/src/pages/questions/is-traverse-a-cross-platform-framework.astro b/src/pages/questions/is-traverse-a-cross-platform-framework.astro
new file mode 100644
index 0000000..0037023
--- /dev/null
+++ b/src/pages/questions/is-traverse-a-cross-platform-framework.astro
@@ -0,0 +1,38 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'Is Traverse a cross-platform framework?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: "It's a cross-platform framework for business logic specifically, not for building UIs. Traverse capabilities compile once and run unmodified on Windows, macOS, Linux, and in the browser today, with mobile embedders in progress or blocked. It doesn't render a UI on any of those platforms — pair it with whatever UI framework you're already using.",
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/questions/what-framework-runs-business-logic-on-any-os.html', label: 'What framework lets me write business logic once and run it on any OS?' },
+ { href: '/compare/vs-cross-platform-frameworks.html', label: 'Traverse vs Flutter, Electron, and Tauri' },
+ { href: '/questions/what-operating-systems-does-traverse-support.html', label: 'What operating systems does Traverse support?' },
+ { href: '/questions/what-is-traverse.html', label: 'What is Traverse?' },
+];
+---
+
+ Depends what you mean by "cross-platform," and that word carries more assumptions than it seems to. If you mean "one codebase that renders a native-feeling UI on multiple operating systems" — the Flutter/Electron/Tauri sense — no, Traverse doesn't do that and isn't trying to. It has no UI layer at all.
+
+ If you mean "one piece of logic that produces the same result no matter which operating system, UI framework, or non-UI caller invokes it" — yes, precisely and by design. You write a capability once, compile it to WASM, attach a contract, and the runtime enforces that contract wherever the binary executes. Today that's natively on Windows, macOS, and Linux, and in the browser; the same binary, no per-OS branch.
+
+ Why the distinction matters
+ Calling Traverse "cross-platform" without that qualifier invites the wrong comparison — stacking it against Flutter feature-for-feature on UI, where it simply has nothing to offer, since it isn't a UI tool. The honest framing is that it's cross-platform for the layer underneath the UI, and it's meant to pair with a UI framework, not replace one. The full comparison spells out exactly where that boundary sits and how the two categories combine.
+
diff --git a/src/pages/questions/is-traverse-suitable-for-a-cross-platform-desktop-app.astro b/src/pages/questions/is-traverse-suitable-for-a-cross-platform-desktop-app.astro
new file mode 100644
index 0000000..404d2aa
--- /dev/null
+++ b/src/pages/questions/is-traverse-suitable-for-a-cross-platform-desktop-app.astro
@@ -0,0 +1,40 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'Is Traverse suitable for a cross-platform desktop app?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: "For the business-logic layer, yes — native Windows, macOS, and Linux support is Traverse's most mature, shipped target. For the UI itself, no, since Traverse has no UI layer; pair it with a desktop UI framework (Tauri is a particularly natural fit, since both are Rust) and let Traverse govern the logic that framework calls into.",
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/compare/vs-cross-platform-frameworks.html', label: 'Traverse vs Flutter, Electron, and Tauri' },
+ { href: '/questions/can-i-use-traverse-with-tauri.html', label: 'Can I use Traverse with Tauri?' },
+ { href: '/questions/does-traverse-support-windows-macos-and-linux.html', label: 'Does Traverse support Windows, macOS, and Linux?' },
+ { href: '/docs/quickstart.html', label: 'Quickstart' },
+];
+---
+
+ Split the question in two, because the honest answer is different for each half. For the business logic behind a desktop app — the rules, calculations, and validations the UI calls into — yes, unreservedly. Native (Windows, macOS, Linux) is Traverse's default, most mature, shipped target, and a capability built for it needs no OS-specific code to run identically on all three.
+
+ For the desktop app's UI itself, Traverse isn't the tool — it has no windowing system, no widget library, nothing that paints a screen. You'll still pick a UI framework: Tauri, Electron, Flutter, or a native toolkit per OS if you want that level of control.
+
+ Which UI framework pairs best
+ Tauri is the most natural fit specifically, because its backend is Rust — the same language Traverse capabilities compile from. A Tauri command can call directly into the public traverse-embedder crate with no FFI boundary to cross. Electron works too, through its Chromium-based renderer, which is already a WASM host. Flutter's Dart runtime doesn't host WASM the same way, so pairing there typically goes through a native plugin bridging to a traverse-embedder-based process instead of an in-process call.
+
+ The full comparison walks through the Tauri pairing with a real code example, if that's the combination you're considering.
+
diff --git a/src/pages/questions/is-webassembly-cross-platform.astro b/src/pages/questions/is-webassembly-cross-platform.astro
new file mode 100644
index 0000000..5f4f478
--- /dev/null
+++ b/src/pages/questions/is-webassembly-cross-platform.astro
@@ -0,0 +1,40 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'Is WebAssembly cross-platform?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: "Yes — that's the point of the format. A WASM binary is a portable instruction set, not machine code for a specific CPU or OS, so any conformant runtime executes it the same way. That's necessary but not sufficient for building a real cross-platform system: WASM alone gives you a portable binary, not a way to describe what it does, validate it, or trace what happened when it ran. Traverse adds that layer on top.",
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/questions/what-framework-runs-business-logic-on-any-os.html', label: 'What framework lets me write business logic once and run it on any OS?' },
+ { href: '/questions/what-is-the-wasm-sandbox.html', label: 'What is the WASM sandbox?' },
+ { href: '/blog/wasm-business-logic.html', label: 'What WASM actually gives you for business logic' },
+ { href: '/questions/can-traverse-run-without-wasm.html', label: 'Can Traverse run without WASM?' },
+];
+---
+
+ Yes. WebAssembly is a formally specified binary instruction format, not native code tied to a particular processor or operating system. Any runtime that implements the spec — a browser, Wasmtime, Wasmer, a custom embedder — executes a given .wasm file the same way. You compile once; you don't recompile per target the way you would for native machine code.
+
+ This is different from, say, a Java .jar, which needs a JVM present and configured per platform, or a native binary, which needs a separate build per OS and CPU architecture entirely. WASM's portability is closer to "the artifact itself doesn't know or care what's hosting it."
+
+ Why that's not the full answer for building a real system
+ A raw WASM binary is portable, but it's also just a file with some exported function names. It doesn't tell you what those functions expect as input, what they guarantee as output, what permissions they need, or whether a given execution actually behaved correctly. Two different callers could invoke it with incompatible assumptions and both technically "work," right up until they don't.
+
+ That's the gap Traverse fills on top of WASM's portability: a contract that declares inputs, outputs, preconditions, and postconditions, a runtime that enforces the contract on every execution, and a trace artifact recording what actually happened. The portability is WebAssembly's contribution. The governance — the part that makes it safe to build a real, auditable system out of that portability — is Traverse's.
+
diff --git a/src/pages/questions/what-does-device-independent-mean-in-traverse.astro b/src/pages/questions/what-does-device-independent-mean-in-traverse.astro
new file mode 100644
index 0000000..a3d5715
--- /dev/null
+++ b/src/pages/questions/what-does-device-independent-mean-in-traverse.astro
@@ -0,0 +1,43 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'What does "device-independent" mean in Traverse?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: "A device-independent capability is a WASM binary that runs unmodified on any client that loads it — the runtime doesn't recompile or branch per host. Execution happens locally on that client by default; the client can heuristically delegate a subset of the work to a server based on its own context (resource constraints, latency), rather than the capability being pinned to a fixed deployment target chosen ahead of time.",
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/questions/what-is-traverse.html', label: 'What is Traverse?' },
+ { href: '/questions/how-do-placement-targets-work.html', label: 'How do placement targets work in Traverse?' },
+ { href: '/questions/what-framework-runs-business-logic-on-any-os.html', label: 'What framework lets me write business logic once and run it on any OS?' },
+ { href: '/docs/concepts.html', label: 'Core Concepts: Traverse Docs' },
+];
+---
+
+ "Device-independent" describes the capability itself, not just where it happens to be deployed. A Traverse capability compiles to a single WASM binary. That binary carries its own contract — inputs, outputs, preconditions, postconditions — and any conformant WASM host can load and run it without recompiling it or maintaining a separate build per target. The same file that runs on your laptop through the CLI is the same file the browser embedder loads.
+
+ The independence goes further than "the binary is portable," though. Execution happens on the client by default — wherever the capability was loaded — and the client decides, using its own heuristics (things like resource constraints or latency), whether to run the whole thing locally or delegate some subset of it to a server. That decision isn't baked into the capability at authoring time. It isn't a fixed "this capability runs in the cloud" flag someone set once. It's evaluated live, by the client, against its own current context.
+
+ Why this is a meaningfully different model from "pick a target"
+ Earlier placement-oriented models (including Traverse's own older documentation) framed this as choosing a target — browser, edge, cloud, ai-pipeline — ahead of time, the way you'd pick a deployment region. The device-independent framing inverts that. The capability doesn't know or care where it will run. The client does, and it decides at the moment of execution, not at build time.
+
+ In practice, right now, that means local (native) and browser are the two contexts with a real, shipped executor behind this model — see Platforms for the honest, evidence-linked state of every target. The concept itself — one binary, client-decided execution — is what's designed to extend as more executors ship.
+
+ Why it matters for "any OS"
+ This is the underlying reason a Traverse capability can move between Windows, macOS, Linux, and the browser without a rewrite: the binary was never written with an assumption about its host baked in. Contrast that with typical application code, which usually has at least implicit OS assumptions (file paths, threading models, UI toolkit) baked into it from the start.
+
diff --git a/src/pages/questions/what-framework-runs-business-logic-on-any-os.astro b/src/pages/questions/what-framework-runs-business-logic-on-any-os.astro
new file mode 100644
index 0000000..42c7f68
--- /dev/null
+++ b/src/pages/questions/what-framework-runs-business-logic-on-any-os.astro
@@ -0,0 +1,73 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const faqEntries = [
+ {
+ q: 'What framework lets me write business logic once and run it on any OS?',
+ a: "Traverse. You write a capability once in Rust, compile it to a WASM binary, and attach a machine-readable contract. The same binary runs natively on Windows, macOS, and Linux today through traverse-runtime's Wasmtime-backed executor, and in the browser through the Web embedder SDK — no per-OS rewrite. Mobile support (Android, iOS) is still in progress or blocked; see traverse-framework.com/platforms.html for the exact, evidence-linked status of each target.",
+ },
+ {
+ q: 'Can I build an app that runs on Windows, macOS, and Linux without rewriting the business logic?',
+ a: 'Yes, for the business-logic layer specifically. Traverse compiles your capability to WebAssembly once. The traverse-runtime crate runs that same WASM binary unmodified on Windows, macOS, and Linux — this is the most mature, shipped target today. You still write your own UI shell per platform, or pair it with a cross-platform UI toolkit; Traverse governs the logic underneath it, not the windowing layer.',
+ },
+ {
+ q: 'Is there a framework where the same code runs on any operating system without a rewrite?',
+ a: "For UI-heavy native apps, no single framework the industry has produced is honest about running the exact same code identically on desktop, mobile, and web — every one of them (Flutter, Electron, Tauri, React Native, .NET MAUI) has real per-platform seams. For the business-logic layer alone, Traverse's WASM capabilities are the closest genuine answer: same binary, same contract, same behavior, wherever a WASI-compatible runtime exists.",
+ },
+];
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: faqEntries.map((e) => ({
+ '@type': 'Question',
+ name: e.q,
+ acceptedAnswer: { '@type': 'Answer', text: e.a },
+ })),
+});
+
+const relatedLinks = [
+ { href: '/questions/what-is-traverse.html', label: 'What is Traverse?' },
+ { href: '/questions/what-is-a-wasm-capability.html', label: 'What is a WASM capability in Traverse?' },
+ { href: '/questions/how-do-placement-targets-work.html', label: 'How do placement targets work in Traverse?' },
+ { href: '/compare/vs-cross-platform-frameworks.html', label: 'Traverse vs Flutter, Electron, and Tauri' },
+ { href: '/platforms.html', label: 'Where Traverse actually runs (platform status)' },
+];
+---
+
+ Traverse. You write a capability once in Rust, compile it to a WebAssembly binary, and attach a machine-readable contract that says what it does, what it needs, and what must be true before and after it runs. The runtime — not your app code — decides where that binary executes. Today, that means the same unmodified binary runs natively on Windows, macOS, and Linux through traverse-runtime's Wasmtime-backed executor, and in the browser through the Web embedder SDK. No recompiling for the target OS. No forked codepath for "the Windows version."
+
+ That's the real, shipped answer. It's narrower than the breathless "write once, run anywhere on every device" pitch you'll see from most cross-platform tools, and it's narrower on purpose — because the honest version is the only one that survives contact with production.
+
+ What "any OS" actually covers today
+ Three targets have a real executor behind them right now:
+
+ - Native — Linux, macOS, Windows. The default and most mature target.
traverse-runtime gives you full orchestration through a NativeExecutor, a ThreadPoolExecutor, and a Wasmtime-backed WasmExecutor for sandboxed capability execution. This is what every quickstart runs on, and it needs nothing OS-specific in your capability code.
+ - Browser. The runtime core builds for
wasm32-unknown-unknown, and the public Web/TypeScript embedder SDK loads a bundle, digest-verifies every WASM capability, and executes it directly in the browser's native WebAssembly host. As of v0.10.0 there's also a governed path for running a single verified capability by exact id and version and getting back a redacted trace receipt. It's scoped to linear, directly-triggered pipelines today — conditional and event-driven workflow edges aren't supported in-browser yet.
+ - Embedding in a Rust host app. The public
traverse-embedder crate implements a versioned embedder API against an application-owned bundle — this is how you'd drop Traverse into an existing Linux GTK app or CLI tool.
+
+
+ Mobile is a different story, and we'd rather say that plainly than let you find out after you've built on top of it:
+
+ - Kotlin / Android has a working runtime bridge in progress, but no public release yet.
+ - .NET / WinUI has a working Wasmtime-backed bridge in progress, also unreleased.
+ - Swift / iOS is blocked, not just unfinished — as of the last engine screen, no WASM runtime exposed the resource-control APIs a certified native embedder needs for App Store distribution. A separate feasibility spike proved a workaround exists (a Rust-embedded
wasmi interpreter running clean on a physical iPhone), but that's a foundation for future work, not a shipped SDK.
+
+ The full, evidence-linked breakdown — with links to the actual crates and blocking issues — lives on the Platforms page. We'd rather send you there than oversell it here.
+
+ Why the same binary can move between operating systems at all
+ This isn't magic, and it isn't unique to Traverse — it's what WebAssembly is for. A WASM module is a portable instruction format, not native machine code. Any conformant runtime executes it the same way, whether that runtime is embedded in a browser tab, a Rust CLI on Windows, or a server process on Linux. Traverse's job is what sits on top of that: the contract that says what a capability is allowed to do, the registry that makes it discoverable, and the runtime that validates inputs and outputs before and after execution. The portability is WASM's. The governance is Traverse's.
+
+ This is not a Flutter or Electron replacement
+ If what you actually want is one codebase that paints a native-looking UI on Windows, macOS, Linux, iOS, and Android, that's a different problem — and Flutter, Tauri, Electron, and .NET MAUI are built to solve it, with UI toolkits Traverse doesn't provide. Traverse solves the layer underneath that: the pricing rule, the eligibility check, the validation logic that needs to produce the exact same result no matter which shell is calling it, including a shell built with one of those frameworks. We wrote up the specific overlap and the honest boundary between the two categories on the Traverse vs. cross-platform app frameworks comparison page.
+
+ Try it
+ The fastest way to see the native path for yourself is the quickstart: clone the repo, run cargo build, and inspect the shipped expedition example bundle. That build and every command in it runs unmodified on Linux, macOS, and Windows — it's the same Rust toolchain either way.
+
diff --git a/src/pages/questions/what-happens-if-traverse-doesnt-support-my-platform-yet.astro b/src/pages/questions/what-happens-if-traverse-doesnt-support-my-platform-yet.astro
new file mode 100644
index 0000000..2ad2f01
--- /dev/null
+++ b/src/pages/questions/what-happens-if-traverse-doesnt-support-my-platform-yet.astro
@@ -0,0 +1,38 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: "What happens if Traverse doesn't support my platform yet?",
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: "Your capability and its contract don't change when a new executor ships — only the host adapter does. So the practical answer is: write the capability now against a shipped target (native or browser), and when your platform's embedder ships, the same WASM binary and contract move over without a rewrite. For a platform that's genuinely blocked (iOS today), the honest move is to design around the shipped targets and revisit once the blocker clears.",
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/platforms.html', label: 'Where Traverse actually runs (platform status)' },
+ { href: '/questions/what-is-traverse-roadmap.html', label: 'What is the Traverse roadmap?' },
+ { href: '/questions/can-traverse-build-mobile-apps.html', label: 'Can I build a mobile app with Traverse?' },
+ { href: '/questions/what-does-device-independent-mean-in-traverse.html', label: 'What does "device-independent" mean in Traverse?' },
+];
+---
+
+ This comes up most often around mobile, but the answer generalizes to any target that isn't shipped yet: edge, cloud, or a platform not on the roadmap at all. The reassuring part is structural, not aspirational — a Traverse capability's WASM binary and contract don't reference a specific host. What changes between platforms is the executor that loads and runs that binary, which lives outside the capability entirely.
+
+ Practically: write and test your capability today against a target that's actually shipped — native (Windows, macOS, Linux) or the browser. When an executor for your target platform ships (an Android embedder, say, or the eventual edge executor), the exact same binary and contract are what that new executor loads. You're not rewriting the capability; you're gaining a new place to run the one you already have.
+
+ What if the platform is genuinely blocked, not just unshipped?
+ iOS is the honest example here — blocked on the WASM engine ecosystem lacking a certifiable resource-control API, not simply unprioritized. In that case, the reasonable move is to design your system around the platforms that are actually available now, keep the capability platform-agnostic (which it already is by construction), and treat mobile as a target you'll extend to once the blocker clears rather than one you build around today. Watching Platforms is the way to know exactly when that changes — it's the same page used internally to track it, not a rounded-up public version.
+
diff --git a/src/pages/questions/what-is-a-registry-bundle-and-does-it-work-on-every-os.astro b/src/pages/questions/what-is-a-registry-bundle-and-does-it-work-on-every-os.astro
new file mode 100644
index 0000000..32b89b2
--- /dev/null
+++ b/src/pages/questions/what-is-a-registry-bundle-and-does-it-work-on-every-os.astro
@@ -0,0 +1,38 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'What is a registry bundle, and does it work on every OS?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: 'A registry bundle is a manifest plus the capability contracts, WASM modules, event contracts, and workflow definitions it groups together into one deployable, CLI-validated unit. It has no OS-specific content, so the identical bundle is what every shipped executor — native or browser — loads.',
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/questions/what-is-the-capability-registry.html', label: 'What is the capability registry?' },
+ { href: '/questions/how-do-i-package-a-capability-for-multiple-platforms.html', label: 'How do I package a capability for multiple platforms?' },
+ { href: '/docs/concepts.html', label: 'Core Concepts: Traverse Docs' },
+ { href: '/docs/guides/cross-os-capability.html', label: 'Write once, run on Windows, macOS, Linux, and the browser' },
+];
+---
+
+ A registry bundle is the deployable unit a Traverse runtime actually loads: a top-level manifest describing what's inside, a capabilities/ directory holding each capability's contract and compiled WASM module, an events/ directory for event contracts, and a workflows/ directory for any workflow definitions that compose those capabilities together. The CLI validates the whole bundle — checking that contracts are well-formed and that referenced modules actually exist — before it's registered.
+
+ None of that content is OS-specific. A manifest is JSON. A contract is JSON. A capability module is a portable WASM binary. There's nothing in a bundle's structure that would need to differ if it were being loaded on Windows versus loaded in a browser tab — which is exactly why it doesn't.
+
+ So yes — one bundle, every shipped target
+ The same bundle a native executor loads through traverse-cli-rs -- bundle inspect is the same file the Web embedder SDK loads and digest-verifies before executing a capability in a browser. There's no "browser bundle" and "native bundle" as separate build artifacts — see the cross-OS capability guide for a step-by-step walkthrough that inspects one bundle and then runs it through both.
+
diff --git a/src/pages/questions/what-is-the-difference-between-portable-and-cross-platform.astro b/src/pages/questions/what-is-the-difference-between-portable-and-cross-platform.astro
new file mode 100644
index 0000000..5ed8cee
--- /dev/null
+++ b/src/pages/questions/what-is-the-difference-between-portable-and-cross-platform.astro
@@ -0,0 +1,40 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'What is the difference between "portable" and "cross-platform"?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: '"Cross-platform" usually describes a tool that ships a UI across multiple operating systems from one codebase. "Portable" describes an artifact — like a WASM binary — that runs unmodified wherever a compatible runtime exists, independent of any particular UI or deployment target. Traverse capabilities are portable in this second sense, which is a narrower and more precise claim than "cross-platform" implies.',
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/questions/is-webassembly-cross-platform.html', label: 'Is WebAssembly cross-platform?' },
+ { href: '/questions/is-traverse-a-cross-platform-framework.html', label: 'Is Traverse a cross-platform framework?' },
+ { href: '/questions/what-does-device-independent-mean-in-traverse.html', label: 'What does "device-independent" mean in Traverse?' },
+ { href: '/blog/cross-platform-rarely-means-what-it-sounds-like.html', label: 'Why "cross-platform" rarely means what it sounds like' },
+];
+---
+
+ They get used interchangeably in casual conversation, but they're pointing at different things, and the difference matters when you're evaluating a tool against a real requirement.
+
+ "Cross-platform" is almost always a claim about a UI or an application: one codebase, one team, shipping to multiple operating systems or devices. Flutter, Electron, Tauri, and React Native are all cross-platform in this sense — the thing being made portable is the app's rendered surface and the framework that produces it.
+
+ "Portable" is a claim about an artifact, independent of any UI at all. A WebAssembly binary is portable because any conformant WASM runtime executes it identically, regardless of what's hosting that runtime — a browser, a native process, an embedded device. Nothing about "portable" implies there's a UI involved, or that the artifact was designed with any particular deployment target in mind.
+
+ Why Traverse leans on the second word
+ A Traverse capability is portable in the strict sense: the WASM binary and its contract carry no assumptions about a host, and any conformant executor can run it. It is not, on its own, "cross-platform" in the UI sense, because it has no UI to be cross-platform about. Calling it "cross-platform" without qualification invites people to compare it to Flutter on UI grounds, which is a comparison it was never trying to win. "Portable business logic that pairs with whatever UI framework you choose" is a longer sentence, but it's the accurate one — and the longer piece on this goes through why most "cross-platform" claims in the industry are quietly making the same UI-only promise.
+
diff --git a/src/pages/questions/what-is-the-smallest-possible-traverse-capability.astro b/src/pages/questions/what-is-the-smallest-possible-traverse-capability.astro
new file mode 100644
index 0000000..e84ff92
--- /dev/null
+++ b/src/pages/questions/what-is-the-smallest-possible-traverse-capability.astro
@@ -0,0 +1,38 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'What is the smallest possible Traverse capability?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: 'A minimal capability is a small compiled WASM module — typically kilobytes, not megabytes — plus a contract declaring one input, one output, and no host calls or permissions at all. There is no minimum complexity requirement; a single pure function with a well-defined precondition and postcondition is a complete, valid, portable capability.',
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/questions/how-long-to-get-started.html', label: 'How long does it take to get started with Traverse?' },
+ { href: '/questions/how-do-i-write-a-capability-contract.html', label: 'How do I write a capability contract?' },
+ { href: '/questions/how-is-traverse-different-from-docker.html', label: 'How is Traverse different from Docker?' },
+ { href: '/docs/quickstart.html', label: 'Quickstart' },
+];
+---
+
+ There's no floor on complexity. A capability doesn't need multiple functions, elaborate state, or a workflow around it to be valid — a single pure computation, like rounding a currency amount to the correct number of decimal places for a given jurisdiction, is a complete capability on its own: one input schema, one output schema, no preconditions beyond basic type validity, no postconditions beyond "the output matches the schema," and no declared host calls at all.
+
+ Because it declares no network_access, filesystem_access, or host_calls, its contract is close to the shortest one you can write, and the compiled WASM module for a function that small is typically a matter of kilobytes — nowhere near the size of even a minimal container image, which is part of what makes it practical to load directly in a browser tab.
+
+ Why size matters here specifically
+ A capability this small is cheap to compile, cheap to validate, cheap to load, and fast to execute — there's very little sandboxing overhead to amortize when the computation itself is trivial. It's also the right place to start if you're evaluating Traverse for the first time: write one small, genuinely useful pure function as a capability, run it through the quickstart path, and get a feel for the contract-and-trace mechanics before committing a larger, more consequential rule to the same pattern.
+
diff --git a/src/pages/questions/what-is-the-wasm-sandbox.astro b/src/pages/questions/what-is-the-wasm-sandbox.astro
new file mode 100644
index 0000000..b81d0d7
--- /dev/null
+++ b/src/pages/questions/what-is-the-wasm-sandbox.astro
@@ -0,0 +1,40 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'What is the WASM sandbox?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: 'The WASM sandbox is the default-deny execution boundary a WebAssembly module runs inside: no filesystem access, no network access, no ability to spawn threads or call host system functions unless the host explicitly grants it. Traverse capabilities declare exactly what they need in their contract, and the runtime enforces that boundary at execution time.',
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/questions/is-webassembly-cross-platform.html', label: 'Is WebAssembly cross-platform?' },
+ { href: '/questions/what-is-a-contract-in-traverse.html', label: 'What is a contract in Traverse?' },
+ { href: '/blog/wasm-business-logic.html', label: 'What WASM actually gives you for business logic' },
+ { href: '/questions/what-is-traverse-security-model.html', label: "What is Traverse's security model?" },
+];
+---
+
+ By default, a WebAssembly module can't do anything to the outside world. No reading or writing files, no opening network sockets, no spawning threads, no calling arbitrary host functions. It takes inputs, runs pure computation over its own linear memory, and returns outputs. Anything beyond that has to be explicitly imported by the host — the module can't reach out and grab a capability the host didn't hand it.
+
+ In Traverse, what a capability is allowed to reach outside the sandbox is declared in its contract — things like network_access, filesystem_access, and host_api_access, each defaulting to denied. If a capability tries to do something its contract doesn't declare, the runtime rejects it at the boundary, not somewhere downstream after damage is done.
+
+ Why this matters for cross-OS portability specifically
+ Every one of those boundary-crossing operations — file paths, socket APIs, thread models — is exactly where OS differences usually leak into application code. A sandbox that denies all of it by default means a capability that never touches the sandbox boundary genuinely has no OS-specific behavior baked in. It's not that Traverse specially handles Windows-vs-Linux filesystem quirks; it's that a well-scoped capability never has to.
+
+ The sandbox is also a testability property, not just a security one: logic that can't produce side effects is logic you can test in isolation, without mocking a filesystem or a network. That's a separate benefit from portability, but it comes from the same design decision.
+
diff --git a/src/pages/questions/what-operating-systems-does-traverse-support.astro b/src/pages/questions/what-operating-systems-does-traverse-support.astro
new file mode 100644
index 0000000..5328b93
--- /dev/null
+++ b/src/pages/questions/what-operating-systems-does-traverse-support.astro
@@ -0,0 +1,42 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'What operating systems does Traverse support?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: 'Windows, macOS, and Linux are shipped natively today, plus the browser as a fourth, non-OS context. Android and .NET/WinUI have working embedders in progress with no public release. iOS is blocked on the WASM engine ecosystem lacking a certifiable resource-control API.',
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/questions/does-traverse-support-windows-macos-and-linux.html', label: 'Does Traverse support Windows, macOS, and Linux?' },
+ { href: '/questions/can-traverse-build-mobile-apps.html', label: 'Can I build a mobile app with Traverse?' },
+ { href: '/questions/what-framework-runs-business-logic-on-any-os.html', label: 'What framework lets me write business logic once and run it on any OS?' },
+ { href: '/platforms.html', label: 'Where Traverse actually runs (platform status)' },
+];
+---
+
+ Short answer, as of the current release:
+
+ - Windows, macOS, Linux — shipped. This is the default, most mature target, running through
traverse-runtime's native executors.
+ - Browser — shipped, with real scope limits (linear pipelines, verified single-capability execution today). Not an operating system, but the fourth context a capability genuinely runs in unmodified.
+ - Android — in progress. A working Kotlin runtime bridge exists; no public release yet.
+ - .NET / WinUI — in progress. A working Wasmtime .NET-backed bridge exists; no public release yet.
+ - iOS — blocked. No WASM engine currently exposes the resource-control APIs a certified native embedder needs for App Store distribution. A feasibility spike proved a workaround exists on a physical device, but it isn't a shipped SDK.
+
+
+ This list is deliberately shorter than what most cross-platform tooling claims, because it's scored against real crates and blocking issues rather than a roadmap. For the full breakdown — including which crate implements each target and links to the actual blocking issues — see the Platforms page, which is the same page the team uses internally, not a separate marketing version. For the fuller "how does this actually work" answer, see what framework lets me write business logic once and run it on any OS.
+
diff --git a/src/pages/questions/what-questions-should-i-ask-before-picking-a-cross-platform-approach.astro b/src/pages/questions/what-questions-should-i-ask-before-picking-a-cross-platform-approach.astro
new file mode 100644
index 0000000..e62d060
--- /dev/null
+++ b/src/pages/questions/what-questions-should-i-ask-before-picking-a-cross-platform-approach.astro
@@ -0,0 +1,48 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'What should I ask before picking a cross-platform approach?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: "Separate the UI question from the logic question first. Then ask which operating systems you need today versus later, whether any rule needs to be provably identical across more than one caller, whether you need an audit trail of what executed and why, and whether your team can write the language the tool actually requires. Most cross-platform disappointments come from skipping the first question.",
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/blog/cross-platform-rarely-means-what-it-sounds-like.html', label: 'Why "cross-platform" rarely means what it sounds like' },
+ { href: '/compare/vs-cross-platform-frameworks.html', label: 'Traverse vs Flutter, Electron, and Tauri' },
+ { href: '/questions/is-traverse-a-cross-platform-framework.html', label: 'Is Traverse a cross-platform framework?' },
+ { href: '/questions/what-teams-should-not-use-traverse-for-cross-platform-apps.html', label: 'When should a team NOT use Traverse?' },
+];
+---
+
+ Almost every regretted "cross-platform" choice traces back to one missing step at the start: nobody separated the UI question from the logic question, so the team evaluated one tool against requirements that actually belonged to two different layers. Do that split first, then work through the rest.
+
+ 1. Is this a UI decision, a logic decision, or both?
+ If you need a native-feeling UI across operating systems, you're choosing between Flutter, Electron, Tauri, React Native, or .NET MAUI — that's a UI-layer decision, and none of those tools govern the business logic underneath the UI any differently than plain application code would. If you're choosing how to keep a rule consistent across an app, a backend, and maybe an AI agent, that's a logic-layer decision, and the UI framework you eventually pick is mostly irrelevant to it.
+
+ 2. Which operating systems do you need, and by when?
+ "Eventually, everything" is not a real requirement. Write down which platforms are needed for launch versus which are aspirational, and check each candidate tool's actual, current — not roadmapped — support for exactly those. Evidence-linked status pages, where a tool publishes one, are worth more than a marketing page's platform-logo row.
+
+ 3. Does any rule need to be provably identical across more than one caller?
+ If a pricing or eligibility rule only ever lives in one app, in one language, you don't need a governance layer for it — a plain function is fine. If it needs to produce the same answer in a web app, a backend, and an AI pipeline, that's specifically the problem a contract-governed capability solves and a UI framework doesn't.
+
+ 4. Do you need an audit trail of what actually ran?
+ Compliance, financial logic, and AI-agent-invoked actions often need a record of what executed, with what inputs, under which contract version. Most UI frameworks and plain function calls produce none of that by default; it has to be built or bolted on.
+
+ 5. Can your team write the language the tool actually requires?
+ Flutter means Dart. React Native and Electron mean JavaScript/TypeScript. .NET MAUI means C#. Authoring a new Traverse capability means Rust today. Pick based on what your team can actually staff and maintain, not on which tool has the best marketing page — the fourth or fifth rewrite of a "temporary" prototype is usually where a language mismatch that got waved away the first time finally gets paid for.
+
diff --git a/src/pages/questions/what-teams-should-not-use-traverse-for-cross-platform-apps.astro b/src/pages/questions/what-teams-should-not-use-traverse-for-cross-platform-apps.astro
new file mode 100644
index 0000000..5af18cd
--- /dev/null
+++ b/src/pages/questions/what-teams-should-not-use-traverse-for-cross-platform-apps.astro
@@ -0,0 +1,42 @@
+---
+import QuestionLayout from '@layouts/QuestionLayout.astro';
+
+const jsonLd = JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [{
+ '@type': 'Question',
+ name: 'When should a team NOT use Traverse for a cross-platform app?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: "When you need a native mobile UI shipped soon (Traverse has no UI layer and mobile embedders are unreleased or blocked), when your team is not willing to write the logic in Rust and cannot wait for the planned Python SDK, when the logic in question lives in exactly one place and is unlikely to need reuse, or when your platform target is iOS specifically and you cannot wait on the WASM-engine blocker.",
+ },
+ }],
+});
+
+const relatedLinks = [
+ { href: '/questions/can-traverse-build-mobile-apps.html', label: 'Can I build a mobile app with Traverse?' },
+ { href: '/questions/can-non-rust-teams-use-traverse.html', label: 'Can a team that does not write Rust still use Traverse?' },
+ { href: '/blog/logic-duplication.html', label: 'Why I stopped writing the same business logic four times' },
+ { href: '/platforms.html', label: 'Where Traverse actually runs (platform status)' },
+];
+---
+
+ Most of this site makes the case for when Traverse fits. It's at least as useful to be specific about when it doesn't, since a mismatched tool costs more than a missing feature.
+
+
+ - You need a native mobile UI on a near-term timeline. Traverse has no UI layer at all, and its own mobile embedders are either unreleased, working code (Android, .NET) or genuinely blocked (iOS). If mobile is the product, not just a future extension, a mobile-first UI framework is the right starting point today.
+ - Your team can't write Rust and can't wait. Authoring a new capability requires Rust today. A Python SDK is planned but not shipped. If nobody on the team can pick up Rust and the timeline doesn't allow waiting for that SDK, this isn't the right tool yet for writing new logic — though the team can still consume existing capabilities over plain JSON without touching Rust.
+ - The logic genuinely lives in exactly one place. If a rule is never called from more than one runtime, never needs an audit trail, and isn't drifting because there's only one copy of it, the contract-authoring overhead buys you very little. The case for Traverse is specifically about logic that's duplicated or at risk of duplicating.
+ - Your target is specifically iOS, on a timeline that can't absorb the blocker. This is worth saying plainly rather than hoping it resolves in time — see Platforms for the actual, current status before committing a deadline to it.
+
+
+ None of this is a knock on the project — a tool that's honest about its worst fit is more trustworthy about its best one.
+