runlet

module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 21, 2026 License: MIT

README

runlet

Single-binary runner for Go scripts with inline dependencies. Like uv run for Python or cargo script for Rust — but for Go.

Go Reference Go Report Card CI Release

⚠️ Pre-release. API and the // runlet:dep comment syntax may shift before v0.1.0. Star/watch to follow.


Write a single .go file, declare its dependencies in a magic comment, run it — no go.mod, no go.sum, no mkdir mytool && go mod init ceremony.

// runlet:dep github.com/charmbracelet/lipgloss v1.0.0
package main

import (
    "fmt"
    "github.com/charmbracelet/lipgloss"
)

func main() {
    style := lipgloss.NewStyle().
        Bold(true).
        Foreground(lipgloss.Color("#FAFAFA")).
        Background(lipgloss.Color("#7D56F4")).
        Padding(0, 1)
    fmt.Println(style.Render("hello from a single file"))
}

Run it:

runlet hello.go

That's it. runlet parses the dependency comments, synthesises a throwaway go.mod in a content-addressed cache, downloads deps, and hands the file to go run.

Why this exists

Other languages closed this gap a while ago:

Inline-deps runner
Python uv run (PEP 723 since uv 0.4) — first-class
Rust cargo +nightly script (RFC 3424) — stabilising
JS/TS bunx, deno run — built into the runtime
Go

go run works on .go files but only resolves the stdlib. Anything beyond that needs a full module layout. For one-off scripts — "parse this log, query that endpoint, format the result" — the module ceremony is the part that kills the workflow.

gorun (erning/gorun, 2013) was the first attempt. It predates Go modules and does not handle inline dependency declarations.

runlet is the modern take: PEP-723-style inline deps, Go-modules under the hood, a content-addressed cache so the second run of the same script starts in milliseconds.

Install

go install github.com/goncharovart/runlet/cmd/runlet@latest

Requires Go 1.22+. The downloaded runlet binary is the only prerequisite — it shells out to your existing go toolchain.

Magic comment grammar

A script declares dependencies through line comments at the top of the file:

// runlet:dep <module path> <version>
  • Comments anywhere in the file are accepted, but conventionally they go at the top.
  • <version> follows Go module versioning: a semver tag (v1.2.3), a pseudo-version (v0.0.0-20240101120000-abcdef012345), or latest (resolved at first run, then frozen in the cache).
  • Multiple runlet:dep lines are allowed; each one becomes a require directive in the synthesised go.mod.

Shebang

Make a script directly executable:

//usr/bin/env runlet "$0" "$@"; exit
// runlet:dep github.com/spf13/cobra v1.9.0

package main
// ...

The //usr/bin/env ...; exit trick is the standard Go workaround for the fact that real #! shebangs break Go's parser. runlet strips the line before handing the file to go run.

Make it executable with chmod +x script.go and call it as ./script.go.

Cache

runlet caches synthesised modules in $XDG_CACHE_HOME/runlet/ (or ~/.cache/runlet/ on Linux/macOS, %LOCALAPPDATA%\runlet\ on Windows). The cache key is a content hash of the script + sorted dep list, so:

  • Changing the script invalidates only that script's cache entry.
  • Two scripts with identical deps reuse the same downloaded modules (through the standard Go module cache GOMODCACHE).
  • runlet cache clear wipes everything.

Status

This is a young project. The roadmap to v0.1.0:

  • CLI scaffold, parser, basic runner
  • Cache layer
  • Shebang stripping
  • runlet cache clear / runlet cache info
  • Multi-file scripts (runlet ./scripts/)
  • First example bundle
  • CI with -race and golangci-lint

Open an issue or a discussion — design feedback on the magic-comment grammar is especially welcome before v0.1.0 ships.

License

MIT. See LICENSE.

Directories

Path Synopsis
cmd
runlet command
Command runlet runs a single-file Go script that declares its dependencies through magic comments.
Command runlet runs a single-file Go script that declares its dependencies through magic comments.
runlet:dep github.com/charmbracelet/lipgloss v1.0.0
runlet:dep github.com/charmbracelet/lipgloss v1.0.0
internal
parser
Package parser extracts runlet metadata from a Go script.
Package parser extracts runlet metadata from a Go script.
runner
Package runner materialises a parsed runlet Script into a temporary Go module on disk and hands it off to the host `go` toolchain.
Package runner materialises a parsed runlet Script into a temporary Go module on disk and hands it off to the host `go` toolchain.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL