Skip to main content

Why Land

Why WebAssembly

Grove uses Wasmtime to run extensions inside a capability-bounded WASM sandbox - the same binary runs on macOS, Linux, and Windows with no Node.js dependency and with OS access granted explicitly rather than by default.

Extensions are the most sensitive third-party code a code editor runs. They can touch files, spawn processes, open network connections, and observe workspace state. Cocoon runs Node.js extensions with full OS access - the correct tradeoff for VS Code compatibility. Grove takes the opposite position: extensions compiled to WASM run inside a Wasmtime sandbox where every OS capability must be granted explicitly. Nothing is accessible by default.

NOTE: Grove is optional (--features grove) and does not affect Cocoon. WASM extensions targeting the WASI ABI can use the sandbox today.

The sandbox boundary

WASM modules execute in linear memory allocated by the host runtime. A module cannot read the host heap, call arbitrary syscalls, or reach another module’s memory. Wasmtime enforces this at the instruction level - hardware-enforced memory isolation, not a policy check a clever extension can bypass.

In Node.js, require('fs') grants full filesystem access. In Grove, a WASM extension must receive a WASI preopened_dir handle from the host. If Grove does not grant it, the extension cannot open files - there is no require('fs') to fall back to.

Capability-based access control

ResourceCocoon (Node.js)Grove (WASM/WASI)
FilesystemFull fs module accessOnly explicitly preopened dirs
Environment varsprocess.env.* - all visibleOnly vars explicitly passed
NetworkFull net/http accessOnly sockets explicitly granted
Subprocess spawnchild_process.spawn - unrestrictedNot available without host function
Stdout/stderrDirectRedirected through WASI fd handles

The security model is additive: start with nothing, grant what is needed. Cocoon is subtractive: start with full Node.js access, restrict what is possible. Grove’s model is more correct for untrusted extensions.

Near-native performance

Wasmtime compiles WASM to native machine code ahead of time. No interpreter, no JIT warmup on the critical path. The gap between WASM-compiled Rust and native Rust is typically under 10% for compute-bound work - the same LLVM backend produces both. For I/O-bound work (most editor extensions), the gap is negligible - waiting for Mountain’s gRPC response dominates.

Cross-platform ABI

A .wasm binary compiled on macOS runs identically on Linux and Windows inside Wasmtime. No per-platform native addon compilation, no node-gyp rebuild, no platform-specific binary. VS Code native addon extensions must ship per-platform binaries per Node.js version. WASM extensions ship one file.

Grove is not a replacement for Cocoon

HostExtensionsNode.js?Isolation
CocoonExisting VS Code (Node.js)YesProcess isolation only
GroveNew WASM-native extensionsNoWasmtime sandbox per module

VS Code extensions run in Cocoon. New Land-specific extensions targeting the Grove API run in Grove. The two hosts are complementary and run concurrently. Grove is not a migration path - WASM extensions must be compiled from source to target the WASI ABI.

Current status

Grove is implemented: Wasmtime runtime, gRPC client to Mountain, WASI host functions, and proto definitions are in place. Compiled as an optional feature flag. Budget controls (memory ceilings, CPU metering via Wasmtime fuel) are implemented. Cocoon remains the default extension host for all VS Code extensions.