Go 1.16 has come out with a feature which I waited for quite some time. With Embed we will be able to add static files into the go binary at build time. It also makes accessing the files as simple as dealing with File System APIs.
This has opened up a whole new world on building and deploying web applications. Now we can embed static web apps along with the API server built in Go. In this article, we are going to explore how we can embed a React application in Go binary at build time.
First, let us create a React application using Create-React-App.
npx create-react-app react-app
Once the application is created, we will have the default App
component which shows the React icon. We are not going to change it. We are just going to use it as it is and embed. So let's build the app, so that we can get the static files from the build
folder.
npm run build
Create a folder in which we are going to code the Go application. Copy the build
folder into the newly created folder.
/
|-build
| |- React build files here
|-main.go
package main
import (
"embed"
"fmt"
"io/fs"
"net/http"
)
//go:embed build
var embeddedFiles embed.FS
func main() {
fmt.Println("Starting Server")
http.Handle("/", http.FileServer(getFileSystem()))
http.ListenAndServe(":9000", nil)
}
func getFileSystem() http.FileSystem {
// Get the build subdirectory as the
// root directory so that it can be passed
// to the http.FileServer
fsys, err := fs.Sub(embeddedFiles, "build")
if err != nil {
panic(err)
}
return http.FS(fsys)
}
Notice the directive go:embed build
. The variable embeddedFiles
will be initialized with a reference to the File System containing
the build
folder as a subdirectory.
go build main.go
Now build the Go application, get the binary and run it wherever you want and go to http://localhost:9000
, you will see the React appliation. It is a single binary containing all the static assets. Easy to deploy or distribute.
This open's up a lot of possibilities. We can embed multiple small frontend applications into a Go binary and they can work together. Everything that can be done on nginx can be very well done using Go while still having all assets packed together.
Top comments (5)
This should also work for e.g. html/template files and arbitrary data files, right?
Yes.. Any files. Configurations, lookup tables, ML trained data, anything.
Ok, cool!
Is this then included inside the built Go binary? You mentioned above it would be referenced. But why then use this? What happens when it gets deleted (the build directory)?
It will be built into the binary. So you will have only one file binary file which contains executable code, as well as static assets.