# Zigbang: shebang scripts with zig code

**URL:** <https://ziggit.dev/t/zigbang-shebang-scripts-with-zig-code/14053>\
**Category:** Showcase\
**Created:** [January 24, 2026, 9:38pm UTC](https://ziggit.dev/t/zigbang-shebang-scripts-with-zig-code/14053 "2026-01-24T21:38:13Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Anthon](https://ziggit.dev/user_avatar/ziggit.dev/anthon/32/8967_2.png) [@Anthon](https://ziggit.dev/u/Anthon)\
**Post date:** [January 24, 2026, 9:38pm UTC](https://ziggit.dev/t/zigbang-shebang-scripts-with-zig-code/14053/1 "2026-01-24T21:38:13Z")

</div>

[`zigbang`](https://codeberg.org/anthon/zigbang) allows you to write scripts on Unix-like systems that start with magic numbers 0x23 and 0x21 (more commonly known as [shebang](https://en.wikipedia.org/wiki/Shebang_(Unix))), and for which the body is a Zig program:

```zig
#! /usr/local/bin/zigbang

const std = @import("std");

pub fn main() !void {
    for (std.os.argv, 0..) |arg, idx|
        std.debug.print("{s}{s}", .{if (idx == 0) "cmd: " else " ", arg});
    std.debug.print("\n", .{});
}

```

if the above is in a file `testzigbang`, which has the execute permission set, you can do

```none
$ testzigbang a b c
Needs compilation testzigbang.zig in dir /opt/zigbang/0.15
/opt/zig/0.15/zig build-exe -O Debug -femit-bin=/opt/zigbang/bin/.zigbang.tmp testzigbang.zig
compilation result .{ .Exited = 0 }
cmd: /opt/zigbang/bin/testzigbang a b c

```

re-running the command will not show the compilation “effort” again, until the script changes. You can suppress non-failing compiler output with `-q` on the shebang line.

`zigbang` has some built-in settings to indicate where the zig compilers “live”, which version of zig to use, where the compiled binaries are cached, etc. These and some compiler invocation options can be overridden with options on the shebang line (those are not commandline options for your program!) :

```none
#! /usr/local/bin/zigbang --fast --no-llvm --dir /opt/zigbang --zig=0.14.1 --zigbase=/opt/zig -q

```

`zigbang` will compile your code and invoke the resulting binary with the commandline options you provided to the “script”. The binaries are cached (with the same name as the file containing the shebang line) and only compiled if necessary/changed. and the binaries are not invoked if the compilation had no errors.

`zigbang` itself compiles with 0.15.2 and has been tested on macOS and Linux ( Windows AFAIK still has no native support for magic numbers ), with the program handling the difference in which the shebang line parameters are passed to the `zigbang` program. If your program is portable, then your zigbang script should be as well.

By default `zigbang` take the major.minor version number from the version of `zig` it was compiled with. Because backwards incompatible improvements to zig are to be expected until zig-1.0, I will probably update `zigbang` with some functionality to “pin” the zig version of any “scripts” with `zigbang` lines that don’t have `--zig=` explicitly set.

_`zigbang` is ideal for those tasks that take only a minute, and that never repeat, but for which you rather spend 10 minutes writing a program (in Zig)._

---

<div class="post-metadata">

**Author:** ![cryptocode](https://ziggit.dev/user_avatar/ziggit.dev/cryptocode/32/817_2.png) [@cryptocode](https://ziggit.dev/u/cryptocode)\
**Post date:** [January 24, 2026, 10:51pm UTC](https://ziggit.dev/t/zigbang-shebang-scripts-with-zig-code/14053/2 "2026-01-24T22:51:18Z")

</div>

Very cool!

(Amusingly, the following works out of the box in most shells:

```zig
//usr/bin/env zig run "$0" -- "$@" ; exit 
const std = @import("std");
pub fn main() !void {
    std.log.info("Awesome, it works\n", .{});
}

```

chmod +x and run the zig file

Yours does a lot more, just wanted to mention it as a little factoid)

---

<div class="post-metadata">

**Author:** ![pachde](https://ziggit.dev/user_avatar/ziggit.dev/pachde/32/2485_2.png) [@pachde](https://ziggit.dev/u/pachde)\
**Post date:** [January 25, 2026, 1:21am UTC](https://ziggit.dev/t/zigbang-shebang-scripts-with-zig-code/14053/3 "2026-01-25T01:21:47Z")

</div>

On Windows, one could get this working:

- Create a unique file extension for zig script files.
- Register a shell `open` verb for that file extension that runs zigbang.

Creating the verb registration would be a pretty easy PowerShell script.
