<?xml version="1.0" encoding="utf-8"?>
<feed xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom"><title>Simon Willison's Weblog: zig</title><link href="http://simonwillison.net/" rel="alternate"/><link href="http://simonwillison.net/tags/zig.atom" rel="self"/><id>http://simonwillison.net/</id><updated>2026-05-14T22:31:20+00:00</updated><author><name>Simon Willison</name></author><entry><title>Quoting Mitchell Hashimoto</title><link href="https://simonwillison.net/2026/May/14/mitchell-hashimoto/#atom-tag" rel="alternate"/><published>2026-05-14T22:31:20+00:00</published><updated>2026-05-14T22:31:20+00:00</updated><id>https://simonwillison.net/2026/May/14/mitchell-hashimoto/#atom-tag</id><summary type="html">
    &lt;blockquote cite="https://twitter.com/mitchellh/status/2055039647924007222"&gt;&lt;p&gt;[...] On the interesting side is how fungible programming languages are nowadays. Programming languages used to be LOCK IN, and they're increasingly not so. You think the Bun rewrite in Rust is good for Rust? Bun has shown they can be in probably any language they want in roughly a week or two. Rust is expendable. Its useful until its not then it can be thrown out. That's interesting!&lt;/p&gt;&lt;/blockquote&gt;
&lt;p class="cite"&gt;&amp;mdash; &lt;a href="https://twitter.com/mitchellh/status/2055039647924007222"&gt;Mitchell Hashimoto&lt;/a&gt;, on Bun porting from Zig to Rust&lt;/p&gt;

    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/ai"&gt;ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/rust"&gt;rust&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/zig"&gt;zig&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/generative-ai"&gt;generative-ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llms"&gt;llms&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/mitchell-hashimoto"&gt;mitchell-hashimoto&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/bun"&gt;bun&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/agentic-engineering"&gt;agentic-engineering&lt;/a&gt;&lt;/p&gt;



</summary><category term="ai"/><category term="rust"/><category term="zig"/><category term="generative-ai"/><category term="llms"/><category term="mitchell-hashimoto"/><category term="bun"/><category term="agentic-engineering"/></entry><entry><title>Quoting Andrew Kelley</title><link href="https://simonwillison.net/2026/Apr/30/andrew-kelley/#atom-tag" rel="alternate"/><published>2026-04-30T21:24:55+00:00</published><updated>2026-04-30T21:24:55+00:00</updated><id>https://simonwillison.net/2026/Apr/30/andrew-kelley/#atom-tag</id><summary type="html">
    &lt;blockquote cite="https://lobste.rs/s/ifcyr1/contributor_poker_zig_s_ai_ban#c_cbtxub"&gt;&lt;p&gt;It's a common misconception that we can't tell who is using LLM and who is not. I'm sure we didn't catch 100% of LLM-assisted PRs over the past few months, but the kind of mistakes humans make are fundamentally different than LLM hallucinations, making them easy to spot. Furthermore, people who come from the world of agentic coding have a certain &lt;em&gt;digital smell&lt;/em&gt; that is not obvious to them but is obvious to those who abstain. It's like when a smoker walks into the room, everybody who doesn't smoke instantly knows it.&lt;/p&gt;
&lt;p&gt;I'm not telling you not to smoke, but I am telling you not to smoke in my house.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p class="cite"&gt;&amp;mdash; &lt;a href="https://lobste.rs/s/ifcyr1/contributor_poker_zig_s_ai_ban#c_cbtxub"&gt;Andrew Kelley&lt;/a&gt;, Creator of Zig&lt;/p&gt;

    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/ai"&gt;ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/zig"&gt;zig&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/generative-ai"&gt;generative-ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llms"&gt;llms&lt;/a&gt;&lt;/p&gt;



</summary><category term="ai"/><category term="zig"/><category term="generative-ai"/><category term="llms"/></entry><entry><title>The Zig project's rationale for their firm anti-AI contribution policy</title><link href="https://simonwillison.net/2026/Apr/30/zig-anti-ai/#atom-tag" rel="alternate"/><published>2026-04-30T01:24:23+00:00</published><updated>2026-04-30T01:24:23+00:00</updated><id>https://simonwillison.net/2026/Apr/30/zig-anti-ai/#atom-tag</id><summary type="html">
    &lt;p&gt;&lt;a href="https://ziglang.org/"&gt;Zig&lt;/a&gt; has one of the most stringent &lt;a href="https://ziglang.org/code-of-conduct/"&gt;anti-LLM policies&lt;/a&gt; of any major open source project:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;No LLMs for issues.&lt;/p&gt;
