WAWK

wawk is a POSIX-compliant AWK engine written in Rust and compiled to WebAssembly. It produces no native binaries — every component compiles to .wasm modules that run in standard hosts: browsers, Node.js, Wasmtime, and other Wasm-compatible runtimes.

wawk consists of wawk-core as the shared engine, wawk-wasi as a command-line tool, and wawk-bindgen as a JavaScript-importable library. All three share the same engine code and produce identical output for the same input.

Runtime
Browser, Node.js, Wasmtime
Language
100% Rust → Wasm
OS Dependencies
None
License
MIT / Apache 2.0

Getting Started

Prerequisites

# Install Wasmtime (for wawk-wasi) $ curl https://wasmtime.dev/install.sh -sSf | bash # Install wasm-pack (for wawk-bindgen) $ cargo install wasm-pack

Build all Wasm targets

$ make build-wasm

Run wawk-wasi

# Build $ cargo build -p wawk-wasi --target wasm32-wasip1 --release # Sum a column $ printf '{ sum += $1 } END { print sum }\n1\n2\n3\n' \ | wasmtime target/wasm32-wasip1/release/wawk-wasi.wasm 6 # Filter lines matching a pattern $ printf '/error/ { print $0 }\ninfo: ok\nerror: disk full\n' \ | wasmtime target/wasm32-wasip1/release/wawk-wasi.wasm error: disk full

Use wawk-bindgen in Node.js

# Build for Node.js $ wasm-pack build crates/wawk-bindgen \ --target nodejs \ --out-dir ../../pkg-node \ --release # Run the end-to-end test $ node crates/wawk-bindgen/tests/node_e2e.js

Use wawk-bindgen in the browser

# Build for the browser $ wasm-pack build crates/wawk-bindgen \ --target web \ --out-dir ../../pkg-web \ --release # Open pkg-web/test.html in a browser

AWK History

AWK is a text-processing language created at Bell Labs. It reads input line by line, matches patterns, and executes actions. It is part of the POSIX standard and has been shipped with every Unix system since the late 1970s.

1977
AWK is created
Alfred Aho, Peter Weinberger, and Brian Kernighan develop AWK at Bell Labs. The name comes from their initials.
1988
The AWK Programming Language published
The authors publish a book covering the language in depth, including associative arrays and regular expressions.
1990s
POSIX standardization
AWK is included in the POSIX standard. Multiple implementations exist: gawk, mawk, nawk, and the original awk.
2026
AWK reinvented in Rust and Wasm
AWK reimplemented in Rust, compiled to Wasm. Runs in browsers and edge runtimes with no OS dependencies.

What AWK is used for

AWK is a general-purpose text processing tool. Common uses include:

Log analysis
Filter, count, and aggregate entries from server logs and structured text streams.
CSV / TSV processing
Extract columns, reshape rows, convert between delimited formats.
Text transformation
Regex-driven rewriting, format conversion, structured extraction from unstructured text.
Reporting
One-pass counting, summing, grouping, and summary generation.

How WAWK Extends AWK

WAWK carries AWK's proven text-processing model into new environments that were not available when AWK was created:

Browser-based data processing
Run AWK directly in the browser — no server required. Build interactive log analyzers and data explorers as client-side web apps.
Edge computing & serverless
Deploy AWK to edge runtimes and serverless platforms. Process data at the edge with zero cold starts and sandboxed execution.
AI agent tool integration
Use AWK as a programmable data-transform layer in AI agent workflows. Pipe data between tools and models with a familiar syntax.
Extensible with Wasm plugins
Add custom functions (hashing, encoding, validation) via WebAssembly plugins written in Rust, C, Go, or any language that compiles to Wasm.

AWK → WAWK

AWK has done its job remarkably well for nearly five decades. WAWK builds on that foundation, adding capabilities that the WebAssembly platform makes possible — without changing the AWK language itself.

Scenario AWK (system-installed) WAWK (Wasm)
Run in browser Outside the browser's scope Native Wasm execution
Deploy to edge Designed for server-based pipelines Edge runtimes, serverless
Custom functions C extensions (gawk) Wasm plugins (Rust, C, Go)
Sandboxing OS-level isolation Wasm runtime sandbox
Distribution Pre-installed on Unix systems Single .wasm file
Cross-platform consistency Multiple implementations (gawk, mawk, nawk) Identical output everywhere

Interactive AWK Tutorial

Edit the script and input below, then press Run. The AWK engine executes in your browser as real WebAssembly via wawk-bindgen.

Chapter 1 Pattern & Action
Loading Wasm...
script.awk
input.txt
stdout
Press Run to execute
1 / 6

Build Your First Plugin

WAWK plugins extend AWK with custom functions. Write your plugin in Rust, C, Go, or any language that compiles to WebAssembly. This guide walks you through creating a wawk-hello plugin that exposes a greet(name) function to AWK.

Step 1: Create the plugin project

# Create a new Rust library $ cargo new --lib plugins/wawk-hello $ cd plugins/wawk-hello # Add dependencies to Cargo.toml [lib] crate-type = ["cdylib"] [dependencies] # No dependencies needed for this simple example

Step 2: Implement the plugin

Every WAWK plugin exports a standard interface. The key functions are plugin_alloc (memory allocation), process_data (function dispatcher), and last_result_len (result retrieval).

// plugins/wawk-hello/src/lib.rs use std::cell::RefCell; // Thread-local result buffer thread_local! { static RESULT_BUF: RefCell<Vec<u8>> = RefCell::new(Vec::new()); } /// Allocate memory in the plugin's linear memory. #[no_mangle] pub extern "C" fn plugin_alloc(size: i32) -> i32 { let buf: Vec<u8> = Vec::with_capacity(size as usize); let ptr = buf.as_ptr() as i32; std::mem::forget(buf); ptr } /// String ABI dispatcher. /// Receives NUL-separated "func_name\0arg" and returns a result pointer. #[no_mangle] pub extern "C" fn process_data(ptr: i32, len: i32) -> i32 { let input = unsafe { std::slice::from_raw_parts(ptr as *const u8, len as usize) }; let parts: Vec<&str> = std::str::from_utf8(input) .unwrap().split('\0').collect(); let result = match parts[0] { "greet" => String::from("Hello, ") + parts[1] + "!", _ => String::from("unknown function"), }; // Store result in thread-local buffer and return pointer RESULT_BUF.with(|cell| { let mut buf = cell.borrow_mut(); buf.clear(); buf.extend_from_slice(result.as_bytes()); }); RESULT_BUF.with(|cell| cell.borrow().as_ptr() as i32) } /// Return the length of the most recent result. #[no_mangle] pub extern "C" fn last_result_len() -> i32 { RESULT_BUF.with(|cell| cell.borrow().len() as i32) }

Step 3: Build the plugin

# Compile to WebAssembly $ cargo build --target wasm32-unknown-unknown --release # Output is at: target/wasm32-unknown-unknown/release/wawk_hello.wasm

Step 4: Use your plugin in AWK

Once loaded, your plugin's functions are available in AWK scripts just like built-in functions. The greet(name) function can now be called from any AWK program.

# Example AWK script using wawk-hello plugin BEGIN { print greet("World") print greet("AWK") } # Output: Hello, World! Hello, AWK!

Plugin ABI Reference

Export Purpose
plugin_alloc(size) → ptr Allocate a buffer in the plugin's linear memory
last_result_len() → i32 Return the length of the most recent result buffer
process_data(ptr, len) → ptr String ABI dispatcher (NUL-separated name\0arg)

Feedback

Questions, bug reports, or suggestions? Send us an email at team@ailur.ai.

You can also find us on GitHub or visit our website.