gowrapper

command module
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Apr 26, 2026 License: MIT Imports: 11 Imported by: 0

README

gowrapper

Packs a directory into a self-extracting Go binary. That's it.

You point it at a folder — your app, its libraries, whatever it needs to run — and it spits out a single executable. When that executable runs, it decompresses everything into a temp directory, launches your binary, then cleans up. The end user never sees any of it.

your bundle/
├── myapp
├── libfoo.so
└── assets/
         ↓
   gowrapper
         ↓
  myapp-portable   ← ships everything, extracts on run, leaves no trace

Why

Distributing apps with native dependencies is annoying. You either write an installer, ask users to install libraries themselves, or maintain a package for every distro. gowrapper is the lazy option: bundle the whole thing and ship one file. Works well for Qt/GTK apps, CLI tools with native deps, or anything compiled in a language that doesn't have Go's static linking story.


Install

go install github.com/Tom5521/gowrapper@latest

Requires Go 1.21+ and a working Go toolchain (it calls go build internally).


Usage

gowrapper --bundle <dir> --bin <path-inside-bundle> --out <output-file> [flags]

Three flags are required: --bundle, --bin, and --out. Everything else is optional.

gowrapper \
  --bundle ./dist/myapp \
  --bin    myapp \
  --out    myapp-portable
# Windows GUI app — no console window, lower compression for faster startup
gowrapper \
  --bundle      ./dist/myapp \
  --bin         myapp/myapp.exe \
  --out         myapp-portable.exe \
  --name        MyApp \
  --windowsgui \
  --compression-level 3
All flags
Flag Short Default Description
--bundle -b required Directory to pack (binary + all its dependencies)
--bin required Path to the target binary inside the bundle
--out -o required Output path for the generated executable
--name -n "" App name — used as the temp directory prefix
--args -a none Default arguments passed to the bundled binary
--compression-level -c 9 lz4 compression level, 0 (fast) to 9 (smallest)
--verbose -v false Pass -v to the Go compiler
--go-args -g none Extra arguments forwarded to go build
--windowsgui false Adds -H=windowsgui to ldflags (hides the console window on Windows)

The compression level trades startup time for bundle size. Level 9 gives the smallest binary; level 0 (lz4.Fast) extracts the quickest. For most apps, somewhere in the middle is fine.


How it works

  1. The bundle directory gets packed into a tar archive and compressed with lz4.
  2. A small Go program (the "template") is written to a temp directory alongside the compressed bundle.
  3. gowrapper runs go build on that template, injecting the app name, binary path, and default args via -ldflags.
  4. The result is a standalone binary with the compressed bundle baked in via //go:embed.

When the generated binary is executed, it decompresses the bundle into os.TempDir(), runs the target binary (forwarding any arguments), and removes the temp directory on exit. On Windows, panics surface as native error dialogs via zenity instead of crashing silently.


Project layout

gowrapper/
├── main.go           # CLI (cobra), orchestrates the build process
├── template/
│   └── main.go       # The wrapper code embedded into every generated binary
└── util/
    ├── compress.go   # tar + lz4 compression
    └── decompress.go # tar extraction

Dependencies


License

MIT

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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