DEV Community

Fareez Ahamed
Fareez Ahamed

Posted on • Originally published at 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
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)
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
flopp profile image
Florian Pigorsch

This should also work for e.g. html/template files and arbitrary data files, right?

Collapse
 
fareez profile image
Fareez Ahamed

Yes.. Any files. Configurations, lookup tables, ML trained data, anything.

Collapse
 
flopp profile image
Florian Pigorsch

Ok, cool!

Collapse
 
davidkroell profile image
David Kröll

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)?

Collapse
 
fareez profile image
Fareez Ahamed

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.