/workers-zig

Write Cloudflare Workers in Zig via WebAssembly

Primary LanguageZigMIT LicenseMIT

Workers-Zig

workers-zig

Workers Zig is a light weight Zig bindings for the Cloudflare Workers environment via WebAssembly.

Why Zig?

  • Zig is a language that is designed to be a small, fast, and portable.
  • The language already supports WASM and WASI.
  • Small builds are easy to achieve. To expound on this, the basic example provided is 5.8Kb of WASM code and 6.8Kb javascript code.
  • I wanted a tool that made it easy for both WASM and JS code to work in tandem.
  • I didn't like that rust wasm bindings would grow the more code you wrote. I came up with a strategy that covers 90% use cases, JS glue doesn't grow, and you can add the 10% as needed.
  • I prefer Zig's memory model over Rust.

Be sure to read the Documentation for guidance on usage.

Features

  • 🔗 Zero dependencies
  • 🗿 WASI support
  • 🤝 Use in tandem with Javascript or 100% Zig WebAssembly
  • 🎮 JS bindings with support to write your own - List of supported bindings here
  • 📨 Fetch bindings
  • ⏰ Scheduled bindings
  • 🔑 Supports Variables and Secrets from env
  • ✨ Cache bindings
  • 📦 KV bindings
  • 🪣 R2 bindings
  • 💾 D1 bindings
  • 🔐 Web-Crypto bindings [partially complete]
  • 💪 Uses TypeScript

Features coming soon

  • 📌 Durable Objects bindings
  • ✉️ WebSockets bindings
  • once CF lands dynamic imports: Only load wasm when needed.

Install

Step 1: Install Zig

Follow the instructions to install Zig

Release used: 0.10.0-dev.3838+77f31ebbb

Step 2a: Use the skeleton project provided

Follow the steps provided by the skeleton project

# in one go
git clone --recurse-submodules -j8 git@github.com:CraigglesO/worker-zig-template.git

# OR

# clone
git clone git@github.com:CraigglesO/worker-zig-template.git
# enter
cd worker-zig-template
# Pull in the submodule
git submodule update --init --recursive

Step 2b: Install the workers-zig package

# NPM
npm install --save workers-zig
# Yarn
yarn add workers-zig
# PNPM
pnpm add workers-zig
# BUN
bun add workers-zig

Step 3: Add workers-zig as a submodule to your project

git submodule add https://github.com/CraigglesO/workers-zig

Step 4: Setup a build.zig script

const std = @import("std");
const Builder = std.build.Builder;

pub fn build(b: *Builder) void {
    b.is_release = true;
    b.cache_root = "cache";
    b.global_cache_root = "cache";
    b.use_stage1 = true;

    const wasm_build = b.addSharedLibrary("zig", "lib/main.zig", .unversioned);
    wasm_build.setOutputDir("dist");
    wasm_build.setTarget(std.zig.CrossTarget {
        .cpu_arch = .wasm32,
        .os_tag = .freestanding,
    });
    wasm_build.build_mode = std.builtin.Mode.ReleaseSmall;
    wasm_build.strip = true;
    wasm_build.linkage = std.build.LibExeObjStep.Linkage.dynamic;
    wasm_build.addPackagePath("workers-zig", "workers-zig/lib/main.zig");
    wasm_build.install();
}

Step 5: Recommended wrangler configuration

name = "zig-worker-template"
main = "dist/worker.mjs"
compatibility_date = "2022-07-29"
usage_model = "bundled" # or unbound
account_id = ""

[build]
command = "zig build && npm run esbuild"
watch_dir = [
  "src",
  "lib"
]

[[build.upload.rules]]
type = "CompiledWasm"
globs = ["**/*.wasm"]
[[build.upload.rules]]
type = "ESModule"
globs = ["**/*.mjs"]