Bundling static files within your Golang app

Alex Nadalin
Apr 16, 2018 · 2 min read

One of the nice features of golang is that you can simply distribute your programs through executables, meaning the user doesn’t need to have custom libraries to install / run your software: just download the executable and you’re set.

What Go really does is to bundle together all your *.go files in a single, platform-dependent executable, that can be run with a single click — which works perfectly in 99% of our use cases.

All of this seems great, until you have to bundle different kind of files in your application, for example an .yml config file or an .xliff translation file.

How would you approach this? Enter the trick of the year.

The idea

The idea is that you can create a go source file which contains all of the non-go files you need to bundle, something of this sort:

package somethingfunc GetAssetContents(string asset) string {
if asset = "file.txt" {
return "1234"
}
if asset = "file.css" {
return "hello { display: block; }"
}
// ...
}

and in your code you can then require those files by just doing GetAssetContents("file.txt"); when doing a go build, then, all of your assets will be “included” in your final binary.

Enter go-bindata

Now, you could argue that writing code like this isn’t ideal, and that is true — that is why you’ll find go-bindata useful, as it generates all of the code automatically:

go get jteeuwen/go-bindata
echo "1234" > sample.txt
go-bindata -pkg something -o sample.go ./sample.txt

and here’s the result: as you can see, go-bindata generated a new go file under the package something, and it embedded the contents of sample.txt in it.

To access the contents you now just have to import your module and call the Asset function:

import (
"github.com/you/library/something";
"fmt"
)
func main () {
fmt.Println(Asset("sample.txt")) // 1234
}

Pretty neat, eh?

I wrapped all of this together in a github repo, where you can see the asset and how it can be included in go code with go-bindata: this is something I had to do in one of my libraries, touchy, and that I automated through a Makefile (no go-generate for me, too lazy :)).

PS: on a side note, have you heard of nexe? It’s a compiling tool for node, which seems to alleviate the pain of distributing node executables.


Originally published at odino.org (30 June 2016).

Alex Nadalin

Written by

CTO at @NamshiDotCom, I like distributed systems, Golang, NodeJS, scalability, software design and µseconds. Writing https://leanpub.com/wasec :wq

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade