Embedding Static Resources in Go with //go:embed
Since Go 1.16, the //go:embed directive allows developers to embed files, directories, or entire static assets directly into the compiled binary, simplifying deployment; this article explains the directive, its three embedding methods, usage in HTTP servers, unit tests, handling parent directories, and important considerations.
The //go:embed compiler directive was introduced in Go 1.16 to embed arbitrary files or directories into a Go binary at compile time, making deployment of static resources straightforward.
What is //go:embed? It is a compiler directive that can embed any file or directory (except a few restricted types) into a variable of type string , []byte , or embed.FS .
Three embedding methods :
Embed a single file into a string variable.
Embed a single file into a []byte variable.
Embed multiple files or a whole directory into an embed.FS virtual file system.
Example syntax:
import "embed"
//go:embed hello.txt
var content string
//go:embed hello.txt
var contentBytes []byte
//go:embed file
var fileFS embed.FSThe directive must be placed immediately above the variable declaration and cannot contain spaces within //go:embed .
Quick start example shows a project structure with hello.txt , file/hello1.txt , etc., and a main.go that embeds these resources and prints their contents using ReadFile , ReadDir , and fs.Sub .
Using //go:embed in an HTTP server demonstrates two approaches: the classic http.FileServer(http.Dir("static")) and the embed‑based version http.FileServer(http.FS(staticFS)) . It also covers stripping the /static/ prefix with http.StripPrefix or using fs.Sub to serve files at the root path.
Unit testing uses the same directive in *_test.go files, showing that the embed package works identically in tests and that test data should reside in a testdata directory.
Embedding parent directories explains that //go:embed does not accept .. patterns, so a workaround is to copy the parent assets into a local directory via //go:generate or to create a dedicated Go file inside the target directory that embeds * and then import that package.
Important notes include:
The embedded string is immutable, while []byte can be modified.
embed.FS is read‑only and safe for concurrent use.
Patterns cannot embed empty directories, symbolic links, or files starting with . or _ unless prefixed with all: or using wildcards.
Path separators are always forward slashes, even on Windows.
The directive can only be applied to package‑level variables.
In summary, //go:embed provides a simple, compile‑time way to bundle static assets into Go binaries, useful for backend services, testing, and reducing runtime file‑system dependencies.
Go Programming World
Mobile version of tech blog https://jianghushinian.cn/, covering Golang, Docker, Kubernetes and beyond.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.