[HN Gopher] Show HN: Gomponents, HTML components in pure Go
       ___________________________________________________________________
        
       Show HN: Gomponents, HTML components in pure Go
        
       Hey everyone! I just released v1.0.0 of gomponents last week. It's
       an HTML component builder in pure Go, with a DSL-like HTML syntax.
       It's been 4 years in the making, and makes it really easy to build
       HTML in your web apps.
        
       Author : markusw
       Score  : 98 points
       Date   : 2024-10-15 11:56 UTC (3 days ago)
        
 (HTM) web link (www.gomponents.com)
 (TXT) w3m dump (www.gomponents.com)
        
       | floydnoel wrote:
       | are event handlers possible? neither the Github repo nor the
       | linked page showed an example of a button or form submission.
        
         | burgerrito wrote:
         | This is basically a HTML templating library. It's server side
         | only. Or do you mean event handlers in the HTML attributes?
        
         | tomhallett wrote:
         | If you mean "action=/foo" for a "form" tag, there is an
         | "Action" attribute:
         | https://github.com/maragudk/gomponents/blob/main/html/attrib...
        
           | markusw wrote:
           | The OG event handler. :D
        
         | _heimdall wrote:
         | It looks like this is focused on server rendering HTML, no
         | client-side runtime or anything like that.
         | 
         | I don't see any used of a `Script()` function or similar in the
         | example apps, though you could always chunk some JS in a public
         | directory and link it in the HTML.
         | 
         | They do have a starter example that uses HTMX. That'd be my go-
         | to as well for a tool that's sticking with server rendering
         | HTML.
        
           | markusw wrote:
           | Yep, this exactly. And the starter kit mentioned is here, for
           | anyone curious: https://github.com/maragudk/gomponents-
           | starter-kit
        
         | markusw wrote:
         | gomponents is just a glorified string builder, so it's more or
         | less like writing HTML in Go that gets output from the server.
         | So you put event handlers on your elements like you normally
         | would, write scripts and include JS like you normally would,
         | etc.
         | 
         | That said, there's gomponents-htmx [0] for easy integration
         | with HTMX.
         | 
         | [0]: https://github.com/maragudk/gomponents-htmx
        
       | dgraph_advocate wrote:
       | Awesome, now do it in Haskell!
        
         | kccqzy wrote:
         | There are at least two generations of libraries doing that in
         | Haskell. There was blaze-html and then lucid afterwards to fix
         | some monad laws.
        
           | kreetx wrote:
           | There was also was WASH[1] way before blaze.
           | 
           | Given the minimal syntactic overhead and the do-syntax
           | overload/Monad type class, Haskell is a great language to do
           | these embedded DSLs in.
           | 
           | [1] http://www2.informatik.uni-freiburg.de/~thiemann/WASH/
        
         | markusw wrote:
         | I wrote the "Go is my hammer and everything is a nail" post
         | circulating a while back, so unfortunately I can't do that. :D
        
       | flashgordon wrote:
       | So I like the idea of it but am feeling a bit wary about UI
       | elements as runtime types. Good thing about this is the strong
       | typing but then you have a fair bit of lispifying going on which
       | I swing back and forth on. I actually like templ's approach on
       | this (though hate the extra build step). So I finally just
       | settled on plain old go templates. Not quite eloquent but just
       | feels staple and simple. Clearly a lot of get off my lawn type of
       | biases here :)
        
         | OccamsMirror wrote:
         | I agree with you, but I like Gomponents over html templates due
         | to the type safety. It's also easier to reason about with. Some
         | of my html templates can get quite difficult to maintain, with
         | often the context not being obvious.
        
           | flashgordon wrote:
           | Totally. I am also in this journey where I keep going back
           | and forth between templates and something typed. I really
           | need something like native jsx inside go. Gosx anybody?
        
             | markusw wrote:
             | Isn't that basically Templ [0] then? But Templ has that
             | extra build step for preprocessing and converting back to
             | plain Go files.
             | 
             | For me, gomponents is the middle ground. You don't get
             | everything, but quite a lot of JSX-like feel. I was
             | inspired by JSX after all. :) [1] Although I called it GOX
             | back then... :D
             | 
             | [0]: https://templ.guide [1]:
             | https://www.maragu.dk/blog/gomponents-declarative-view-
             | compo...
        
           | markusw wrote:
           | I started with html/template, but got fed up with it because
           | I thought it was so hard to pass data around to different
           | components. I don't know, I just didn't jell with it.
        
       | burntcaramel wrote:
       | That's awesome! I have a very similar project Dovetail, that
       | tries to nudge you into making things accessible.
       | 
       | https://github.com/RoyalIcing/Dovetail
        
         | markusw wrote:
         | I hadn't seen that one yet, I'll check it out. :-)
        
       | burgerrito wrote:
       | Looks cool. There is also Templ[1] that does something similar,
       | though uses codegen.
       | 
       | I wish there is an equivalent of Storybook for these things
       | though, it would be really nice!
       | 
       | [1] https://templ.guide/
        
         | markusw wrote:
         | What's Storybook? Could you elaborate?
        
           | Brajeshwar wrote:
           | Not the OP but I think he meant the one at
           | https://storybook.js.org
        
             | markusw wrote:
             | Oooh, that looks cool. Thanks!
        
       | jerf wrote:
       | While acknowledging the use case of "the designer who doesn't
       | know how to program" and the desirability in some sense of
       | separating logic from data, if I am going to slam together some
       | HTML as a programmer, with no "non-programmer" designer in sight,
       | I tend to slap together a local version of templates like this if
       | I can't find a good one available. The reason is, if I'm going to
       | mix logic and presentation anyhow, why bother with a template
       | library that is basically an inner-platform, when I can just use
       | the programming language itself? Then you get other integrations
       | as useful, e.g., do you have some concept of
       | interfaces/traits/whatever? Define a useful default
       | representation for something and you can push it straight out in
       | a template. This may not work for large UI elements, but in terms
       | of "hey, here's how you display a Username in general" it can be
       | useful, and it's not like you're stuck with _only_ that way of
       | rendering an object.
       | 
       | Closures, modules, functions, loops or recursion, conditionals,
       | every feature of your programming language just right there,
       | without some large templating library in the way. Debug your
       | templates with the actual debugger. Very high performance with
       | just a bit of care in the API design. Every programmer in your
       | language can pick this up very quickly with hardly any effort and
       | doesn't have to learn yet another complete templating language to
       | start using your project, it's just comparable to picking up an
       | API.
       | 
       | So many advantages... it's just... you _have_ to be programmer if
       | you want to modify the resulting code. Other than that, and I
       | guess the fact you need to implement whatever discipline you may
       | want on your own[1]... but those are a total killer in many
       | cases.
       | 
       | [1]: This approach does not _require_ that you mix presentation
       | and logic, but if you want that separation, you will need to
       | discipline yourself to maintain it. Though I have to admit, 25
       | years of programming on the web and I 'm frankly still
       | unconvinced by this argument, or, at least, unconvinced that it
       | is the absolute most important thing in every context and only a
       | cretinous lunatic would _dare_ mix logic and presentation. It
       | seems to me to be a rule espoused by far more people than it is
       | followed by.
        
         | markusw wrote:
         | I'm really curious whether this will hold true in the future. I
         | think the whole JS/React/JSX ecosystem really got a lot of
         | people over to the programming side from "just" writing HTML
         | and CSS, and I'm wondering whether this could happen for
         | something like Go, too.
         | 
         | Now that the pendulum has swung in favor of rendering HTML
         | server-side again and sprinkling Javascript on top, I sense a
         | lot of interest in different ways of doing things than the
         | default backend + JSON HTTP API + React/Vue frontend stack. And
         | because Go is such a relatively simple language, maybe purely
         | frontend/design-focused developers can pick it up and start
         | writing HTML components with it?
         | 
         | (It helps that my preferred style of putting all HTML
         | components inside a package called "html" inside the Go
         | module/app could neatly containerize newcomers, to not scare
         | them off with all the other stuff that is a Go app.)
        
         | kccqzy wrote:
         | Exactly. EDSLs are underrated.
        
       | markusw wrote:
       | Hey all! Sorry for being late to the party. I posted this on HN
       | earlier this week, and only just saw it pop up here. I'll hang
       | around today and try to answer questions and comments. :) I'm in
       | the CEST timezone.
       | 
       | You may also be interested in the "go podcast()" episode I was in
       | earlier this week, talking about gomponents with Dominik:
       | https://gopodcast.dev/episodes/045-gomponent-with-markus-wus...
        
       | icy wrote:
       | Similarly, for Templ/Tailwind/AlpineJS components, I've recently
       | found https://goilerplate.com.
        
         | markusw wrote:
         | Nice! Maybe I should build a small adapter so Templ components
         | can be used with gomponents.
        
       | cynicalsecurity wrote:
       | This is a horrifyigly bad idea.
        
         | markusw wrote:
         | :D
        
         | majewsky wrote:
         | Another horrifyingly bad idea is to make a comment like this
         | without presenting any form of argument.
        
       | brody_slade_ai wrote:
       | Not sure about this one but will give it a try. By using a custom
       | element and enhancing it with JavaScript, I was able to create a
       | component that rendered quickly and seamlessly
        
         | markusw wrote:
         | Yeah, give it a try! It's weird at first but grows on you IMO.
        
       | kubb wrote:
       | I saw the dot imports and thought "What a neat feature! I wonder
       | why nobody uses it." Then I googled it and saw a million articles
       | saying how they should be avoided and removed from the language
       | because they make code more difficult to understand.
       | 
       | Typical gophers, can't accept that there's a time and place for
       | everything and need to have a hard rule to use that applies to
       | every single situation. Imagine that code, but with
       | gomponents.Ul, gomponents.Li, gomponents.Div everywhere.
        
         | markusw wrote:
         | Yeah, the dot import made the whole thing click for this
         | library. It's the only use case I found for it so far though.
         | :D
         | 
         | Fun fact: I got the idea from an episode of the GoTimeFM
         | podcast, where the hosts and guests were discussing features
         | they would like to see removed from the language.
        
         | arccy wrote:
         | the import is html not gomponents, which imo is fine
        
         | ofrzeta wrote:
         | It's the same with the Ginkgo testing library: "After the
         | package books_test declaration we import the ginkgo and gomega
         | packages into the test's top-level namespace by performing a .
         | dot-import. Since Ginkgo and Gomega are DSLs this makes the
         | tests more natural to read."
         | 
         | https://onsi.github.io/ginkgo/
        
         | js2 wrote:
         | > (Some people don't like dot-imports, and luckily it's
         | completely optional.)
         | 
         | You can rename imports to whatever you like, but the default
         | name for the package that contains the HTML elements is `html`,
         | not `gocomponents`.
        
       | hn6000 wrote:
       | This reminds me of Lucky Framework for Crystal
       | 
       | https://luckyframework.org/guides/frontend/rendering-html
        
       ___________________________________________________________________
       (page generated 2024-10-18 23:02 UTC)