How to Embed a Single File with go

embed

Use the `embed` package to embed a single file by declaring a variable with the `//go:embed` directive pointing to the specific file path.

Use the embed package to embed a single file by declaring a variable with the //go:embed directive pointing to the specific file path. This compiles the file's contents directly into your binary as a []byte or string, eliminating the need for external file dependencies at runtime.

Here is a practical example embedding a single JSON configuration file:

package main

import (
	"encoding/json"
	"embed"
	"fmt"
	"log"
)

//go:embed config.json
var configData []byte

type Config struct {
	AppName string `json:"app_name"`
	Port    int    `json:"port"`
}

func main() {
	var cfg Config
	if err := json.Unmarshal(configData, &cfg); err != nil {
		log.Fatal(err)
	}
	fmt.Printf("App: %s, Port: %d\n", cfg.AppName, cfg.Port)
}

If you prefer to work with the embed.FS interface (useful if you might expand to multiple files later), you can define a variable of type embed.FS and read the file using Open or Read:

package main

import (
	"embed"
	"fmt"
	"io"
	"log"
)

//go:embed config.json
var f embed.FS

func main() {
	file, err := f.Open("config.json")
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	content, err := io.ReadAll(file)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(content))
}

Key points to remember:

  1. Path Resolution: The path in //go:embed is relative to the file containing the directive. If your file is in a subdirectory, use subdir/file.txt.
  2. Build Tags: The //go:embed directive is processed by the Go compiler, not the interpreter. If you have build constraints (like //go:build linux), the directive must be in a file that satisfies those constraints.
  3. Variable Types: You can embed into []byte, string, or embed.FS. Using []byte or string is slightly more efficient for single files as it avoids the overhead of the virtual filesystem interface.
  4. No Wildcards for Single Files: While embed supports wildcards (e.g., *.json), for a single file, explicitly naming it is clearer and prevents accidental inclusion of unintended files.

This approach ensures your configuration or static assets are always available, even if the deployment environment lacks the original source files.