fareez.info

Embedding a React Application in Go Binary

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.

comments powered by Disqus