Getting Started

Install

go get github.com/floatpane/termimage

CGo is required (stb_image decode). You need a C compiler on your PATH. On Arch Linux: pacman -S gcc. On Debian/Ubuntu: apt install build-essential.

Minimal usage

package main

import (
    "os"
    termimage "github.com/floatpane/termimage"
)

func main() {
    // Required: lets sandboxed child processes identify themselves.
    termimage.MaybeRunWorker()

    err := termimage.Display(os.Stdout, os.Args[1], termimage.Options{})
    if err != nil {
        panic(err)
    }
}
go run main.go ~/Pictures/photo.jpg

With sandboxing

termimage.Display(os.Stdout, path, termimage.Options{
    Sandboxed: true, // decode in Landlock-restricted subprocess
})
Important

MaybeRunWorker() must be the first line of main() when using Sandboxed: true. The library re-execs your binary as the worker; if MaybeRunWorker() is called after other init code runs, the child may behave unexpectedly.

Explicit protocol

termimage.Display(os.Stdout, path, termimage.Options{
    Protocol:  termimage.Kitty,
    MaxWidth:  1920,
    MaxHeight: 1080,
})

Remote images and data URIs

Display accepts any of these as src:

// Local file
termimage.Display(os.Stdout, "/path/to/cat.png", opts)

// Remote URL
termimage.Display(os.Stdout, "https://example.com/cat.png", opts)

// Data URI (base64 only)
termimage.Display(os.Stdout, "data:image/png;base64,iVBORw0KGgo...", opts)

Remote URLs are fetched in the parent process; payloads cap at 64 MiB. The sandboxed worker still runs — bytes are piped to it over stdin with Landlock denying all filesystem access.

For cancellable fetches, use DisplayContext:

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
termimage.DisplayContext(ctx, os.Stdout, url, opts)