It is possible to place files directly inside Go executables when compiled. This allows us to create single-file websites and other applications with minimal runtime dependencies.
With the embed package, we can use directives within comments that indicate files. These directives are replaced with file contents during compilation.
Here we use the embed module in the simplest way possible—by embedding a text file as a string
. Please note the exact syntax of the "go:embed" statement within comments.
exampleTxt
" string
.package main import ( "fmt" _ "embed" ) //go:embed example.txt var exampleTxt string func main() { // Print the length of embedded string, and also the string itself. fmt.Println(len(exampleTxt)) fmt.Println(exampleTxt) }18 Some example text.
We can embed an entire file system into our Go executable. We use the same "go:embed" statement, but with multiple file names, and follow it with a "embed.FS
" variable.
WalkDir
with 3 arguments.WalkDir
is the name of the embed.FS
—here we used the identifier "x."func
that is called on each file found by WalkDir
. In this func
, we access each file, and print its path and contents.package main import ( "fmt" "io/fs" "embed" ) //go:embed example.txt output.webp var x embed.FS func main() { // Walk all files in the embedded file system. fs.WalkDir(x, ".", func(path string, d fs.DirEntry, err error) error { // Ignore error. if err != nil { return nil } // Skip period path. if path == "." { return nil } fmt.Println("PATH:", path) // Read file. content, _ := fs.ReadFile(x, path) // Print file length and file if it is short. fmt.Println("FILE LENGTH:", len(content)) if len(content) <= 50 { fmt.Println("FILE CONTENTS:", string(content)) } return nil }) }PATH: example.txt FILE LENGTH: 18 FILE CONTENTS: Some example text. PATH: output.webp FILE LENGTH: 4796
With the embed module, we can embed files as strings, and even entire file systems which we can later access with WalkDir
. We can open each embedded file and display its contents.