Embed Static Files into Your Go Binary Using statik

Embed Static Files into Your Go Binary Using statik

Building web applications in Go often means juggling a binary and a collection of static assets—HTML pages, CSS styles, JavaScript bundles, images, fonts, and so on. Shipping a single executable that contains everything can simplify deployment, reduce confusion over file paths, and avoid missing‑resource errors in production. The Go ecosystem offers a neat helper for this purpose: statik.

statik is a tiny command‑line tool that scans a directory and generates a Go source file that registers the contents with an http.FileSystem.

This guide walks through installing the tool, generating embedded files, using them in code, and a few best‑practice tips.


Why Use statik?

  • One‑file deploy – ship one binary, no external files. Great for Docker images, serverless functions, or embedding assets in a CLI.
  • Type‑safe access – the generated package gives a typed fs.FileSystem; compile‑time errors surface early.
  • Deterministic output – by default statik preserves file modification times; optional flags allow turning this off for CI scenarios.

1. Install the statik CLI

# Go 1.22+ supports `go install` with @latest
go install github.com/rakyll/statik@latest

On older Go versions you can pull the module manually:

go get github.com/rakyll/statik

The binary will live at $GOPATH/bin or $HOME/go/bin depending on your environment.


2. Prepare a static asset folder

Create a folder named public (or whatever you like) and drop your assets inside:

└─ public/
   ├─ index.html
   ├─ styles.css
   ├─ script.js
   └─ images/
       └─ logo.png

Feel free to use any directory name; just remember the path you’ll pass to statik.


3. Generate the Go source

Run statik against the folder. Two common options:

  • -src: the path to the source directory.
  • -srcpath: name of the package the generated code will belong to.
# Classic usage
statik -src=./public

This produces a statik folder with a statik.go file that registers everything from public.

Filtering by extension

If you only want certain file types in a single binary (to keep size down), use the -include flag:

statik -src=./public -include=*.html,*.css,*.js

Or exclude:

statik -src=./public -exclude=*.png,*.jpg

Ignoring modification timestamps

In CI pipelines the Git checkout may give different mtime values than at development time, breaking deterministic tests. Suppress it with -m:

statik -m -src=./public

4. Use the embedded filesystem in your code

Import the generated package and initialize a fs.FileSystem.

package main

import (
    "fmt"
    "log"
    "net/http"

    "github.com/rakyll/statik/fs"

    // Import the generated package; the package name is the name created by -srcpath, 
    // most often just `statik` when you run statik without a custom path.
    _ "./statik"
)

func main() {
    // Create a new statik file system instance
    statikFS, err := fs.New()
    if err != nil {
        log.Fatalf("statik: %v", err)
    }

    // Optionally read a single file
    r, err := statikFS.Open("/index.html")
    if err != nil {
        log.Fatalf("open: %v", err)
    }
    defer r.Close()
    content, _ := io.ReadAll(r)
    fmt.Println("Loaded \"index.html\" content:", string(content)[:100])

    // Serve content over HTTP
    http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(statikFS)))
    log.Println("Serving on http://localhost:8080/static/")
    log.Fatal(http.ListenAndServe(":8080", nil))
}

Running the program:

go run main.go

Open http://localhost:8080/static/index.html to see your static page served from the binary.


5. Tips & tricks

  • Keep your assets tiny – statik works best when the total size stays under a few megabytes.
  • Use the -md5 flag (future feature, not yet released) to store MD5 checksums for integrity.
  • Avoid huge binary rebuilds – only re‑run statik when assets change. Use a makefile target or git hooks for automation.
  • Check deterministic builds – unit tests can open a file from the generated FS and assert its content or timestamp.

6. Where else can you use statik?

  • CLI tools that need local templates.
  • Serverless Go functions – embed dependencies and assets directly.
  • Desktop Go apps – include icons, help files, and configuration templates.

The tool is maintained actively; check the GitHub repository for new releases and enhancements.


Conclusion

Bundling static assets with your Go binary streamlines deployment and reduces external dependencies. statik provides an elegant, zero‑config solution that integrates cleanly with Go’s http.FileSystem. By following the steps above, you’ll be able to generate, embed, and serve static files in minutes, keeping your production environments lean and straightforward.

Original Article: View Original

Share this article