I put together a simple static file server in Go - useful for local testing of web applications. Check it out at https://github.com/eliben/static-server

If you have Go installed on your machine, you don't have to download anything else; you can run:

$ go run github.com/eliben/static-server@latest

And it will start serving the current directory! Run it with -help for usage information. No configuration files needed - the default is useful and you can adjust it to your needs using command-line flags.

Obviously, you can also install it once with:

$ go install github.com/eliben/static-server@latest

And then just invoke static-server if your PATH is properly set up.

Why

When developing web applications locally, for basic test cases we can open an HTML file directly in the browser (using the file:/// scheme). However, this is sometimes insufficient, and in several scenarios it's necessary to properly serve the HTML (along with its JS and CSS). Some cases where I encountered this are web applications that use at least one of:

  • Web workers
  • Web sockets
  • WASM
  • Separate API servers, requiring CORS
  • Loading ES modules from separate files

In the past, when I was more active in the Python ecosystem, I used python -m SimpleHTTPServer <port> quite a bit. While it's nice, it has some issues too: it's not very configurable, and it requires Python to be installed.

Another option I've used is http-server from the Node.js ecosystem; in fact, it has served as the inspiration for static-server. You can run it with npx without installing, and it's also configurable through command-line flags, without requiring configuration files.

But we can't expect all Go developers to have npm or npx installed. Moreover, sometimes you want to tweak the server a bit and digging in JavaScript is not any Go programmer's idea of a good time. Like many tools in that ecosystem, this Node.js-based HTTP server is all in on dependencies - with 13 of them, it's not easy to understand or modify its code; much of it is split across multiple helper packages, and making changes can be tricky.

How

Spinning up a static file server in Go is very easy - I wrote a whole blog post about the possibilities at some point. The simplest static server to serve the current working directory is just:

package main

import "net/http"

func main() {
  port := ":8080"
  handler := http.FileServer(http.Dir("."))
  http.ListenAndServe(port, handler)
}

Having found myself plopping a small server.go with these contents in too many web projects, I decided enough was enough. Thus static-server was born.

static-server is simple, yet versatile. It will do the right thing by default, with no flags whatsoever. But you can also use flags to configure a few aspects, e.g.: the port it serves on, CORS support, serving via TLS, control how logging is done.

static-server is hackable and easy to understand. All the code is in a single file (with fewer than 200 lines of code, including comments and handling flags) and there are no dependencies (except one package that is only used for testing).

I find static-server very useful, and I hope others will too. If you run into any problems or have questions, open a GitHub issue or send me an email.