https://github.com/bdombro/shebangsy
A #!shebang for single-file apps in C++, Go, Mojo, Nim, Python 3, Rust, and Swift
https://github.com/bdombro/shebangsy
cpp go mojo nim python rust shebang swift
Last synced: about 1 month ago
JSON representation
A #!shebang for single-file apps in C++, Go, Mojo, Nim, Python 3, Rust, and Swift
- Host: GitHub
- URL: https://github.com/bdombro/shebangsy
- Owner: bdombro
- Created: 2026-04-17T17:09:46.000Z (2 months ago)
- Default Branch: main
- Last Pushed: 2026-04-19T12:07:26.000Z (2 months ago)
- Last Synced: 2026-04-19T13:26:02.615Z (2 months ago)
- Topics: cpp, go, mojo, nim, python, rust, shebang, swift
- Language: Nim
- Homepage:
- Size: 1.67 MB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
Awesome Lists containing this project
README
```
/$$ /$$ /$$
/ $$/ $$ | $$
/$$$$$$$$$$| $$ /$$$$$$$ /$$ /$$
| $$ $$_/| $$ /$$_____/| $$ | $$
/$$$$$$$$$$|__/| $$$$$$ | $$ | $$
|_ $$ $$_/ \____ $$| $$ | $$
| $$| $$ /$$ /$$$$$$$/| $$$$$$$
|__/|__/ |__/|_______/ \____ $$
/$$ | $$
| $$$$$$/
\______/
```
# Shebangsy
**Shebangsy** (also written `#!sy`) runs single-file scripts in **C++, Go, Mojo, Nim, Python 3, Rust, and Swift**. You add a shebang, mark the file executable, and run it like any other program. Dependencies and build flags live in small `#!` directives at the top of the file, so you can pin versions without maintaining a separate project tree for every script.
On a warm cache hit, overhead versus a pre-built binary is on the order of **~10 ms**—enough for interactive use, including shell completions.
**Platforms:** macOS and Linux (POSIX). Windows is not supported.
## Quick start
1. Put **`shebangsy` on your `PATH`** (see [Install](#install)).
2. Start the file with `#!/usr/bin/env -S shebangsy `.
3. Run `chmod +x` on the script and execute it.
Example: save as `gonum-hello.go`, then run it.
```go
#!/usr/bin/env -S shebangsy go
#!requires: gonum.org/v1/gonum
package main
import (
"fmt"
"gonum.org/v1/gonum/mat"
)
func main() {
u := mat.NewVecDense(3, []float64{1, 2, 3})
v := mat.NewVecDense(3, []float64{4, 5, 6})
fmt.Println("u · v =", mat.Dot(u, v))
}
```
```sh
chmod +x gonum-hello.go
./gonum-hello.go # first run: compile, then execute
./gonum-hello.go # warm cache: run cached binary
```
More samples live under [`examples/`](./examples).
## How it works
The first time you run a script, shebangsy compiles (or materializes) it into a cache under `~/.cache/shebangsy`. Later runs compare the source file’s **size and modification time** to that cache entry. When both still match the cached entry, the cached artifact runs immediately; any change to size or mtime (including `touch` without editing) invalidates the entry and shebangsy rebuilds. Directive lines (`#!requires:`, `#!flags:`) are stripped before the compiler sees the source.
## Command line
Without a shebang, you can invoke the same pipeline explicitly:
```text
shebangsy [...script args]
```
## Install
**Releases:** prebuilt binaries are on the [releases](https://github.com/bdombro/shebangsy/releases) page. You can copy them to your path (e.g. `~/.local/bin`).
```sh
curl -sSL https://api.github.com/repos/bdombro/shebangsy/releases/latest | grep -Eo 'https://[^"]*aarch64-apple-darwin[^"]*\.zip' | head -1 | xargs curl -sSL -o shebangsy.zip
unzip -o shebangsy.zip && chmod +x shebangsy
mv shebangsy ~/.local/bin/
rm shebangsy.zip
```
From a clone of this repository:
```sh
just install
# or: ./scripts/install.sh
```
That builds with Nimble and installs **`shebangsy`** to **`~/.nimble/bin`**. Ensure that directory is on your **`PATH`** before running.
Pre-built archives (macOS host and Linux glibc) are produced under **`dist/`** when you run:
```sh
just build-cross
# or: ./scripts/build-cross.sh
```
The install script also clears existing cache files under `~/.cache/shebangsy` after a successful install.
## Cache
Artifacts and shared workspaces live under **`~/.cache/shebangsy`**. You normally do not need to touch this directory; changing the script’s size or mtime invalidates its entry.
**When to clear manually:** For example, after changing Swift dependency versions in a shared SwiftPM workspace, or if you want a completely clean slate, remove the cache directory:
```sh
rm -rf ~/.cache/shebangsy
```
There is no separate `cache-clear` subcommand; deleting that path is the supported reset.
## Benchmark
### Results
Mean end-to-end time for small “hello” style programs, averaged over benchmark runs. The chart compares shebangsy to running a compiled `bin` in the same language and to other runners where applicable.
In short, shebangsy is in the same ballpark as alternatives, with roughly **~10 ms** overhead versus a direct binary on warm paths.
```mermaid
---
config:
themeVariables:
xyChart:
backgroundColor: "#e8eaed"
plotColorPalette: "#1d4ed8, #1d4ed8, #15803d, #15803d, #15803d, #15803d, #a16207, #a16207, #7c3aed, #7c3aed, #b91c1c, #b91c1c, #b91c1c, #0e7490, #0e7490, #4338ca, #4338ca, #4338ca"
titleColor: "#111318"
xAxisLabelColor: "#2d3139"
yAxisLabelColor: "#2d3139"
xAxisTitleColor: "#1a1d24"
yAxisTitleColor: "#1a1d24"
xAxisLineColor: "#9aa0ab"
yAxisLineColor: "#9aa0ab"
xAxisTickColor: "#5c6370"
yAxisTickColor: "#5c6370"
---
xychart-beta horizontal
title "Mean time (ms) per app — all time"
x-axis ["cpp/bin", "cpp/shebangsy.cpp", "go/bin", "go/shebangsy.go", "go/gorun.go", "go/scriptisto.go", "mojo/bin", "mojo/shebangsy.mojo", "nim/bin", "nim/shebangsy.nim", "python/bin", "python/shebangsy.py", "python/uv.py", "rust/bin", "rust/shebangsy.rs", "swift/bin", "swift/shebangsy.swift", "swift/swift_sh.swift"]
y-axis "ms" 0 --> 80
bar [5.8, 16.3, 6.6, 18.0, 18.6, 18.8, 10.8, 22.0, 6.1, 17.8, 16.5, 30.3, 54.3, 6.1, 18.1, 7.0, 17.9, 80.0]
```
See [`docs/contributing.md`](./docs/contributing.md#running-the-benchmark) for how to run the benchmark and [`benches-report.md`](./benches-report.md) for more charts.
## Documentation
- **[Language reference](docs/language-reference.md)** — `#!requires:`, `#!flags:`, and per-language behavior.
- **[Contributing](docs/contributing.md)** — build, test, editor tips, architecture, cache model, benchmarks.
- **[Adding a language](docs/adding-a-language.md)** — registration checklist and backend contract.
## License
MIT