Running Native Bash Scripts from a Web Interface Using WebAssembly and WASI
What if your browser could run actual Bash scripts — not simulated, but real native Bash logic — without any server? Thanks to WebAssembly and WASI, it’s now possible to compile Bash to run securely in the browser. This article shows how to expose real shell scripting via a frontend interface, opening up some wild new workflows for DevOps dashboards, embedded terminals, and education tools. Why Bash in the Browser? Great for tutorials and sandboxes (e.g. "try-it-yourself" Unix) Build CI dashboards with real shell logic, offline Use shell scripts in PWAs or remote UIs without network calls Step 1: Use a Precompiled WASI Bash Binary You can grab a precompiled Bash WebAssembly binary with WASI support from projects like runwasi or Wasmer. For simplicity, assume we have bash.wasm already. Step 2: Load WASM with JavaScript Use the WebAssembly JS API to load and instantiate it: const response = await fetch("bash.wasm"); const wasmBinary = await response.arrayBuffer(); const wasi = new WASI({ args: ["bash", "-c", "echo Hello from Bash"], env: {}, bindings: { ...WASI.defaultBindings } }); const { instance } = await WebAssembly.instantiate(wasmBinary, { wasi_snapshot_preview1: wasi.wasiImport }); wasi.start(instance); Step 3: Build an Input Shell UI Let’s bind the shell command input from the user directly to the WASI environment: Run async function runBash() { const cmd = document.getElementById("cmd").value; const response = await fetch("bash.wasm"); const binary = await response.arrayBuffer(); const stdout = []; const wasi = new WASI({ args: ["bash", "-c", cmd], env: {}, bindings: { ...WASI.defaultBindings, fs: require("fs"), stdout: { write: (str) => stdout.push(str) } } }); const { instance } = await WebAssembly.instantiate(binary, { wasi_snapshot_preview1: wasi.wasiImport }); wasi.start(instance); document.getElementById("output").textContent = stdout.join(""); } Step 4: Notes on File System and Safety Because WASI gives you access to a virtualized file system, you can read/write to an in-memory FS that doesn’t touch the real machine. It’s sandboxed by default — meaning no access to system files, so it's safe to run in untrusted environments. Pros and Cons ✅ Pros Real Bash without needing a server Portable, sandboxed, and fast Powerful educational and DevOps tooling potential ⚠️ Cons Still limited in browser compatibility (especially FS bindings) Lack of real-time I/O like interactive shell prompts WASM and WASI are evolving rapidly — API shifts expected
What if your browser could run actual Bash scripts — not simulated, but real native Bash logic — without any server? Thanks to WebAssembly and WASI, it’s now possible to compile Bash to run securely in the browser. This article shows how to expose real shell scripting via a frontend interface, opening up some wild new workflows for DevOps dashboards, embedded terminals, and education tools.
Why Bash in the Browser?
- Great for tutorials and sandboxes (e.g. "try-it-yourself" Unix)
- Build CI dashboards with real shell logic, offline
- Use shell scripts in PWAs or remote UIs without network calls
Step 1: Use a Precompiled WASI Bash Binary
You can grab a precompiled Bash WebAssembly binary with WASI support from projects like runwasi or Wasmer.
For simplicity, assume we have bash.wasm
already.
Step 2: Load WASM with JavaScript
Use the WebAssembly JS API to load and instantiate it:
const response = await fetch("bash.wasm");
const wasmBinary = await response.arrayBuffer();
const wasi = new WASI({
args: ["bash", "-c", "echo Hello from Bash"],
env: {},
bindings: {
...WASI.defaultBindings
}
});
const { instance } = await WebAssembly.instantiate(wasmBinary, {
wasi_snapshot_preview1: wasi.wasiImport
});
wasi.start(instance);
Step 3: Build an Input Shell UI
Let’s bind the shell command input from the user directly to the WASI environment:
Step 4: Notes on File System and Safety
Because WASI gives you access to a virtualized file system, you can read/write to an in-memory FS that doesn’t touch the real machine. It’s sandboxed by default — meaning no access to system files, so it's safe to run in untrusted environments.
Pros and Cons
✅ Pros
- Real Bash without needing a server
- Portable, sandboxed, and fast
- Powerful educational and DevOps tooling potential
⚠️ Cons
- Still limited in browser compatibility (especially FS bindings)
- Lack of real-time I/O like interactive shell prompts
- WASM and WASI are evolving rapidly — API shifts expected