Backend Development 6 min read

Understanding Go 1.16 embed: Use Cases, Implementation Details, and Design Rationale

This article explains the Go 1.16 embed feature by describing the typical configuration‑file problem, showing traditional file‑reading code versus embed‑based code, and diving into the compiler’s embedcfg handling and the underlying design philosophy of the new io/fs package.

IEG Growth Platform Technology Team
IEG Growth Platform Technology Team
IEG Growth Platform Technology Team
Understanding Go 1.16 embed: Use Cases, Implementation Details, and Design Rationale

The author, a backend engineer at Tencent IEG Growth Platform, introduces Go 1.16’s new embed feature and outlines three main topics: practical use cases, the source‑level implementation, and the design ideas behind it.

When deploying a new project, configuration files placed alongside the source code are not automatically bundled into the container image, causing the binary to fail at runtime because it cannot locate the required files.

Traditionally, developers read configuration files with code like the following, which expects the file to exist next to the binary:

func main() {
	fPath := "conf/conf.ini"
	c, err := ioutil.ReadFile(fPath)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(c))
}

Using go:embed , the same file can be compiled directly into the binary, eliminating the need for external copies. The embed declaration and usage look like this:

//go:embed conf/conf.ini
var f embed.FS

func main() {
	fPath := "conf/conf.ini"
	data, err := f.ReadFile(fPath)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(data))
}

The implementation is a compile‑time operation. The Go compiler scans for go:embed directives, writes the referenced file paths into an embedcfg file, and later the initEmbed routine reads those files, converting them into symbols that are linked into the final .a package. Key functions such as fileStringSym perform the actual file system calls (open, stat) during this phase.

Beyond solving the configuration‑file problem, go:embed was introduced to support the new io/fs package, which provides a generic, read‑only file‑system abstraction inspired by the Unix “everything is a file” philosophy. The generated FS object implements the fs.FS interface, whose Open method returns a fs.File that can be used like a regular file but is read‑only. This design moves away from the older os.File model and aligns Go with more modern, portable file‑system handling.

Although the current FS implementation is read‑only, proposals for write capabilities are already under discussion, indicating the design will continue to evolve.

In conclusion, go:embed provides a seamless way to embed static assets into Go binaries, preserves compatibility with existing APIs (e.g., ioutil.ReadFile vs. embed.FS.ReadFile ), and lays the groundwork for a richer, cross‑platform file‑system abstraction.

BackendGoembedfile-embeddinggo1.16io/fs
IEG Growth Platform Technology Team
Written by

IEG Growth Platform Technology Team

Official account of Tencent IEG Growth Platform Technology Team, showcasing cutting‑edge achievements across front‑end, back‑end, client, algorithm, testing and other domains.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.