
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">
    <channel>
        <title><![CDATA[ The Cloudflare Blog ]]></title>
        <description><![CDATA[ Get the latest news on how products at Cloudflare are built, technologies used, and join the teams helping to build a better Internet. ]]></description>
        <link>https://blog.cloudflare.com</link>
        <atom:link href="https://blog.cloudflare.com/" rel="self" type="application/rss+xml"/>
        <language>en-us</language>
        <image>
            <url>https://blog.cloudflare.com/favicon.png</url>
            <title>The Cloudflare Blog</title>
            <link>https://blog.cloudflare.com</link>
        </image>
        <lastBuildDate>Fri, 03 Apr 2026 11:18:45 GMT</lastBuildDate>
        <item>
            <title><![CDATA[Running Zig with WASI on Cloudflare Workers]]></title>
            <link>https://blog.cloudflare.com/running-zig-with-wasi-on-cloudflare-workers/</link>
            <pubDate>Mon, 01 Aug 2022 14:12:26 GMT</pubDate>
            <description><![CDATA[ After the recent announcement regarding WASI support in Workers I decided to see what it would take to get code written in Zig to run as a Worker, and it turned out to be pretty trivial. This post documents the process I followed ]]></description>
            <content:encoded><![CDATA[ 
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6IYT1Gc6y5cogG4X4H9skK/583baf4700006967596b41b2dbff7908/image1-4.png" />
            
            </figure><p>After the recent announcement regarding <a href="/announcing-wasi-on-workers/">WASI support in Workers</a>, I decided to see what it would take to get code written in <a href="https://ziglang.org/">Zig</a> to run as a Worker, and it turned out to be trivial. This post documents the process I followed as a new user of Zig. It’s so exciting to see how Cloudflare Workers is a polyglot platform allowing you to write programs in the language you love, or the language you’re learning!</p>
    <div>
      <h3>Hello, World!</h3>
      <a href="#hello-world">
        
      </a>
    </div>
    <p>I’m not a Zig expert by any means, and to keep things entirely honest I’ve only just started looking into the language, but we all have to start somewhere. So, if my Zig code isn’t perfect please bear with me. My goal was to build a real, small program using Zig and deploy it on Cloudflare Workers. And to see how fast I can go from a blank screen to production code.</p><p>My goal for this wasn’t ambitious, just read some text from stdin and print it to stdout with line numbers, like running <code>cat -n</code>. But it does show just how easy the Workers paradigm is. This Zig program works identically on the command-line on my laptop and as an HTTP API deployed on Cloudflare Workers.</p><p>Here’s my code. It reads a line from stdin and outputs the same line prefixed with a line number. It terminates when there’s no more input.</p>
            <pre><code>const std = @import("std");

pub fn main() anyerror!void {
	// setup allocator
	var gpa = std.heap.GeneralPurposeAllocator(.{}){};
	defer std.debug.assert(!gpa.deinit());
	const allocator = gpa.allocator();

	// setup streams
	const stdout = std.io.getStdOut().writer();
	const in = std.io.getStdIn();
	var reader = std.io.bufferedReader(in.reader()).reader();

	var counter: u32 = 1;

	// read input line by line
	while (try reader.readUntilDelimiterOrEofAlloc(allocator, '\n', std.math.maxInt(usize))) |line| {
    	    defer allocator.free(line);
    	    try stdout.print("{d}\t{s}\n", .{counter, line});
    	    counter = counter + 1;
	}
}</code></pre>
            <p>To build Zig code, you create a <code>build.zig</code> file that defines how to build your project. For this trivial case I just opted to build an executable from the sources</p>
            <pre><code>const std = @import("std");

pub fn build(b: *std.build.Builder) void {
	const target = b.standardTargetOptions(.{});
	const mode = b.standardReleaseOptions();

	const exe = b.addExecutable("print-with-line-numbers", "src/main.zig");
	exe.setTarget(target);
	exe.setBuildMode(mode);
	exe.install();
}</code></pre>
            <p>By running <code>zig build</code> the compiler will run and output a binary under <code>zig-out/bin</code></p>
            <pre><code>$ zig build

$ ls zig-out/bin
print-with-line-numbers

$ echo "Hello\nWorld" | ./zig-out/bin/print-with-line-numbers
1    Hello
2    World</code></pre>
            
    <div>
      <h3>WASI</h3>
      <a href="#wasi">
        
      </a>
    </div>
    <p>The next step is to get this running on Workers, but first I need to compile it into WASM with WASI support.</p><p>Thankfully, this comes out of the box with recent versions of Zig, so you can just tell the compiler to build your executable using the <code>wasm32-wasi</code> target, which will produce a file that can be run on any WASI-compatible WebAssembly runtime, such as <a href="https://wasmtime.dev/">wasmtime</a>.</p><p>This same .wasm file can be run in wasmtime and deployed directly to Cloudflare Workers. This makes building, testing and deploying seamless.</p>
            <pre><code>$ zig build -Dtarget=wasm32-wasi

$ ls zig-out/bin
print-with-line-numbers.wasm

$ echo "Hello\nWorld" | wasmtime ./zig-out/bin/print-with-line-numbers.wasm
1    Hello
2    World</code></pre>
            
    <div>
      <h3>Zig on Workers</h3>
      <a href="#zig-on-workers">
        
      </a>
    </div>
    <p>With our binary ready to go, the last piece is to get it running on Cloudflare Workers using <a href="/wrangler-v2-beta/">wrangler2</a>. That is as simple as publishing the .wasm file on workers.dev. If you don’t have a <a href="https://workers.dev">workers.dev</a> account, you can follow the tutorial on our <a href="https://developers.cloudflare.com/workers/get-started/guide/">getting started guide</a> that will get you from code to deployment within minutes!</p><p>In fact, once I signed up for my account, all I needed to do was complete the first two steps, install wrangler and login.</p>
            <pre><code>$ npx wrangler@wasm login
Attempting to login via OAuth...
Opening a link in your default browser: https://dash.cloudflare.com/oauth2/auth
Successfully logged in.</code></pre>
            <p>Then, I ran the following command to publish my worker:</p>
            <pre><code>$ npx wrangler@wasm publish --name print-with-line-numbers --compatibility-date=2022-07-07 zig-out/bin/print-with-line-numbers.wasm
Uploaded print-with-line-numbers (3.04 sec)
Published print-with-line-numbers (6.28 sec)
  print-with-line-numbers.workers.dev</code></pre>
            <p>With that step completed, the worker is ready to run and can be invoked by calling the URL printed from the output above.</p>
            <pre><code>echo "Hello\nWorld" | curl https://print-with-line-numbers.workers.dev -X POST --data-binary @-
1    Hello
2    World</code></pre>
            <p>Success!</p>
    <div>
      <h3>Conclusion</h3>
      <a href="#conclusion">
        
      </a>
    </div>
    <p>What impressed me the most here was just how easy this process was.</p><p>First, I had a binary compiled for the architecture of my laptop, then I compiled the code into WebAssembly by just passing a flag to the compiler, and finally I had this running on workers <b>without having to change any code.</b></p><p>Granted, this program was not very complicated and does not do anything other than read from STDIN and write to STDOUT, but it gives me confidence of what is possible, especially as technology like WASI matures.</p> ]]></content:encoded>
            <category><![CDATA[Cloudflare Workers]]></category>
            <category><![CDATA[WebAssembly]]></category>
            <category><![CDATA[WASM]]></category>
            <category><![CDATA[Developers]]></category>
            <category><![CDATA[Developer Platform]]></category>
            <guid isPermaLink="false">5Xy5uTuM3ghJ0CV01dfsLi</guid>
            <dc:creator>Daniel Harper</dc:creator>
        </item>
    </channel>
</rss>