[HN Gopher] Show HN: htmgo - build simple and scalable systems w...
       ___________________________________________________________________
        
       Show HN: htmgo - build simple and scalable systems with golang +
       htmx
        
       Hey all, I just wanted to share a project I've been working on for
       the past month.  After years of heavy frameworks, I really like the
       idea of using htmx, but it's a little too low level for me and
       needs a thin layer above it to facilitate things like components,
       better syntax with complex JS inside of an attribute, etc  To try
       and solve this problem with a very minimal stack (golang + htmx)
       that I've been really enjoying, I'm building this project to cater
       to my needs and was thinking it would be useful for other
       developers.
        
       Author : maddalax
       Score  : 152 points
       Date   : 2024-09-28 21:34 UTC (1 days ago)
        
 (HTM) web link (htmgo.dev)
 (TXT) w3m dump (htmgo.dev)
        
       | DLA wrote:
       | This is useful! Love the Go & HTMX combination and use it often.
       | Good documentation too for an alpha release. Nice work.
        
       | ilrwbwrkhv wrote:
       | Beautiful! I don't use Go anymore (moved to Rust) but this looks
       | pristine.
        
         | sureglymop wrote:
         | I love web dev using rust! I use sveltekit and proxy all
         | requests to /api to a rust backend (though it works with any
         | SSR framework). This is nicely configurable for the vite dev
         | server. Then I basically have all the business logic on the
         | rust side and all the presentation logic on the SSR side to get
         | the best of both worlds. This gives me two things:
         | 
         | 1. A development experience with instant visual feedback for
         | the frontend. Even more so when using tailwind.
         | 
         | 2. A stable, safe and performant backend.
         | 
         | The downside is that a node process has to be running and doing
         | the ssr, though that is an okay trade off for me because my
         | project is mainly the api, having a reference implementation of
         | the frontend is just a nice extra.
         | 
         | I've also experimented with implementing the reverse proxy in
         | rust itself and using a unix socket and other IPC mechanisms to
         | push the data to the SSR layer.
        
           | klabb3 wrote:
           | > I love web dev using rust! I use sveltekit and proxy all
           | requests to /api to a rust backend
           | 
           | I think this most people would call this backend-, api- or
           | service development. Especially if your api endpoint does not
           | do anything web specific except http.
           | 
           | Anyway, how do you share types between the backend and
           | frontend? Are you rawdogging json?
        
             | j45 wrote:
             | Rust could probably generate the HTML.
        
       | OccamsMirror wrote:
       | htmx + Templ (https://templ.guide/) is something I'm really
       | enjoying as a replacement for React in my personal projects.
        
         | maddalax wrote:
         | I do also like the idea behind templ, only issue is when I
         | tried to use it, the DX was pretty poor on Jetbrains IDE's. I
         | think the LSP is broken for it
        
           | chabad360 wrote:
           | That's actually something I've been slowly working on.
           | There's a bug in the go parser tho that kinda slowed things
           | down a lot.
        
           | kosmozaut wrote:
           | I'm kind of in the same boat (but with VSCode). In addition
           | to that, I found that it didn't make things too much easier
           | than something like MVC with built-in template/html. The
           | context integration seems like a huge footgun, since it just
           | panics if you access a value that doesn't exist.
        
           | jonathrg wrote:
           | There is definitely a problem with the LSP. I've resorted to
           | turning off the templ extension in VS Code, syntax
           | highlighting and all.
        
       | sublinear wrote:
       | "Scalable", but does it scale in terms of business requirements
       | typical of web projects?
        
       | tanduv wrote:
       | The example TODO app doesn't seem to be doing so well
       | https://todo-example.htmgo.dev/
        
         | maddalax wrote:
         | lol looks like I forgot to limit the user input length,
         | clearing those now...
        
           | maddalax wrote:
           | someone decided to ddos it with profanity so I'm pushing an
           | update now so its not global viewable anymore.
        
             | lnxg33k1 wrote:
             | I would have paid extra for free profanity, consider to
             | offer it as an addon
        
       | winrid wrote:
       | Reminds me of https://j2html.com
       | 
       | Which I have also been starting to use for one project, with
       | quarkus, been a nice experience so far.
        
         | thwg wrote:
         | j makes me shudder. But thanks for sharing.
        
           | winrid wrote:
           | haha, to be fair my Java code is more like Go than typical
           | Java. I should probably try Go someday.
        
         | mattgreenrocks wrote:
         | Have you tried Renarde and Qute?
        
           | winrid wrote:
           | Yes. My concern is the template compilation will get really
           | slow or the custom IDE integration will get out of date and
           | break.
        
             | mattgreenrocks wrote:
             | It will suggest a tweak to config if it sees live reload
             | times going past 4s. That seems to help a lot on my 2019
             | MBP.
             | 
             | I hear you on point #2 though. The Red Hat IntelliJ plugin
             | for that seems janky to me. And JetBrains own plugin
             | doesn't seem great either. In fact I don't know if I've
             | ever seen autocomplete in a Qute template ever.
             | 
             | Shame, because the rest of the stack is so damn good.
        
               | winrid wrote:
               | > It will suggest a tweak to config if it sees live
               | reload times going past 4s
               | 
               | No I mean, I can tell it _will_ get slow, haha.
               | 
               | > the rest of the stack is so damn good.
               | 
               | I agree! (so far, I think)
        
         | jacques_chester wrote:
         | Also Gomponents, a similar project for Go:
         | https://www.gomponents.com
        
       | anonzzzies wrote:
       | These things are really nice and I enjoy using them very much,
       | but we depend now so much on shadcn and ready made templates on
       | top of that; almost all of those are react (and next). The world
       | needs far more open source (fully, not those 'pay to a for all
       | the useful components and templates'; not because I don't want to
       | pay, but because of the licensing; we reuse all things
       | internally, so 1-site license etc are just not options)
       | html/tailwind, htmx, htmgo, clog etc templates with components.
       | 
       | edit: typo
        
       | anonzzzies wrote:
       | I find, for a little extra productivity, that liveview [0] even
       | adds a bit more effortless building personally. No plumbing
       | endpoints is great with all written in Go.
       | 
       | [0] https://github.com/canopyclimate/golive
        
         | kitd wrote:
         | Looks nice. I've tried (a couple of times) to build something
         | similar to this, and to OP's project, but it's never worked
         | out. Golive looks the nearest to the ideal in my head.
        
       | ocean_moist wrote:
       | Backend devs rejoice as they can now build dashboards without
       | leaving go.
        
       | 2024user wrote:
       | Without touching JavaScript but now you have to type
       | 
       | return h.NewPage( h.Div( h.Class("flex gap-2"), h.TextF("the
       | current time is %s", now.String()) ) )
       | 
       | To me that is horrible.
        
         | maddalax wrote:
         | Well when you put it all on one line it doesn't look great :)
         | 
         | With it properly spaced out and nested, after a few days it
         | started reading exactly like HTML to me, where I can quickly
         | see the hiearchy
        
           | snorremd wrote:
           | As a developer who has worked extensively with React and
           | Reagent (a ClojureScript wrapper around React) I actually
           | enjoy this kind of syntax. Better that then some custom HTML
           | templating syntax I need to learn in addition to the
           | language.
           | 
           | It doesn't look too bad if one also break the code into
           | multiple functions to make "layouts" and "components".
           | 
           | I have had lots of fun building with Bun, ElysiaJS, and HTMX.
           | Might test your go library out as well. Looks pretty neat.
        
             | maddalax wrote:
             | Awesome, yeah those are pretty nice technologies.
             | Definitely let me know if you do / encounter any issues!
        
         | j45 wrote:
         | Everything doesn't have to be for everyone, and that doesn't
         | make it bad.
        
           | sitkack wrote:
           | This attitude would stop over 50% of disagreements.
        
             | j45 wrote:
             | and.. piss off another group who get their validation
             | externally by evangelically putting down the technological
             | choices of others.
             | 
             | Prejudice may not be in social areas but the same behaviour
             | of prejudice is alive and well in justifying your own or
             | denigrating someone else's technology choices.
             | 
             | Same folks aren't willing to be open to what is new to them
             | in a new framework is still a 20 year old thing.
        
         | hadthischat wrote:
         | You still type out code? My toolkit is endless generators and
         | macros.
         | 
         | I suppose bike shedding still matters to people who see
         | themselves as Hemingway not an engineer
        
           | bilekas wrote:
           | This is not right, there's nothing wrong with typing out
           | code. Generators are fine, until they're not.
           | 
           | > I suppose bike shedding still matters to people who see
           | themselves as Hemingway not an engineer
           | 
           | This is anything but bikeshedding.
        
       | seumars wrote:
       | How is htmx low level?
        
         | maddalax wrote:
         | Low level in the sense that it doesn't have things you would
         | traditionally need to build an application, such as re-usable
         | components, conditional rendering, etc. To do that you have to
         | wire it up with something else such as your backends templating
         | system, alpine, etc.
        
       | smallerfish wrote:
       | Kotlin is a great fit for this - it has an html dsl library
       | called Kotlinx.html, which works alongside HTMX fantastically.
       | And, you can write a kotlinjs frontend chunk for anything
       | additional you need that HTMX isn't a great fit for. I built a
       | framework for my own use that has typesafe routing & SQL. It's a
       | thing of beauty.
        
         | maddalax wrote:
         | that looks nice, I've enjoyed Kotlin when I used it in the past
        
         | andy800 wrote:
         | Kotlin is indeed a great backend to pair with HTMX. However I
         | find jte.gg templating superior to kotlinx.html's awkward
         | syntax. You still benefit from working with native Kotljn
         | objects inside the templates. Check it out!
        
       | jasonlotito wrote:
       | I remember the days when one of the complaints about PHP was
       | people mixing PHP and HTML together. And no, it was mixing PHP
       | and HTML together. That's it. Don't try to tack on anything else
       | to the conversation. And we've been going back to it for some
       | time now. This doesn't even map to HTML naturally!
       | 
       | I'm mean fine have fun with your libraries but the amount of
       | excitement for something like this? Amazing.
        
       | novoreorx wrote:
       | Welp, another fasthtml project. I still don't understand the idea
       | of reinventing HTML in another language. It's too restrictive and
       | will never be as compatible as JSX.
       | 
       | Don't get me wrong, I love HTMX, I just don't want to write DSL
       | to generate HTML. IMO a backend language should integrate HTMX
       | similar to how https://hotwired.dev/ works.
        
         | bilekas wrote:
         | > IMO a backend language should integrate HTMX similar to how
         | https://hotwired.dev/ works.
         | 
         | Turbo stimulus and Strada..
         | 
         | HTMX... Nothing. Just serve it however you feel. In the posts
         | case, they decided to add some tight coupling with go, while
         | not for everyone, is not really a framework.
         | 
         | I appreciate go server for really lightweight banal sites or
         | even light services and htmlx is quickly becoming my new
         | favourite markup. I will say this project isn't for me, but
         | casting it as just another 'fasthtml' project is a bit far off
         | the mark.
        
           | imacrayon wrote:
           | I actually created https://alpine-ajax.js.org for this
           | reason. HTMX and Hotwire both have opinionated requirements
           | around the content and status codes that your server returns.
           | One of the goals with Alpine AJAX is you should be able to
           | drop it into any basic CRUD app and have it working without
           | changing any server code.
           | 
           | HTMX for example requires that a successful form submission
           | respond with a 200 status, but many applications (most?) will
           | 302 redirect to a new page to prevent duplicate form request
           | on refresh.
        
             | maddalax wrote:
             | This is very cool, I like the website too
        
         | gwd wrote:
         | > I still don't understand the idea of reinventing HTML in
         | another language.
         | 
         | I switched from using golang templates with hand-crafted HTML
         | to gomponents[1] a few months ago, and it's been amazing. It is
         | _so so so_ much easier to write re-usable components, so much
         | easier to express complicated conditionals, so much nicer to
         | have a type checker helping you not make mistakes.
         | 
         | And of course I like gomponents for the same reason (I presume)
         | JS-oriented people like NodeJS: It's just a lot nicer to have
         | as much as possible written in the same language, be it
         | JavaScript or Golang.
         | 
         | [1] https://www.gomponents.com/
        
       | breadchris wrote:
       | I love this! I have been working on something similar recently
       | [1] and it is exciting to think about the possibility of building
       | full stack components for the web that are not going to break in
       | the foreseeable future. Even if I need to swap
       | languages/frameworks go is easy to parse and transpile!
       | 
       | I dream of a library like ours to take on the likes of React, and
       | to get there the devex needs to have some key features. Most
       | notably, imo, is live reload. You could use air, but I find it
       | still to be too slow to recompile the entire app. I have had some
       | success so far with yaegi to interpret the go at runtime [2]. It
       | isn't perfect, but the full language spec is implemented.
       | 
       | My personal goal is to build the Go equivalent of rails/django.
       | Live reloading is needed in addition to plugins that provide web
       | app primitives (auth, storage, logging, metrics, etc).
       | Additionally, I think the network effect of React is a powerful
       | value driver, so some easy way to include React in an app is also
       | important. Thankfully evanw has made this trivial with esbuild
       | [3]
       | 
       | [1]
       | https://github.com/breadchris/share/blob/master/html2/html.g...
       | [2] https://github.com/traefik/yaegi [3]
       | https://github.com/breadchris/share/blob/master/graph/build....
        
         | maddalax wrote:
         | Haha we kind of have the same vision. That's eventually what I
         | want to turn htmgo into, something like rails, but as minimal
         | as it can be (essentially plugins, good defaults but you can
         | opt out).
         | 
         | > You could use air, but I find it still to be too slow to
         | recompile the entire app.
         | 
         | At the moment I'm using fsnotify to watch file changes and
         | restart the process immediately, so far it hasn't been too bad
         | for live reloading. I'm hoping as long as precautions are taken
         | to lazy load things on startup, then it would stay fairly
         | quick.
        
           | hilti wrote:
           | 15 years ago I created a web framework for newLISP. It even
           | ran fast on a Nokia N900
           | 
           | Maybe you want to have a look at the code and get some
           | inspiration.
           | 
           | https://github.com/taoeffect/dragonfly-newlisp
        
         | maddalax wrote:
         | yaegi is very interesting... I'm going to see if I can get it
         | working on htmgo for reloading the views.
        
           | breadchris wrote:
           | I would take a look at this demo [1]. Pay close attention to
           | what is being interpreted vs bound as a symbol to compiled
           | code. The `yaegi extract` command will not work on exported
           | generics atm.
           | 
           | If you want to collab more, shoot me an email:
           | chris@breadchris.com
           | 
           | [1] https://github.com/DCjanus/yaegi_demo
        
       | politician wrote:
       | Template functions are a better approach, IMO.
       | 
       | [1] https://templ.guide/
        
       | TripleChecker wrote:
       | interesting idea, can it be used with Gin or any other Go web
       | framework - or is that not just the html templating library but a
       | framework on its own?
       | 
       | There were a few typos in the docs page:
       | https://triplechecker.com/s/D32t6y/htmgo.dev?v=HrUfl
        
         | maddalax wrote:
         | Ah good call, I should have checked for typos. Will fix, ty.
         | 
         | The routing uses the std lib + chi, it's fairly integrated into
         | the html builder because the http request needs to be utilized
         | to check specific htmx headers.
         | 
         | I could imagine you could use your own web framework though,
         | since you can wrap the std lib handlers.
        
           | maddalax wrote:
           | Also depending on popularity, I may make other adapters for
           | different go web frameworks
        
       | Terretta wrote:
       | _"Letting a hundred flowers blossom and a hundred schools of
       | thought contend is the policy for promoting progress in the arts
       | and the sciences and a flourishing socialist culture in our
       | land."_
       | 
       | Hand-coding HTML is three decades in, like using computer
       | languages from the 1970s in the 2000s.
       | 
       | There are so many of these experiments the last few years, could
       | any be what replaces HTML5?
       | 
       | If not, why not? What _would_ be enough better? Most likely not
       | just another form of the same.
        
       | 65 wrote:
       | Has there ever been a widely used open source project for writing
       | HTML as functions inside of another language? (JSX and PHP don't
       | count - you're still writing the HTML markup).
        
         | pmdr wrote:
         | Phlex (https://phlex.fun), but I don't know about the 'widely'
         | part.
        
         | librasteve wrote:
         | I have been working on a raku module (HTML::Functional) to do
         | this, as with the OP the main motivation is for me to be able
         | to declutter my own projects, so not widely used, but yes OSS.
         | 
         | Here is an "Elm-like" example from
         | https://elmprogramming.com/building-a-simple-page-in-elm.htm...
         | coded in raku. HTMX is a great lever to put the code on the
         | server - thus Go, Raku, whatever.                 use
         | HTML::Functional;            my $body = body [         div(
         | :class<jumbotron>, [           h1("Welcome to Dunder
         | Mifflin!"),           p  "Dunder Mifflin Inc. (stock
         | symbol{strong 'DMI'})\n" ~               q:to/END/;
         | is a micro-cap regional paper and office               supply
         | distributor with an emphasis on servicing               small-
         | business clients.               END         ]),              p
         | :hx-get<https://v2.jokeapi.dev/joke/Any?format=txt&safe-mode>,
         | "Click Me",       ];
         | 
         | From the module synopsis which means some of the capabilities
         | of the Raku Quoting Slang are in play ...
         | https://raku.land/zef:librasteve/HTML::Functional. Raku
         | functions only need parens for disambiguation btw. Named attrs
         | can use the :name<value> syntax which imo is the tidiest.
        
         | gwd wrote:
         | I dunno how widely used it is, but I've found gomponents[1] a
         | big improvement over golang templates with hand-crafted HTML.
         | 
         | [1] https://www.gomponents.com/
        
       | bugsense wrote:
       | Fresh air
        
       | pmdfgy wrote:
       | I'll defintely give it a try when I can but in the meantime I
       | wanted to congratulate and encourage you for the *simple* and yet
       | very practical website presenting the project. It's so rare
       | nowadays that it deserves it.
        
       ___________________________________________________________________
       (page generated 2024-09-29 23:02 UTC)