Show HN: gomponents, HTML components in pure Go (gomponents.com)

15 points by markusw ↗ HN
Hey everyone!

I’ve built gomponents over the past couple of years because I wasn’t satisfied with using templating languages in Go.

In particular, it was really hard to pass data around when using stdlib html/template, and it just didn’t sit right with me.

Using just Go, you get so much for free from the language, and building HTML components becomes much easier, I think.

The way you use it basically looks like using a DSL, but it’s not! It’s using the often-disliked but occasionally useful dot import mechanism of the language. This way, there’s full autocompletion built right in if your editor supports Go.

Anyhoo, I hope you find some use in it. I know a lot of people already do. :) Enjoy!

PS: There's gomponents-htmx as well. The two work really well together.

6 comments

[ 2.7 ms ] story [ 10.2 ms ] thread
Oh hey, I wrote something similar as part of a web framework (https://github.com/gospel-sh/gospel), not officially released yet as I’m working on reactive client-side rendering and a few other things.
Cool! What does reactive client-side rendering mean in this context? That state changes are pushed from the server?
Yeah but also that you can load data to the client and then have components react to it just like you would do with a regular frontend framework.
This looks neat!

What's the performance like? I thought about trying to build something similar but I figured performance would be awful if it was based on naive string appending. I presumed GC would dominate the runtime from allocating a thousand copies of half an HTML doc.

Does this do any kind of memo-ization/caching? That's where I ultimately wanted to end up. I wanted the Page to use generics to pick a struct for the parameters used in building the HTML, and then maintain a cache mapping hashed inputs to already-built output. I never decided whether it was better to memo-ize the whole page as a template or memo-ize just the components so it could do partial re-renders. It's ideologically very similar to React

Honestly, I don't know. I've never measured because it's never been a problem. Most of it is writing string literals to an io.Writer, no idea what the overhead is there. Could be fun to write some benchmarks. :)

With regard to caching, I think I would opt for a solution at a different layer. For example, render the page and just cache the output in memcached, Redis or similar. Or just in memory maybe. As always, it depends.

> With regard to caching, I think I would opt for a solution at a different layer. For example, render the page and just cache the output in memcached, Redis or similar. Or just in memory maybe. As always, it depends.

I totally get that, it is dramatically simpler and it probably does well enough for most things.

My theory was that you can effectively cache parts of a page, and then build pages out of the cache. Like if my page relies on a user ID and some kind of "is logged in" boolean, the "is logged in" parts have probably already been rendered before so we only have to dynamically render the parts that rely on this user ID (presuming we haven't seen this user ID and cached those parts already).

Caching the whole page requires rendering both the user ID and the "is logged in" part, because it caches over the totality of the parameters.

Now that I'm writing this out, it does seem a touch excessive lol. It's kind of like server side React, but I'd probably rather push that processing onto the client device because I don't pay for their CPU cycles.