Go 1.16 added a new embed package.

While the idea is not a novelty, there were already some packages with slightly different APIs fulfilling similar roles, for example:

Having an official package is always a welcome addition to the batteries-included standard library.

Usage

A possible way to embed react assets could be as simple as:

package web

import (
    "embed"
    "io/fs"
)

//go:embed build/*
var content embed.FS

And serving assets using http.FileServer:

http.Handle("/static/", http.FileServer(http.FS(content)))

However, following this structure, one may end up with some unexpected 404 responses.

Exploring Embed

Fortunately, go list gained some new fields we can use to understand how embed works.

.EmbedPatterns displays patterns being used:

$ go list -f '{{ join .EmbedPatterns "\n" }}' ./...
build/*

It can even detect if a pattern is not matching any resources:

$ go list -f '{{ join .EmbedPatterns "\n" }}' ./...
client/client.go:10:20: pattern foobar/*: no matching files found

Another addition to go list is allowing to list embed files:

go list -f '{{ join .EmbedFiles "\n" }}' ./...
build/favicon.ico
build/index.html
build/logo512.png
build/robots.txt
build/static/css/main.6dea0f05.chunk.css
build/static/js/2.6071c2c3.chunk.js

In this case, we can observe using the directive //go:embed build/* will include the build directory and all files in the directory.

If the files being served are not expecting to be in build directory it is possible to change the subtree:

// Contents helper function
func Contents() (fs.FS, error) {
    return fs.Sub(content, "build")
}

Embed package seems an exciting addition to the Go standard library.

I am curious to see which uses cases are possible. For now, I am expecting it to become the de facto solution to store database migration scripts and assets in low traffic apps.

Example code is available in https://github.com/jacoelho/sample-go-react