&lt;p&gt;No LLMs for pull requests.&lt;/p&gt;
&lt;p&gt;No LLMs for comments on the bug tracker, including translation. English is encouraged, but not required. You are welcome to post in your native language and rely on others to have their own translation tools of choice to interpret your words.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The most prominent project written in Zig may be the &lt;a href="https://bun.com/"&gt;Bun&lt;/a&gt; JavaScript runtime, which was &lt;a href="https://bun.com/blog/bun-joins-anthropic"&gt;acquired by Anthropic&lt;/a&gt; in December 2025 and, unsurprisingly, makes heavy use of AI assistance.&lt;/p&gt;
&lt;p&gt;Bun operates its own fork of Zig, and recently &lt;a href="https://x.com/bunjavascript/status/2048427636414923250"&gt;achieved a 4x performance improvement&lt;/a&gt; on Bun compile after adding "parallel semantic analysis and multiple codegen units to the llvm backend". Here's &lt;a href="https://github.com/oven-sh/zig/compare/upgrade-0.15.2%E2%80%A6upgrade-0.15.2-fast"&gt;that code&lt;/a&gt;. But &lt;a href="https://twitter.com/bunjavascript/status/2048428104893542781"&gt;@bunjavascript says&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We do not currently plan to upstream this, as Zig has a strict ban on LLM-authored contributions.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;(Update: here's &lt;a href="https://ziggit.dev/t/bun-s-zig-fork-got-4x-faster-compilation-times/15183/19"&gt;a Zig core contributor&lt;/a&gt; providing details on why they wouldn't accept that particular patch independent of the LLM issue - parallel semantic analysis is a long planned feature but has implications "for the Zig language itself".)&lt;/p&gt;
&lt;p&gt;In &lt;a href="https://kristoff.it/blog/contributor-poker-and-ai/"&gt;Contributor Poker and Zig's AI Ban&lt;/a&gt; (&lt;a href="https://lobste.rs/s/ifcyr1/contributor_poker_zig_s_ai_ban"&gt;via Lobste.rs&lt;/a&gt;) Zig Software Foundation VP of Community Loris Cro explains the rationale for this strict ban. It's the best articulation I've seen yet for a blanket ban on LLM-assisted contributions:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In successful open source projects you eventually reach a point where you start getting more PRs than what you’re capable of processing. Given what I mentioned so far, it would make sense to stop accepting imperfect PRs in order to maximize ROI from your work, but that’s not what we do in the Zig project. Instead, &lt;strong&gt;we try our best to help new contributors to get their work in, even if they need some help getting there&lt;/strong&gt;. We don’t do this just because it’s the “right” thing to do, but also &lt;strong&gt;because it’s the smart thing to do&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Zig values contributors over their contributions. Each contributor represents an investment by the Zig core team - the primary goal of reviewing and accepting PRs isn't to land new code, it's to help grow new contributors who can become trusted and prolific over time.&lt;/p&gt;
&lt;p&gt;LLM assistance breaks that completely. It doesn't matter if the LLM helps you submit a &lt;em&gt;perfect&lt;/em&gt; PR to Zig - the time the Zig team spends reviewing your work does nothing to help them add new, confident, trustworthy contributors to their overall project.&lt;/p&gt;
&lt;p&gt;Loris explains the name here:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The reason I call it “contributor poker” is because, just like people say about the actual card game, “you play the person, not the cards”. In contributor poker, you bet on the contributor, not on the contents of their first PR.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This makes a lot of sense to me. It relates to an idea I've seen circulating elsewhere: if a PR was mostly written by an LLM, why should a project maintainer spend time reviewing and discussing that PR as opposed to firing up their own LLM to solve the same problem?&lt;/p&gt;

    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/javascript"&gt;javascript&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/open-source"&gt;open-source&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai"&gt;ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/zig"&gt;zig&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/generative-ai"&gt;generative-ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llms"&gt;llms&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai-assisted-programming"&gt;ai-assisted-programming&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/anthropic"&gt;anthropic&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai-ethics"&gt;ai-ethics&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/bun"&gt;bun&lt;/a&gt;&lt;/p&gt;



</summary><category term="javascript"/><category term="open-source"/><category term="ai"/><category term="zig"/><category term="generative-ai"/><category term="llms"/><category term="ai-assisted-programming"/><category term="anthropic"/><category term="ai-ethics"/><category term="bun"/></entry><entry><title>Zig 0.16.0 release notes: "Juicy Main"</title><link href="https://simonwillison.net/2026/Apr/15/juicy-main/#atom-tag" rel="alternate"/><published>2026-04-15T01:59:21+00:00</published><updated>2026-04-15T01:59:21+00:00</updated><id>https://simonwillison.net/2026/Apr/15/juicy-main/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://ziglang.org/download/0.16.0/release-notes.html#Juicy-Main"&gt;Zig 0.16.0 release notes: &amp;quot;Juicy Main&amp;quot;&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Zig has &lt;em&gt;really good&lt;/em&gt; release notes - comprehensive, detailed, and with relevant usage examples for each of the new features.&lt;/p&gt;
&lt;p&gt;Of particular note in the newly released Zig 0.16.0 is what they are calling "Juicy Main" - a dependency injection feature for your program's &lt;code&gt;main()&lt;/code&gt; function where accepting a &lt;code&gt;process.Init&lt;/code&gt; parameter grants access to a struct of useful properties:&lt;/p&gt;
&lt;div class="highlight highlight-source-zig"&gt;&lt;pre&gt;&lt;span class="pl-k"&gt;const&lt;/span&gt; &lt;span class="pl-v"&gt;std&lt;/span&gt; &lt;span class="pl-k"&gt;=&lt;/span&gt; &lt;span class="pl-k"&gt;@import&lt;/span&gt;(&lt;span class="pl-s"&gt;"std"&lt;/span&gt;);

