I remember when I was starting out; I struggled a lot with what to build.
Especially right after learning a new language!
But I’ve been around for a while now, seen a few things, and learned something important: language is not the barrier anymore.
So in this post, I want to show you four solid fields you can build in using Golang.
But first:
What can you build with Go?
Everything...
but you probably shouldn’t.
Let me explain. Here are 4 recommendations (with tools to get you started):
Web Servers
Desktop Applications
Systems Applications
Terminal UIs
Web Servers
I call Go the infrastructure darling. It's one of the most important and widely-used backend tools out there, e.g Docker, Kubernetes, Prometheus are written in Go!
If you peek into the standard library, you'll see Go was built for backend engineering. It's clean, powerful, and the standard lib already covers a ton.
Here’s how easy it is to spin up a basic http.ServeMux
server:
import (
"log"
"net/http"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/foo", func(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
w.WriteHeader(http.StatusAccepted)
})
log.Fatal(http.ListenAndServe(":3000", mux))
}
And the ecosystem?
Incredible. Thanks to the strong stdlib foundation, you’ve got frameworks that are fast, expressive, and flexible:
1. Gin - speed
Based on a radix tree. Small memory footprint. Zero reflection. Just clean, predictable performance.
package main
import "github.com/gin-gonic/gin"
func main() {
router := gin.Default()
router.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{"message": "pong"})
})
router.Run() // 0.0.0.0:8080
}
2. Echo - For the minimalist with max control
package main
import (
"net/http"
"github.com/labstack/echo/v4"
)
func main() {
e := echo.New()
e.GET("/", func(c echo.Context) error {
return c.String(http.StatusOK, "Hello, World!")
})
e.Logger.Fatal(e.Start(":1323"))
}
3. Beego - The Django of Go
Batteries included. Opinionated. Structured.
package main
import "github.com/beego/beego/v2/server/web"
func main() {
web.Run()
}
Pick your poison. Personally?
I’m a Gin guy.
Desktop Applications
When I say desktop apps, I mean utility software.
Things with a UI that normal users (non-developers) can interact with.
Think: calendars, alarms, to-do apps, simple editors.
You can build two kinds of UIs in Go:
Web UI (wrapped in a desktop shell)
Native UI (fully system-integrated)
Why Web UI?
Web UIs are more design-mature, because the market lives on the web. More users = faster dev = better tools.
So it's now a standard for many utility desktop apps.
I’ve written a full guide on 3 approaches here, but I’ll show you my personal favorite below 👇
WebView (flexible and simple)
Before we start, install the right runtime:
Windows: Webview2
macOS:
xcode-select --install
Linux:
sudo apt install gcc libgtk-3-dev libwebkit2gtk-4.0-dev
Install the Go module:
go get github.com/webview/webview_go
Now the code:
package main
import webview "github.com/webview/webview_go"
var htmlPath = "C:/[absolute path]/index.html"
func main() {
w := webview.New(true)
defer w.Destroy()
w.SetTitle("Webview App")
w.SetSize(600, 420, webview.HintNone)
w.Bind("hello", func() string {
return "Hello from Webview!"
})
w.Navigate(htmlPath)
w.Run()
}
Native UI Libraries
If you want native OS controls, here are two great options:
Fyne
package main
import (
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/widget"
)
func main() {
a := app.New()
w := a.NewWindow("Hello World")
w.SetContent(widget.NewLabel("Hello World!"))
w.ShowAndRun()
}
Gio
func main() {
go func() {
window := new(app.Window)
err := run(window)
if err != nil {
log.Fatal(err)
}
os.Exit(0)
}()
app.Main()
}
func run(window *app.Window) error {
// render loop and widgets go here
}
Systems Applications
This is the deep end, for advanced users.
You’re talking direct kernel interaction via syscalls.
Think:
Containers (hello again, Docker 👋)
Custom kernels
Shared libraries (
.so
,.dll
)
I used this approach to port Charm’s Bubbles to JavaScript via a native .dll
.
If you want a good intro to this world, watch Liz Rice’ talk:
GopherCon 2017: A Go Programmer's Guide to Syscalls
Terminal UIs (TUIs)
These are tools for other developers.
And Go shines here with one of the best ecosystems for TUI dev.
Charm’s Bubble Tea
Elegant terminal UIs made easy.
Want to render Markdown in your terminal?
import "github.com/charmbracelet/glamour"
r, _ := glamour.NewTermRenderer(
glamour.WithAutoStyle(),
glamour.WithWordWrap(40),
)
out, _ := r.Render("# Hello World\nThis is Markdown!")
fmt.Print(out)
And if you're building command-line tools with subcommands and flags?
Cobra is your best friend.
package main
import "yourproject/cmd"
func main() {
cmd.Execute()
}
In Summary
Go is versatile. You can build anything...
But like I said:
You probably shouldn’t.
In this post, we looked at 4 categories of real-world Go applications:
Web Servers
Desktop Apps
Systems Tools
Terminal UIs
Each with its own niche and use case.
So pick your area, and start building.
Got a cool Go library or project you’re working on?
Drop it in the comments, I’m always looking for new stuff to tinker with!
Thanks for reading.