Live data from Hacker News

Htmy – Async, pure-Python rendering engine

volfpeter.github.io

71–80 of 90 posts

Re: Htmy – Async, pure-Python rendering engine

#72

How does this compare with FastHTML?

The most important difference is that htmy does not bring its own web framework, you can use it your preferred one (preferably one with async support, but you can always delegate the rendering if you use a sync one).

Re: Htmy – Async, pure-Python rendering engine

#73
post #5

I was looking for something like this a few weeks ago. I typically use Django and hate the template engines limitations. I needed to make some reusable components and the best option available was switching to jinja to get their macro support, bleh. This reminds me of the best part of Flutter UI composition, but in a language I always return to. Have you done any benchmarking? I don't even know what the comparison wo…

I haven't done benchmarking yet. To be fair, I had limited time and I focused on developer comfort and the features I needed for projects I work on. Simplicity and flexibility was another goal: the rendering engine itself is as minimal as possible, but can be replaced or optimized in the future.

I'll probably do a simple comparison with Jinja (using FastAPI) this week. Given that I can put an htmy() method on my business objects (it was an important design consideration, no conflict with other tools), I expect an okay results, but we'll see.

Re: Htmy – Async, pure-Python rendering engine

#74
post #46

Earlier quoted context omitted.

Yes. But you should be equally strategic about introducing sync code into your platform. Because making your platform sync basically makes it only be able to call sync functions of your code. It's not that async infects. It's sync that infects and restricts. We are just used to it by default. The fact that we started from sync was the cause of all the trouble of rpc because everything outside of CPU is innately async…

I just completely disagree. Async is syntactic sugar that can be reduced to sync code with callbacks. It doesn’t exist on equal footing. If you want to call sync code from async code, you just… call it. If it performs blocking IO, it’ll block, but that’s exactly what it would do if called from other sync code, too. By contrast, calling async code from sync code requires a special blocking wrapper (Python) or unavoida…

> Async is syntactic sugar that can be reduced to sync code with callbacks

The whole point of introducing async was to get away from callback hell.

Re: Htmy – Async, pure-Python rendering engine

#75
post #47

Earlier quoted context omitted.

Imagine you have 2 big components, one fetches from an third-party API and the other from your backend, this way they can load at the same time instead of sequentially.

But does it actually work that way? If I `await fetch_from_api()` in the first component before returning the tree with the second component that fetches from my backend, `fetch_from_api()` has to resolve before Htmy finds out about the second component.

You’d have to structure it differently, it’s definitely not a free lunch

Re: Htmy – Async, pure-Python rendering engine

#76
post #54

Earlier quoted context omitted.

> By contrast, calling async code from sync code requires a special blocking wrapper (Python) ... That's exaclty my point. If you don't have async by default in your platform you need to do stupid things to fake it. If function calls and main in Python were innately async you could be calling async code just as easily as sync code. > [...] or unavoidably breaks control flow (JavaScript). async/await syntax avoids it…

> Tbh await should be default function call semantics and there should be special keyword for calling without awaiting. Your comment made me realize this is exactly what golang "go" keyword does. This is actually great.

also Cilk spawn.

Re: Htmy – Async, pure-Python rendering engine

#77

Earlier quoted context omitted.

I was imagining more like you have a Django view that does all the async data fetching and then you hand off the results to a 'dumb' page component that does only rendering I guess the point is to have components know how to fetch their own data, particularly when combining with HTMX and having backend return page fragments that correspond to components. But maybe this makes more sense in React than it does when tran…

You're right, fetching all the data (that you may or may not need during rendering) in advance is of course doable and quite common. That's what you do for example with tools like Jinja. That may or may not work well for your use-case. htmy does not force you to put data fetching or anything else into components (you can still have dumb components). It also doesn't force you to write async components. The most import…

My comment was just thinking out loud really...

It seems like if you're not doing data fetching in the component then there's no need for it to be async.

And then I was wondering if maybe data fetching in components was a good pattern. It's quite different from what I'm used to doing.

Re: Htmy – Async, pure-Python rendering engine

#78

There is already htpy: https://htpy.dev/ I have used it in production and like it. For those asking the point is being able to do similar to React JSX components, but on the server side. It's so much nicer to use than templates like Django or Jinja (there might be other reasons, but this is quite clearly the goal of htpy and I assume this too). Just looking at this one briefly it seems to use magic methods on datacla…

I've seen htpy before starting this project. While creative, I'm not too happy with the interface if I'm honest and it feels quite a bit more limited. There are no magic methods really, you can even write function components. Using dataclasses in examples is also an irrelevant technical details. The actual reason for requiring an `htmy()` method is that this way you can turn any of your business objects (be it Pydant…

Ah OK, that makes sense. I hadn't really thought there was much room to do things differently than what htpy does, but I probably just haven't thought about it enough. I'll definitely give this a go as well. I think the idea in general is a good one.

Re: Htmy – Async, pure-Python rendering engine

#79

Looks similar to a framework I've been using for some personal sites reflex.dev, pretty cool when would you recommend using this over that?

That's a pretty complex question.

Reflex is a great project with a great feature set, it does everything (client rendering, state sync, API) and you can even write your callbacks in Python. It seems like the best option from this family of frameworks (alternative is NiceGUI for example, but having worked quite a bit with that, I probably wouldn't recommend it). Doing everything has some downsides though: there's a ton of "magic" under the hood, the lib is obviously very opinionated (it couldn't exist otherwise) and you may have a hard time if you need something that's not built in to the framework.

htmy is pretty much the opposite, it only does HTML rendering and comes with a set of utilities for advanced uses, e.g. async support, context usage, styled markdown, etc.. With FastHX, you also get a pretty convenient, declarative integration with FastAPI and HTMX. The tool is ergonomic, but you do need to put in more work compared to Reflex (create APIs, use HTMX, maybe AlpineJS or similar client-side tools). In exchange for simplicity (and lack of magic), you get full control over everything: you can convert your business objects to components, use any CSS/UI lib, any backend tooling. Extra benefit is you can migrate to (and from) it relatively easily from tools like Jinja.

Re: Htmy – Async, pure-Python rendering engine

#80

Earlier quoted context omitted.

You're right, fetching all the data (that you may or may not need during rendering) in advance is of course doable and quite common. That's what you do for example with tools like Jinja. That may or may not work well for your use-case. htmy does not force you to put data fetching or anything else into components (you can still have dumb components). It also doesn't force you to write async components. The most import…

My comment was just thinking out loud really... It seems like if you're not doing data fetching in the component then there's no need for it to be async. And then I was wondering if maybe data fetching in components was a good pattern. It's quite different from what I'm used to doing.

Yeah, the renderer itself must be async to enable async tooling, but everything else can remain sync unless async is really needed.

Regarding data fetching (it's a recurring theme in the comments), I'd probably do most of my async business logic in my routes (well, I'm obviously using htmy with FastAPI and HTMX through FastHX), and components may fetch additional resources if they need something other than the route's result (translations, markdown, html snippets, some other IO).

I'm not sure if any other tool really enables this pattern, but I'm quite curious to see how I'll use it in future projects, and hopefully also what ideas and patterns others come up with in their projects. There's definitely room for creativity.

Post reply on HN