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.
# 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.wasm6# Filter lines matching a pattern$ printf '/error/ { print $0 }\ninfo: ok\nerror: disk full\n' \ | wasmtime target/wasm32-wasip1/release/wawk-wasi.wasmerror: 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
Background
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 extensions
Add custom functions (hashing, encoding, validation) via WebAssembly extensions written in Rust, C, Go, or any language that compiles to Wasm.
Extensions
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 extensions (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
Tutorial
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 1Pattern & Action
Loading Wasm...
script.awk
input.txt
stdout
Press Run to execute
1 / 6
Extension Development
Build Your First Extension
Wawk extensions add custom functions to AWK by implementing the AwkExternalFunction trait from wawk-core. When the evaluator encounters a function call it doesn't recognise as built-in or user-defined, it delegates to your handler. This guide walks you through creating a HelloHandler that exposes a greet(name) function to AWK.
The AwkExternalFunction trait provides two methods. call_external_str (String ABI) receives arguments as &[String] and returns Option<String>. call_external (Numeric ABI) is a legacy fallback with f64 arguments. Return Some(result) when you handle a function, None to let the evaluator report "unknown function".
// src/lib.rsuse wawk_core::traits::AwkExternalFunction;
use wawk_core::error::AwkResult;
pub structHelloHandler;
implAwkExternalFunctionforHelloHandler {
fncall_external_str(
&mut self,
name: &str,
args: &[String],
) -> AwkResult<Option<String>> {
match name {
"greet" => {
let who = args.first()
.map(|s| s.as_str())
.unwrap_or("World");
Ok(Some(format!("Hello, {}!", who)))
}
_ => Ok(None), // unknown function
}
}
}
Step 3: Register with the Evaluator
Create an Evaluator, attach your handler via set_external_function_handler, then run the program. The handler is consulted for every unrecognised function call during execution.
// src/main.rsuse wawk_core::parser::parse;
use wawk_core::eval::Evaluator;
use wawk_core::traits::{MemReader, MemWriter, StubEnvironment, StubCommandExecutor};
let script = r#"
BEGIN {
print greet("World")
print greet("AWK")
}
"#;
let program = parse(script).unwrap();
let mut reader = MemReader::new("");
let mut writer = MemWriter::new();
let env = StubEnvironment::default();
let mut cmd = StubCommandExecutor;
let mut eval = Evaluator::new(&mut reader, &mut writer, &env, &mut cmd);
// Attach the extension handler
eval.set_external_function_handler(Box::new(HelloHandler));
eval.execute(&program).unwrap();
// writer.output now contains:// Hello, World!// Hello, AWK!
Step 4: Use in AWK scripts
Once registered, your extension's functions are available in AWK scripts just like built-in functions. The evaluator tries the String ABI first; if your handler returns None, it falls back to the Numeric ABI before reporting an unknown function error.
# AWK script using the greet() extensionBEGIN {
printgreet("World")
printgreet("AWK")
}
# Output:Hello, World!Hello, AWK!
Trait API Reference
Method
Signature
Purpose
call_external_str
(&str, &[String]) → Option<String>
String ABI (preferred) — handles function calls with string arguments
call_external
(&str, &[f64]) → Option<f64>
Numeric ABI (legacy fallback) — for simple numeric extensions
Key points
Return Ok(Some(result)) when you handle a function, Ok(None) when the function name is unknown to your handler.
The String ABI is tried first. Override call_external only if you need legacy numeric dispatch.
Both methods have default implementations that return None, so you only need to override the one you use.
Multiple extensions can be composed by implementing a dispatcher that routes to the correct handler based on function name.
Contact
Feedback
Questions, bug reports, or suggestions? Send us an email at team@ailur.ai.