Go

How does //go:embed work? Show the three target types.

Question 433MediumGo 1.22 to 1.25

//go:embed (Go 1.16) compiles files into the binary at build time. The directive goes immediately above a package-level variable of type string, []byte, or embed.FS. Paths are relative to the source file's directory.

package web

import (
    "embed"
    "io/fs"
    "net/http"
)

//go:embed VERSION
var version string          // single file only

//go:embed schema.sql
var schema []byte           // single file only

//go:embed static templates/*.tmpl
var assets embed.FS         // many files / dirs, read-only fs.FS

func Handler() http.Handler {
    sub, err := fs.Sub(assets, "static")   // strip "static/" prefix
    if err != nil {
        panic(err)
    }
    return http.FileServerFS(sub)          // Go 1.22+
}

Key points:

  • You must import embed. Use a blank import _ "embed" when only string or []byte targets are used.
  • embed.FS implements fs.FS, fs.ReadDirFS and fs.ReadFileFS, so it works with template.ParseFS, http.FS and similar.
  • It is read-only and safe for concurrent use.
  • No copy is made at startup. A string target points at read-only data. A []byte target points at writable data, so mutating it is allowed, but every user of that variable sees the change (copy it if you need a pristine version). embed.FS contents cannot be modified.

This is the typical interview answer for "ship a single binary with a SPA, migrations or templates".

More on Modules, Packages & Tooling

All 36 Modules, Packages & Tooling questions