volfpeter's comments

volfpeter | 5 months ago | on: Show HN: Next.js-like Python web framework, built for Htmx with FastAPI

It's just sugar.

It hides the manual template selection, context creation, and rendering logic behind a simple decorator. This way you always write standard FastAPI routes (or you add HTML rendering to existing JSON APIs without changing the route or breaking the existing functionality).

With htmy, it does a bit more, like adding some utilities to the rendering context, adding context processor support, simplify rendering, letting you statically check whether your components receive the correct properties.

volfpeter | 5 months ago | on: Show HN: Next.js-like Python web framework, built for Htmx with FastAPI

It's a shame you did all the rendering manually :) FastHX would have simplified your life a bit.

devpush seems really interesting! I wasn't aware of it, but I'll check it out! It also looks great (no surprise there, it's Basecoat).

Although I usually go with DaisyUI, Basecoat is a vey good source for ideas and more complex component patterns. This is why I feel translating Basecoat snippets to htmy wouldn't be that much trouble, and I'm seriously considering starting it.

volfpeter | 5 months ago | on: Show HN: Next.js-like Python web framework, built for Htmx with FastAPI

Well, the thing is, FastHX, htmy, and holm should be powerful an unopinionated. Think of them like ReactDOM, React, and Next.js.

On the other hand, I already thought about building a component library for htmy. I'd prefer to do it with TailwindCSS and DaisyUI, or I could use for example BasecoatUI https://basecoatui.com/ as a template, because it already offers Jinja-like component snippets.

Now that I have holm as well, I may eventually do it. It's a lot of work though, finding so much spare time is hard.

FastUI is now Reflex. They essentially build a FastAPI + NextJS app combo from your code (maybe they already swapped NextJS for something else). NiceGUI is similar as well.

For my projects, I really want to avoid a big JavaScript companion app, so interactivity will remain HTMX, pure JS where needed, or AlpineJS for example. I'm also thinking about a server-component concept for HTMX with holm, but I don't have a clear plan just yet. I can think about these more now that I have holm.

volfpeter | 1 year ago | on: Htmy – Async, pure-Python rendering engine

With the current renderer (which is super basic because simplicity and features were the main priority over optimization for now), if a component has multiple async children, they will be resolved concurrently. I assume that's what you meant by "parallel". Not sure why that would need an example, but you can simply create a component that calls asyncio.sleep(1), then create a bunch of instances and render them to test it.

I want to have at least the same level of concurrency when the new, better optimized renderer lands.

volfpeter | 1 year ago | on: Htmy – Async, pure-Python rendering engine

I did some testing in the meantime. Depending on what you render, it's about an order of magnitude slower currently.

The renderer is as simple/minimal as possible at this point (the focus was on the core feature set I needed until now), so it's performance is as bad as it can be :) There's plenty of room for improvement. I'll work on a few optimizations as I have time, but contributions are more than welcome.

volfpeter | 1 year ago | on: Htmy – Async, pure-Python rendering engine

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.

volfpeter | 1 year ago | on: Htmy – Async, pure-Python rendering engine

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.

volfpeter | 1 year ago | on: Htmy – Async, pure-Python rendering engine

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.

volfpeter | 1 year ago | on: Htmy – Async, pure-Python rendering engine

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).

volfpeter | 1 year ago | on: Htmy – Async, pure-Python rendering engine

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 Pydantic or SQLModel classes for example) into components without the fear of a method name conflict with your business stuff. Actually, I expect/planned this to be a very frequent use-case, and then there'll be zero unnecessary nesting.

volfpeter | 1 year ago | on: Htmy – Async, pure-Python rendering engine

That's a fair point, although my feeling after working quite a bit with Jinja recently is the opposite (primarily for lack of static analysis and IDE support).

You're right, for example the documentation should be improved quite a bit. Keep in mind that this project is pretty new, I simply had no time to add more docs or further improve the existing one.

Ps.: with the Snippet utility and markdown support, you can actually write quite a bit of your HTML in a html files rather than Python. You could even use Jinja templates as the backend for some of your components. This part will see more work as I have spare time to work more on the project.

volfpeter | 1 year ago | on: Htmy – Async, pure-Python rendering engine

Components don't really need to fetch anything, they don't need to be smart. It's up to you where data fetching happens. If you look at fasthx for example, you'll see that routes/views normally handle your business logic and fasthx does the rendering (now with Jinja or htmy). With Jinja for example, it can only work like this. With htmy, you have more flexibility (which can be an advantage but of course it can also be misused).

Async components can be handy for example when you need to load files. See the Snippet utility and the markdown support in the lib. https://volfpeter.github.io/htmy/examples/markdown/

volfpeter | 1 year ago | on: Htmy – Async, pure-Python rendering engine

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 important thing it does is it gives you the option to build your application entirely in Python (no ugly custom templating language syntax with lack of static analysis or proper IDE support) and enables the use of modern async tools.

And admittedly, the lib was built with FastAPI and HTMX in mind, which kind of necessitates async support...

page 1