&lt;span class="pl-k"&gt;pub&lt;/span&gt; &lt;span class="pl-k"&gt;fn&lt;/span&gt; &lt;span class="pl-en"&gt;main&lt;/span&gt;(&lt;span class="pl-v"&gt;init&lt;/span&gt;: &lt;span class="pl-k"&gt;std.process.Init&lt;/span&gt;) &lt;span class="pl-k"&gt;!&lt;/span&gt;&lt;span class="pl-k"&gt;void&lt;/span&gt; {
    &lt;span class="pl-c"&gt;/// general purpose allocator for temporary heap allocations:&lt;/span&gt;
    &lt;span class="pl-k"&gt;const&lt;/span&gt; &lt;span class="pl-v"&gt;gpa&lt;/span&gt; &lt;span class="pl-k"&gt;=&lt;/span&gt; &lt;span class="pl-v"&gt;init&lt;/span&gt;.&lt;span class="pl-v"&gt;gpa&lt;/span&gt;;
    &lt;span class="pl-c"&gt;/// default Io implementation:&lt;/span&gt;
    &lt;span class="pl-k"&gt;const&lt;/span&gt; &lt;span class="pl-v"&gt;io&lt;/span&gt; &lt;span class="pl-k"&gt;=&lt;/span&gt; &lt;span class="pl-v"&gt;init&lt;/span&gt;.&lt;span class="pl-v"&gt;io&lt;/span&gt;;
    &lt;span class="pl-c"&gt;/// access to environment variables:&lt;/span&gt;
    &lt;span class="pl-v"&gt;std&lt;/span&gt;.&lt;span class="pl-v"&gt;log&lt;/span&gt;.&lt;span class="pl-v"&gt;info&lt;/span&gt;(&lt;span class="pl-s"&gt;"{d} env vars"&lt;/span&gt;, .{&lt;span class="pl-v"&gt;init&lt;/span&gt;.&lt;span class="pl-v"&gt;environ_map&lt;/span&gt;.&lt;span class="pl-v"&gt;count&lt;/span&gt;()});
    &lt;span class="pl-c"&gt;/// access to CLI arguments&lt;/span&gt;
    &lt;span class="pl-k"&gt;const&lt;/span&gt; &lt;span class="pl-v"&gt;args&lt;/span&gt; &lt;span class="pl-k"&gt;=&lt;/span&gt; &lt;span class="pl-k"&gt;try&lt;/span&gt; &lt;span class="pl-v"&gt;init&lt;/span&gt;.&lt;span class="pl-v"&gt;minimal&lt;/span&gt;.&lt;span class="pl-v"&gt;args&lt;/span&gt;.&lt;span class="pl-v"&gt;toSlice&lt;/span&gt;(
        &lt;span class="pl-v"&gt;init&lt;/span&gt;.&lt;span class="pl-v"&gt;arena&lt;/span&gt;.&lt;span class="pl-v"&gt;allocator&lt;/span&gt;()
    );
}&lt;/pre&gt;&lt;/div&gt;

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://lobste.rs/s/4vvozb/zig_0_16_0_release_notes"&gt;Lobste.rs&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/zig"&gt;zig&lt;/a&gt;&lt;/p&gt;



</summary><category term="zig"/></entry><entry><title>Thoughts on Go vs. Rust vs. Zig</title><link href="https://simonwillison.net/2025/Dec/5/go-vs-rust-vs-zig/#atom-tag" rel="alternate"/><published>2025-12-05T04:28:05+00:00</published><updated>2025-12-05T04:28:05+00:00</updated><id>https://simonwillison.net/2025/Dec/5/go-vs-rust-vs-zig/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://sinclairtarget.com/blog/2025/08/thoughts-on-go-vs.-rust-vs.-zig/"&gt;Thoughts on Go vs. Rust vs. Zig&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Thoughtful commentary on Go, Rust, and Zig by Sinclair Target. I haven't seen a single comparison that covers all three before and I learned a lot from reading this.&lt;/p&gt;
&lt;p&gt;One thing that I hadn't noticed before is that none of these three languages implement class-based OOP.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://news.ycombinator.com/item?id=46153466"&gt;Hacker News&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/go"&gt;go&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/object-oriented-programming"&gt;object-oriented-programming&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/programming-languages"&gt;programming-languages&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/rust"&gt;rust&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/zig"&gt;zig&lt;/a&gt;&lt;/p&gt;



