Building Reusable Web View Components in Pure Go: Markus Wüstenberg

One of the things anyone notices about Go is the built-in HTML templating support provided by the standard library. Not surprisingly, the advice one often hears from Go community members is to just “use the standard library.” The same applies to using templates - if the standard library provides templating support out of the box, do we need to search for alternatives?
Personally, I believe we should. While the standard library provides templating support, it is rudimentary and requires a bit of tweaking before productive work becomes more enjoyable. It gets 75-80% of all tasks well enough, but the remaining edge cases are often painful enough that I have been on the hunt for a better solution many times. And while there is a whole list of 3rd-party templating engines, none of it solves the core problems:
- How do I turn everything into reusable components?
- How can I ensure the safety of the data I pass to templates?
- How can I avoid learning a new syntax every time?
Not surprisingly, many teams move towards building single-page applications not because they need the added interactivity but because the tooling and templating support are better. If only there were a way to achieve the same ease of building React components but using pure Go. Well, it turns out there is!

What is gomponents?
gomponents is a library that makes it easy to build view components using pure Go. A Go component is nothing more than a plain Golang function that takes some inputs and returns a Node instance.
func Navbar() g.Node {
return Nav(Class("navbar"),
Ol(
Li(A(Href("/"), g.Text("Home"))),
Li(A(Href("/contact"), g.Text("Contact"))),
Li(A(Href("/about"), g.Text("About"))),
),
)
}
The library offers an entire array of HTML elements that we are all familiar with in the form of helper functions. Thus, as developers using gomponents, we can start building our UIs immediately. Best of all, it is all Go code, so we won’t need to worry about learning yet another syntax or that the language doesn’t allow us to implement a complex scenario.
If the example above reminds you a tiny bit about React or Flutter, it is because those inspired my guest Markus Wüstenberg to build gomponents.
Tell us a bit about yourself. Who is Markus?
Hey, I’m Markus! I’m an independent software consultant working with various web and cloud technologies, Go being a central tool in that. I also build Go courses for developers who want to learn how to do what I do and make open-source tools mainly for the Go community. In my spare time, I play with modular synthesizers and my newly acquired theremin. The latter I’m still ridiculously bad at, but it’s fun!
How did you come to Go?
I used to work on storage infrastructure at Uber. One of my colleagues introduced us to this new-ish language called Go, which he had been prototyping with over the weekend, and had seen some dramatic performance improvements in benchmarks compared to our Python solution to the same problem.
Initially, I wouldn’t say I liked the language too much. It seemed verbose and sort of hacky (letter casing determines identifier visibility?!). But after a project I was on needed a new component, and we could choose between Java and Go, and we ended up choosing Go, I became pretty hooked. The relative simplicity did it for me.
How did gomponents come to be?
I was using html/template
for a static site generator project (yes, the world needed another one). I had to get used to the syntax, but it was okay, so I started building my components. Passing data between components was a pain and sometimes impossible, depending on what I was trying to send, so I started thinking about other solutions.
The API went through a lot of iterations before it felt right, but when I put all helper functions into one package and learned about dot imports, it clicked for me, and I’ve been using the library since.
Do you plan on extending the library for production use?
I use it in production all the time. I’m a big fan of radically cutting down on complexity, so I can focus on solving business problems instead of plumbing problems. I’ve pretty much dropped using Javascript SPAs with API glue code in between. I now render my HTML server-side and deliver it to clients, old-school style.
When I need something else, I reach for HTMX or plain Javascript. Combined with deploying to an edge close to users, this gives an incredible user experience. And I’m super productive!
Gomponents could benefit from people trying it and building tools and components that raise the level of abstraction. Sort of what React has with its great component ecosystem.
What is a major challenge for adopting gomponents more widely?
I honestly think it’s a question of discovery. There’s clearly a demand for generating HTML in Go, and gomponents is pretty easy to get started with. Of course, taste factors into that decision (dot imports are not to everyone’s liking). But if the ecosystem of components were bigger, it would make the decision easier. There are other libraries that do more or less the same, with slightly different syntax, so it would just be really cool if the community decided on one of them and ran with it.
Other than that, you might be coming from an existing project with components written in another templating language or pure HTML, and it can take a while to convert all that to gomponents. Luckily, you can just gradually adopt gomponents and plug them in where it makes sense. Or use the Raw helper function, pass some raw HTML back, and use string interpolation for your data. It’s not pretty, but it works. It’s on my wish list to create converters from various other languages to gomponents, but that wish list is pretty long, so I don’t know if I’ll ever get around to it.
And sometimes, you just need an extra bit of interactivity where a full-page refresh in the browser just won’t do. In those cases, I reach for HTMX or other tiny Javascript helpers, as already mentioned. People are even building gomponents+HTMX libraries! And I’m thinking of making an official one.
You also teach a course on building Go applications for the cloud. Tell us more about it.
I do! I wanted to build a course that focused on using Go to build web applications in the cloud, using the cloud building blocks available (think: deployed to containers, managed SQL databases, object stores/S3, managed message queues, and more).

It's almost insane (in a good way!) how much one can accomplish with some good tools—such as Go and a cloud ecosystem—with relatively little money and some focused development. And I wanted to show other developers how well Go fits into that story. So, if you're curious about Go and deploying apps to the cloud, check it out.
Feel free to write to me directly with any questions you might have. I'm reachable at markus@maragu.dk and on Mastodon at @markus@hachyderm.io.