Victor is a full stack software engineer who loves travelling and building things. Most recently created Ewolo, a cross-platform workout logger.
Hot-reload Go applications

In the Node.js world we have nodemon that will watch your sources for changes and can restart your application. Since Go code compiles to a binary, I wanted something similar for my project which was essentially a web server.

In this article we will use ag (a modern grep) and entr, a nodemon like utility which integrates very well with linux and Macos. Both projects are open source and you can check out the respective links for platform-specific installation instructions.

The first step is to create a really basic Makefile:


# Go parameters
GOCMD=go
GOBUILD=$(GOCMD) build
GOCLEAN=$(GOCMD) clean
GOTEST=$(GOCMD) test
GOGET=$(GOCMD) get
BINARY_NAME_PREFIX=radmon
BINARY_NAME=$(BINARY_NAME_PREFIX).exec
BINARY_UNIX=$(BINARY_NAME_PREFIX)-unix.exec

all: test build
build: 
	$(GOBUILD) -o $(BINARY_NAME) -v
test: 
	$(GOTEST) -v ./...
clean: 
	$(GOCLEAN)
	rm -f $(BINARY_NAME)
	rm -f $(BINARY_UNIX)
run:
	$(GOBUILD) -o $(BINARY_NAME) -v
	./$(BINARY_NAME)
deps:
	$(GOGET) github.com/mattn/go-oci8
	
# Cross compilation
build-linux:
	CGO_ENABLED=0 GOOS=linux GOARCH=amd64 $(GOBUILD) -o $(BINARY_UNIX) -v

Once the Makefile is setup we can now run commands like make test and make run to test, build and run our application. The final step is to filter files using ag and use entr to watch the filtered files for changes and re-run the provided command. Here's an example run-dev.sh script:


#!/bin/sh
ag --go --json -l --ignore-dir=ui | entr -r -s "make run" 

While I prefer this setup as it is very simple, there also exist task runners (all written in Go itself) that provide live reloading and come with Windows support:

If you do try the above feel free to get in touch regarding your experience. Happy Go coding!