</summary><category term="go"/><category term="object-oriented-programming"/><category term="programming-languages"/><category term="rust"/><category term="zig"/></entry><entry><title>Geoffrey Huntley is cursed</title><link href="https://simonwillison.net/2025/Sep/9/cursed/#atom-tag" rel="alternate"/><published>2025-09-09T09:31:21+00:00</published><updated>2025-09-09T09:31:21+00:00</updated><id>https://simonwillison.net/2025/Sep/9/cursed/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://ghuntley.com/cursed/"&gt;I ran Claude in a loop for three months, and it created a genz programming language called cursed&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Geoffrey Huntley vibe-coded an entirely new programming language using Claude:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The programming language is called "cursed". It's cursed in its lexical structure, it's cursed in how it was built, it's cursed that this is possible, it's cursed in how cheap this was, and it's cursed through how many times I've sworn at Claude.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Geoffrey's initial prompt:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;Hey, can you make me a programming language like Golang but all the lexical keywords are swapped so they're Gen Z slang?&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Then he pushed it to keep on iterating over a three month period.&lt;/p&gt;
&lt;p&gt;Here's Hello World:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;vibe main
yeet "vibez"

slay main() {
    vibez.spill("Hello, World!")
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And here's &lt;a href="https://github.com/ghuntley/cursed/blob/ecda33d496e1562e0e02efb25b6936ad94e79b72/test_suite/leetcode_comprehensive_suite/binary_search/704_binary_search_backup.%F0%9F%92%80"&gt;binary search&lt;/a&gt;, part of &lt;a href="https://github.com/ghuntley/cursed/tree/zig/test_suite/leetcode_comprehensive_suite"&gt;17+ LeetCode problems&lt;/a&gt; that run as part of the test suite:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;slay binary_search(nums normie[], target normie) normie {
    sus left normie = 0
    sus right normie = len(nums) - 1    
    bestie (left &amp;lt;= right) {
        sus mid normie = left + (right - left) / 2
        ready (nums[mid] == target) {
            damn mid
        }
        ready (nums[mid] &amp;lt; target) {
            left = mid + 1
        } otherwise {
            right = mid - 1
        }
    }
    damn -1
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a &lt;em&gt;substantial&lt;/em&gt; project. The repository currently has &lt;a href="https://github.com/ghuntley/cursed/commits/zig/"&gt;1,198 commits&lt;/a&gt;. It has both an interpreter mode and a compiler mode, and can compile programs to native binaries (via LLVM) for macOS, Linux and Windows.&lt;/p&gt;
&lt;p&gt;It looks like it was mostly built using Claude running via &lt;a href="https://ampcode.com/"&gt;Sourcegraph's Amp&lt;/a&gt;, which produces &lt;a href="https://github.com/ghuntley/cursed/commit/ec5be8a4c4f6e82f6b93774a9b3b3f88308680dd"&gt;detailed commit messages&lt;/a&gt;. The commits include links to archived Amp sessions but sadly those don't appear to be publicly visible.&lt;/p&gt;
&lt;p&gt;The first version was written in C, then Geoffrey had Claude port it to Rust and then Zig. &lt;a href="https://twitter.com/GeoffreyHuntley/status/1965295152962097550"&gt;His cost estimate&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Technically it costs about 5k usd to build your own compiler now because cursed was implemented first in c, then rust, now zig. So yeah, it’s not one compiler it’s three editions of it. For a total of $14k USD.&lt;/p&gt;
&lt;/blockquote&gt;

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://x.com/GeoffreyHuntley/status/1965258228314636524"&gt;@GeoffreyHuntley&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/c"&gt;c&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/programming-languages"&gt;programming-languages&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai"&gt;ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/rust"&gt;rust&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/zig"&gt;zig&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/generative-ai"&gt;generative-ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llms"&gt;llms&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai-assisted-programming"&gt;ai-assisted-programming&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/anthropic"&gt;anthropic&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/claude"&gt;claude&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/vibe-coding"&gt;vibe-coding&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/geoffrey-huntley"&gt;geoffrey-huntley&lt;/a&gt;&lt;/p&gt;



</summary><category term="c"/><category term="programming-languages"/><category term="ai"/><category term="rust"/><category term="zig"/><category term="generative-ai"/><category term="llms"/><category term="ai-assisted-programming"/><category term="anthropic"/><category term="claude"/><category term="vibe-coding"/><category term="geoffrey-huntley"/></entry><entry><title>My Approach to Building Large Technical Projects</title><link href="https://simonwillison.net/2024/Dec/28/my-approach-to-building-large-technical-projects/#atom-tag" rel="alternate"/><published>2024-12-28T14:54:46+00:00</published><updated>2024-12-28T14:54:46+00:00</updated><id>https://simonwillison.net/2024/Dec/28/my-approach-to-building-large-technical-projects/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://mitchellh.com/writing/building-large-technical-projects"&gt;My Approach to Building Large Technical Projects&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Mitchell Hashimoto wrote this piece about taking on large projects back in June 2023. The project he described in the post is a terminal emulator written in Zig called &lt;a href="https://ghostty.org/"&gt;Ghostty&lt;/a&gt; which just reached its &lt;a href="https://mitchellh.com/writing/ghostty-1-0-reflection"&gt;1.0 release&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I've learned that when I break down my large tasks in chunks that result in seeing tangible forward progress, I tend to finish my work and retain my excitement throughout the project. People are all motivated and driven in different ways, so this may not work for you, but as a broad generalization I've not found an engineer who doesn't get excited by a good demo. And the goal is to always give yourself a good demo.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For backend-heavy projects the lack of an initial UI is a challenge here, so Mitchell advocates for early automated tests as a way to start exercising code and seeing progress right from the start. Don't let tests get in the way of demos though:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;No matter what I'm working on, I try to build one or two demos per week intermixed with automated test feedback as explained in the previous section.&lt;/p&gt;
&lt;p&gt;Building a demo also provides you with invaluable product feedback. You can quickly intuit whether something &lt;em&gt;feels good&lt;/em&gt;, even if it isn't fully functional.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For more on the development of Ghostty see &lt;a href="https://mitchellh.com/writing/ghostty-and-useful-zig-patterns"&gt;this talk&lt;/a&gt; Mitchell gave at Zig Showtime last year:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I want the terminal to be a modern platform for text application development, analogous to the browser being a modern platform for GUI application development (for better or worse).&lt;/p&gt;
&lt;/blockquote&gt;

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://bsky.app/profile/vickiboykis.com/post/3l7xplgkifb2p"&gt;@vickiboykis.com&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/open-source"&gt;open-source&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/software-engineering"&gt;software-engineering&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/testing"&gt;testing&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/zig"&gt;zig&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/mitchell-hashimoto"&gt;mitchell-hashimoto&lt;/a&gt;&lt;/p&gt;



</summary><category term="open-source"/><category term="software-engineering"/><category term="testing"/><category term="zig"/><category term="mitchell-hashimoto"/></entry><entry><title>Things I've Learned Serving on the Board of The Perl Foundation</title><link href="https://simonwillison.net/2024/Sep/24/the-board-of-the-perl-foundation/#atom-tag" rel="alternate"/><published>2024-09-24T01:42:14+00:00</published><updated>2024-09-24T01:42:14+00:00</updated><id>https://simonwillison.net/2024/Sep/24/the-board-of-the-perl-foundation/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://blogs.perl.org/users/makoto_nozaki/2024/09/things-ive-learned-serving-on-the-board-of-the-perl-foundation.html"&gt;Things I&amp;#x27;ve Learned Serving on the Board of The Perl Foundation&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
My &lt;a href="https://simonwillison.net/2024/Sep/18/board-of-the-python-software-foundation/"&gt;post about the PSF board&lt;/a&gt; inspired Perl Foundation secretary Makoto Nozaki to publish similar notes about how TPF (also known since 2019 as TPRF, for The Perl and Raku Foundation) operates.&lt;/p&gt;
&lt;p&gt;Seeing this level of explanation about other open source foundations is fascinating. I’d love to see more of these.&lt;/p&gt;
&lt;p&gt;Along those lines, I found the &lt;a href="https://ziglang.org/news/2024-financials/"&gt;2024 Financial Report&lt;/a&gt; from the Zig foundation really interesting too.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://twitter.com/heismakoto/status/1838389539204641143"&gt;@ heismakoto&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/open-source"&gt;open-source&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/perl"&gt;perl&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/zig"&gt;zig&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/psf"&gt;psf&lt;/a&gt;&lt;/p&gt;



</summary><category term="open-source"/><category term="perl"/><category term="zig"/><category term="psf"/></entry><entry><title>Cyber</title><link href="https://simonwillison.net/2023/Jan/28/cyber/#atom-tag" rel="alternate"/><published>2023-01-28T04:25:17+00:00</published><updated>2023-01-28T04:25:17+00:00</updated><id>https://simonwillison.net/2023/Jan/28/cyber/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://cyberscript.dev/"&gt;Cyber&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
“Cyber is a new language for fast, efficient, and concurrent scripting.” Lots of interesting ideas in here, but the one that really caught my eye is that its designed to be easily embedded into other languages and “will allow the host to insert gas mileage checks in user scripts. This allows the host to control how long a script can run”—my dream feature for implementing a safe, sandboxed extension mechanism! Cyber is  implemented using Zig and LLVM.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://lobste.rs/s/v8edeu/cyber_is_new_language_for_fast_efficient"&gt;lobste.rs&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/llvm"&gt;llvm&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/programming-languages"&gt;programming-languages&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/sandboxing"&gt;sandboxing&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/zig"&gt;zig&lt;/a&gt;&lt;/p&gt;



</summary><category term="llvm"/><category term="programming-languages"/><category term="sandboxing"/><category term="zig"/></entry><entry><title>Bun</title><link href="https://simonwillison.net/2022/Jul/6/bun/#atom-tag" rel="alternate"/><published>2022-07-06T17:24:13+00:00</published><updated>2022-07-06T17:24:13+00:00</updated><id>https://simonwillison.net/2022/Jul/6/bun/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://bun.sh/"&gt;Bun&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
“Bun is a fast all-in-one JavaScript runtime”—this is very interesting. It’s the first project I’ve seen written using the Zig language, which I see as somewhat equivalent to Rust. Bun provides a full Node.js-style JavaScript environment plus a host of packaged tools—an npm install client, a TypeScript transpiler, bundling tools—all wrapped up in a single binary. The JavaScript engine itself extends JavaScriptCore. Bun also ships with its own wrapper for SQLite.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/javascript"&gt;javascript&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/sqlite"&gt;sqlite&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/npm"&gt;npm&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/typescript"&gt;typescript&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/zig"&gt;zig&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/bun"&gt;bun&lt;/a&gt;&lt;/p&gt;



</summary><category term="javascript"/><category term="sqlite"/><category term="npm"/><category term="typescript"/><category term="zig"/><category term="bun"/></entry><entry><title>Bundling binary tools in Python wheels</title><link href="https://simonwillison.net/2022/May/23/bundling-binary-tools-in-python-wheels/#atom-tag" rel="alternate"/><published>2022-05-23T15:06:04+00:00</published><updated>2022-05-23T15:06:04+00:00</updated><id>https://simonwillison.net/2022/May/23/bundling-binary-tools-in-python-wheels/#atom-tag</id><summary type="html">
    &lt;p&gt;I spotted a new (to me) pattern which I think is pretty interesting: projects are bundling compiled binary applications as part of their Python packaging wheels. I think it’s really neat.&lt;/p&gt;
&lt;h4&gt;pip install ziglang&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://ziglang.org/"&gt;Zig&lt;/a&gt; is a new programming language lead by Andrew Kelley that sits somewhere near Rust: Wikipedia &lt;a href="https://en.wikipedia.org/wiki/Zig_(programming_language)"&gt;calls it&lt;/a&gt; an "imperative, general-purpose, statically typed, compiled system programming language".&lt;/p&gt;
&lt;p&gt;One of its most notable features is that it bundles its own C/C++ compiler, as a “hermetic” compiler - it’s completely standalone, unaffected by the system that it is operating within. I learned about this usage of the word hermetic this morning from &lt;a href="https://jakstys.lt/2022/how-uber-uses-zig/"&gt;How Uber Uses Zig&lt;/a&gt; by Motiejus Jakštys.&lt;/p&gt;
&lt;p&gt;The concept reminds me of Gregory Szorc's &lt;a href="https://github.com/indygreg/python-build-standalone"&gt;python-build-standalone&lt;/a&gt;, which provides redistributable Python builds and was key to getting &lt;a href="https://simonwillison.net/2021/Sep/8/datasette-desktop/"&gt;my Datasette Desktop Electron application&lt;/a&gt; working with its own hermetic build of Python.&lt;/p&gt;
&lt;p&gt;One of the options provided for installing Zig (and its bundled toolchain) is &lt;a href="https://github.com/ziglang/zig-pypi/blob/main/README.pypi.md"&gt;to use pip&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell"&gt;&lt;pre&gt;% pip install ziglang
...
% python -m ziglang cc --help
OVERVIEW: clang LLVM compiler

USAGE: zig [options] file...

OPTIONS:
  -#&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt;#                    Print (but do not run) the commands to run for this compilation&lt;/span&gt;
  --amdgpu-arch-tool=&lt;span class="pl-k"&gt;&amp;lt;&lt;/span&gt;value&lt;span class="pl-k"&gt;&amp;gt;&lt;/span&gt;
                          Tool used &lt;span class="pl-k"&gt;for&lt;/span&gt; &lt;span class="pl-smi"&gt;detecting AMD GPU arch&lt;/span&gt; &lt;span class="pl-k"&gt;in&lt;/span&gt; the system.
...&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This means you can now &lt;code&gt;pip install&lt;/code&gt; a full C compiler for your current platform!&lt;/p&gt;
&lt;p&gt;The way this works is really simple. The &lt;code&gt;ziglang&lt;/code&gt; package that you install has two key files: A &lt;code&gt;zig&lt;/code&gt; binary (155MB on my system) containing the full Zig compiled implementation, and a &lt;code&gt;__main__.py&lt;/code&gt; module containing the following:&lt;/p&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-s1"&gt;os&lt;/span&gt;, &lt;span class="pl-s1"&gt;sys&lt;/span&gt;, &lt;span class="pl-s1"&gt;subprocess&lt;/span&gt;
&lt;span class="pl-s1"&gt;sys&lt;/span&gt;.&lt;span class="pl-en"&gt;exit&lt;/span&gt;(&lt;span class="pl-s1"&gt;subprocess&lt;/span&gt;.&lt;span class="pl-en"&gt;call&lt;/span&gt;([
    &lt;span class="pl-s1"&gt;os&lt;/span&gt;.&lt;span class="pl-s1"&gt;path&lt;/span&gt;.&lt;span class="pl-en"&gt;join&lt;/span&gt;(&lt;span class="pl-s1"&gt;os&lt;/span&gt;.&lt;span class="pl-s1"&gt;path&lt;/span&gt;.&lt;span class="pl-en"&gt;dirname&lt;/span&gt;(&lt;span class="pl-s1"&gt;__file__&lt;/span&gt;), &lt;span class="pl-s"&gt;"zig"&lt;/span&gt;),
    &lt;span class="pl-c1"&gt;*&lt;/span&gt;&lt;span class="pl-s1"&gt;sys&lt;/span&gt;.&lt;span class="pl-s1"&gt;argv&lt;/span&gt;[&lt;span class="pl-c1"&gt;1&lt;/span&gt;:]
]))&lt;/pre&gt;
&lt;p&gt;The package also bundles &lt;code&gt;lib&lt;/code&gt; and &lt;code&gt;doc&lt;/code&gt; folders with supporting files used by Zig itself, unrelated to Python.&lt;/p&gt;
&lt;p&gt;The Zig project then bundles and ships eight different Python wheels targetting different platforms. &lt;a href="https://github.com/ziglang/zig-pypi/blob/de14cf728fa35c014821f62a4fa9abd9f4bb560e/make_wheels.py#L115-L124"&gt;Here's their code&lt;/a&gt; that does that, which lists the platforms that are supported:&lt;/p&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;for&lt;/span&gt; &lt;span class="pl-s1"&gt;zig_platform&lt;/span&gt;, &lt;span class="pl-s1"&gt;python_platform&lt;/span&gt; &lt;span class="pl-c1"&gt;in&lt;/span&gt; {
    &lt;span class="pl-s"&gt;'windows-i386'&lt;/span&gt;:   &lt;span class="pl-s"&gt;'win32'&lt;/span&gt;,
    &lt;span class="pl-s"&gt;'windows-x86_64'&lt;/span&gt;: &lt;span class="pl-s"&gt;'win_amd64'&lt;/span&gt;,
    &lt;span class="pl-s"&gt;'macos-x86_64'&lt;/span&gt;:   &lt;span class="pl-s"&gt;'macosx_10_9_x86_64'&lt;/span&gt;,
    &lt;span class="pl-s"&gt;'macos-aarch64'&lt;/span&gt;:  &lt;span class="pl-s"&gt;'macosx_11_0_arm64'&lt;/span&gt;,
    &lt;span class="pl-s"&gt;'linux-i386'&lt;/span&gt;:     &lt;span class="pl-s"&gt;'manylinux_2_12_i686.manylinux2010_i686'&lt;/span&gt;,
    &lt;span class="pl-s"&gt;'linux-x86_64'&lt;/span&gt;:   &lt;span class="pl-s"&gt;'manylinux_2_12_x86_64.manylinux2010_x86_64'&lt;/span&gt;,
    &lt;span class="pl-s"&gt;'linux-armv7a'&lt;/span&gt;:   &lt;span class="pl-s"&gt;'manylinux_2_17_armv7l.manylinux2014_armv7l'&lt;/span&gt;,
    &lt;span class="pl-s"&gt;'linux-aarch64'&lt;/span&gt;:  &lt;span class="pl-s"&gt;'manylinux_2_17_aarch64.manylinux2014_aarch64'&lt;/span&gt;,
}.&lt;span class="pl-en"&gt;items&lt;/span&gt;():
    &lt;span class="pl-c"&gt;# Build the wheel here...&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;They &lt;a href="https://github.com/ziglang/zig-pypi/blob/main/README.pypi.md#usage"&gt;suggest&lt;/a&gt; that if you want to run their tools from a Python program you do so like this, to ensure your script can find the installed binary:&lt;/p&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-s1"&gt;sys&lt;/span&gt;, &lt;span class="pl-s1"&gt;subprocess&lt;/span&gt;

&lt;span class="pl-s1"&gt;subprocess&lt;/span&gt;.&lt;span class="pl-en"&gt;call&lt;/span&gt;([&lt;span class="pl-s1"&gt;sys&lt;/span&gt;.&lt;span class="pl-s1"&gt;executable&lt;/span&gt;, &lt;span class="pl-s"&gt;"-m"&lt;/span&gt;, &lt;span class="pl-s"&gt;"ziglang"&lt;/span&gt;])&lt;/pre&gt;
&lt;p&gt;I find this whole approach pretty fascinating. I really love the idea that I can add a full C/C++ compiler as a dependency to any of my Python projects, and thanks to Python wheels I'll automatically get a binary excutable compiled for my current platform.&lt;/p&gt;
&lt;h4&gt;Playwright Python&lt;/h4&gt;
&lt;p&gt;I spotted another example of this pattern recently in &lt;a href="https://playwright.dev/python/docs/intro"&gt;Playwright Python&lt;/a&gt;. Playwright is Microsoft's open source browser automation and testing framework - a kind of modern Selenium. I used it recently to build my &lt;a href="https://shot-scraper.datasette.io/"&gt;shot-scraper&lt;/a&gt; screenshot automation tool.&lt;/p&gt;
&lt;p&gt;Playwright provides a full-featured API for controlling headless (and headful) browser instances, with implementations in Node.js, Python, Java and .NET.&lt;/p&gt;
&lt;p&gt;I was intrigued as to how they had developed such a sophisticated API for four different platforms/languages at once, providing full equivalence for all of their features across all four.&lt;/p&gt;
&lt;p&gt;So I dug around in their Python package (from &lt;code&gt;pip install playwright&lt;/code&gt;) and found this:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;77M ./venv/lib/python3.10/site-packages/playwright/driver/node&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;That's a full copy of the Node.js binary!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ./venv/lib/python3.10/site-packages/playwright/driver/node --version
v16.13.0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Playwright Python works by providing a Python layer on top of the existing JavaScript API library. It runs a Node.js process which does the actual work, the Python library just communicates with the JavaScript for you.&lt;/p&gt;
&lt;p&gt;As with Zig, the Playwright team offer &lt;a href="https://pypi.org/project/playwright/#files"&gt;seven pre-compiled wheels&lt;/a&gt; for different platforms. The list today is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;playwright-1.22.0-py3-none-win_amd64.whl&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;playwright-1.22.0-py3-none-win32.whl&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;playwright-1.22.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;playwright-1.22.0-py3-none-manylinux1_x86_64.whl&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;playwright-1.22.0-py3-none-macosx_11_0_universal2.whl&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;playwright-1.22.0-py3-none-macosx_11_0_arm64.whl&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;playwright-1.22.0-py3-none-macosx_10_13_x86_64.whl&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I wish I could say "you can now &lt;code&gt;pip install&lt;/code&gt; a browser!" but Playwright doesn't actually bundle the browsers themselves - you need to run &lt;code&gt;python -m playwright install&lt;/code&gt; to download those separately.&lt;/p&gt;
&lt;p&gt;Pretty fascinating example of the same pattern though!&lt;/p&gt;
&lt;h4&gt;pip install a SQLite database&lt;/h4&gt;
&lt;p&gt;It's not quite the same thing, since it's not packaging an executable, but the one project I have that fits this mould if you squint a little is my &lt;a href="https://datasette.io/plugins/datasette-basemap"&gt;datasette-basemap&lt;/a&gt; plugin.&lt;/p&gt;
&lt;p&gt;It's a Datasette plugin which bundles a 23MB SQLite database file containing OpenStreetMap tiles for the first seven zoom levels of their world map - 5,461 tile images total.&lt;/p&gt;
&lt;p&gt;I built it so that people could use my &lt;a href="https://datasette.io/plugins/datasette-cluster-map"&gt;datasette-cluster-map&lt;/a&gt; and &lt;a href="https://datasette.io/plugins/datasette-leaflet-geojson"&gt;datasette-leaflet-geojson&lt;/a&gt; entirely standalone, without needing to load tiles from a central tile server.&lt;/p&gt;
&lt;p&gt;You can &lt;a href="https://datasette-tiles-demo.datasette.io/-/tiles/basemap"&gt;play with a demo here&lt;/a&gt;. I wrote more about that project in &lt;a href="https://simonwillison.net/2021/Feb/4/datasette-tiles/"&gt;Serving map tiles from SQLite with MBTiles and datasette-tiles&lt;/a&gt;. It's pretty fun to be able to run &lt;code&gt;pip install datasette-basemap&lt;/code&gt; to install a full map of the world.&lt;/p&gt;
&lt;p&gt;Seen any other interesting examples of &lt;code&gt;pip install&lt;/code&gt; being (ab)used in this way? Ping them to me &lt;a href="https://twitter.com/simonw/status/1528754782311047168"&gt;on Twitter&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt;  Paul O'Leary McCann &lt;a href="https://twitter.com/polm23/status/1528937321139122177"&gt;points out&lt;/a&gt; that PyPI has a default 60MB size limit for packages, though it can be raised on a case-by-case basis. He wrote about this in &lt;a href="https://www.dampfkraft.com/code/distributing-large-files-with-pypi.html"&gt;Distributing Large Files with PyPI Packages&lt;/a&gt;.&lt;/p&gt;
    
        &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/packaging"&gt;packaging&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/pypi"&gt;pypi&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/playwright"&gt;playwright&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/zig"&gt;zig&lt;/a&gt;&lt;/p&gt;
    

</summary><category term="packaging"/><category term="pypi"/><category term="python"/><category term="playwright"/><category term="zig"/></entry></feed>