Compressing embedded files in Go
Go’s embed feature lets you bundle static assets into an executable, but it stores them uncompressed. This wastes space: a web interface with documentation can bloat your binary by dozens of megabytes. A proposition to optionally enable compression was declined because it is difficult to handle all use cases. One solution? Put all the assets into a ZIP archive! 🗜️
Code
The Go standard library includes a module to read and write ZIP archives. It
contains a function that turns a ZIP archive into an io/fs.FS
structure that can replace embed.FS in most contexts.1
package embed import ( "archive/zip" "bytes" _ "embed" "fmt" "io/fs" "sync" ) //go:embed data/embed.zip var embeddedZip []byte var dataOnce = sync.OnceValue(func() *zip.Reader { r, err := zip.NewReader(bytes.NewReader(embeddedZip), int64(len(embeddedZip))) if err != nil { panic(fmt.Sprintf("cannot read embedded archive: %s", err)) } return r }) func Data() fs.FS { return dataOnce() }
We can build the embed.zip archive with a rule in a Makefile. We specify the
files Continue reading