1. I don't use the internal DB stuff, I've been using Peewee ORM instead because it is more declarative (less magical) and fits in my head better.
2. I use app.get/post/etc. because it is more declarative. I like to know without thinking what sort of message an endpoint is expecting.
3. Query params: I don't know how I feel about this. There's some ambiguity in my head still about URL params vs query params.
4. Leveraging return values for DB model creation: This is syntactic sugar. It looks nice, but I prefer to have my code broken out so I can parse it mentally one piece at a time.
5. Use .to() for URL Generation: This is pretty cool I'll have to give this a try.
6. PicoCSS: I've been using this exclusively and it comes out rather nicely with a minimal amount of custom CSS.
7. Smart Defaults: Again, I prefer more declarative code, so I don't like this and I don't use it.
8. FastHTML Handles Iterables: I don't use this. I prefer list comprehensions when building out lists of components. An extra function call reads as confusing to me. Potato tomato.
9. Minimal Code: This is growing on me. I like one-liners for very short components or endpoints. It means I can fit more code on the screen at any given point in the file.
10. Use POST for All Mutations: I do this exclusively. I know htmx has other tags, but I don't use them because they muddy my understanding.
11. Modern HTMX Event Syntax: I haven't made enough use of HTMX to have to use this.
---
In all I've been very pleased with FastHTML and the speed at which I can build out an app. I'm nearly ready to release my first project in all its glory. It isn't much, but I've learned a bunch about web stuff by putzing around with it in the in-between times.
librasteve 1 days ago [-]
an intriguing post with the ubiquitous todo example
model Todo does Component::Red[:C:R:U:D] {
also does HxTodo;
has UInt $.id is serial;
has Bool $.checked is rw is column = False;
has Str $.text is column is required;
method toggle is controller {
$!checked = !$!checked;
$.^save;
self
}
method HTML {
tr
td( input :type<checkbox>, |$.hx-toggle, :$!checked),
td( $!checked ?? del $!text !! $!text),
td( button :type<submit>, |$.hx-delete, :style<width:50px>, '-'),
}
}
Todo.^create-table;
Is this maybe in the wrong place? How does this relate to FastHTML best practices?
librasteve 1 hours ago [-]
the HARC stack is quite similar to FastHTML … both are back end libraries that leverage HTMX to help build web apps on the server side and reduce the complexity of modern web development
specifically the OP references the todo example app and I thought readers here who are interested in server side web coding would like to see the same example done in another stack that is less hampered by the limitations of Python
daft_pink 1 days ago [-]
I’m really curious if they’ve created a way to use FT components but use FastAPI to serve the HTMX
CraigJPerry 1 days ago [-]
Another day, another FastHTML post on HN, someone is active on the marketing front ;-)
Joking aside, enough of the premise resonated with me that i've been test driving it the past few days - i'm definitely target audience - and generally finding it pretty good.
I like the fact it's just functions and data, a lot of complexity has just been thrown in the bin. No bundler, no build/packaging step required etc etc but you'd have to be in the target audience to be happy with this[1]
For example when it comes to organising my thoughts, i don't need to learn some new paradigm, it's just functions, so i was able to just use regular basic concepts i'd use to organise any code. Concrete example: a template expressed as a function that takes a couple of parameters to inject somewhere makes for an easy to live with approach to reuse - since unlike a base.html in jinja2 for example, i can navigate to usages in my editor because it's just function composition. No templating DSL.
Another concrete example - i wanted something akin to a component in react, something with some state and an ability to render() - so i created a dumb plain old class, put the state as fields on the class and had a render method. Refreshingly basic. I didn't need a conventions guide or anything like that "here's how we do this in Framework X" - i just used basic how to write code principles.
I don't find the docs that consistent - for example the linked page (which i've never seen before) points out using @rt with function name for the route - i saw this was possible in an annotated claude chat they link from the github and immediately figured that's a 1000 better than @app.route("xxx") def post|get ... - but it has gotchas, AIUI just using rt creates a post and get handler by default - but it has benefits that i can use the function itself as the way to resolve the path (think url_for in other frameworks like django) - the docs are mostly littered with the awkward "you'll have lots of functions called get or post with a decorator specifying the route" approach.
The types .pyi is good enough for my use case (letting my editor look up what functions exist etc.) but it's incomplete if you want something like pyright to be happy on its strictest settings.
Their development process seems quite intriguing - all written in notebooks!
Their coding style is different from the approach you'd more commonly see (e.g. Black style formatting) but actually quite nice, it's more like Peter Norvig style (which i see as gold standard).
[1] i just want a python SSR webapp with html, minimal css and minimal js - to make it performant i'll lean on reverse proxying and etags in front of it
2. I use app.get/post/etc. because it is more declarative. I like to know without thinking what sort of message an endpoint is expecting.
3. Query params: I don't know how I feel about this. There's some ambiguity in my head still about URL params vs query params.
4. Leveraging return values for DB model creation: This is syntactic sugar. It looks nice, but I prefer to have my code broken out so I can parse it mentally one piece at a time.
5. Use .to() for URL Generation: This is pretty cool I'll have to give this a try.
6. PicoCSS: I've been using this exclusively and it comes out rather nicely with a minimal amount of custom CSS.
7. Smart Defaults: Again, I prefer more declarative code, so I don't like this and I don't use it.
8. FastHTML Handles Iterables: I don't use this. I prefer list comprehensions when building out lists of components. An extra function call reads as confusing to me. Potato tomato.
9. Minimal Code: This is growing on me. I like one-liners for very short components or endpoints. It means I can fit more code on the screen at any given point in the file.
10. Use POST for All Mutations: I do this exclusively. I know htmx has other tags, but I don't use them because they muddy my understanding.
11. Modern HTMX Event Syntax: I haven't made enough use of HTMX to have to use this.
---
In all I've been very pleased with FastHTML and the speed at which I can build out an app. I'm nearly ready to release my first project in all its glory. It isn't much, but I've learned a bunch about web stuff by putzing around with it in the in-between times.
here’s how that looks in https://harcstack.org
full code is here https://github.com/librasteve/Air-Play/blob/main/lib/Air/Pla...specifically the OP references the todo example app and I thought readers here who are interested in server side web coding would like to see the same example done in another stack that is less hampered by the limitations of Python
Joking aside, enough of the premise resonated with me that i've been test driving it the past few days - i'm definitely target audience - and generally finding it pretty good.
I like the fact it's just functions and data, a lot of complexity has just been thrown in the bin. No bundler, no build/packaging step required etc etc but you'd have to be in the target audience to be happy with this[1]
For example when it comes to organising my thoughts, i don't need to learn some new paradigm, it's just functions, so i was able to just use regular basic concepts i'd use to organise any code. Concrete example: a template expressed as a function that takes a couple of parameters to inject somewhere makes for an easy to live with approach to reuse - since unlike a base.html in jinja2 for example, i can navigate to usages in my editor because it's just function composition. No templating DSL.
Another concrete example - i wanted something akin to a component in react, something with some state and an ability to render() - so i created a dumb plain old class, put the state as fields on the class and had a render method. Refreshingly basic. I didn't need a conventions guide or anything like that "here's how we do this in Framework X" - i just used basic how to write code principles.
I don't find the docs that consistent - for example the linked page (which i've never seen before) points out using @rt with function name for the route - i saw this was possible in an annotated claude chat they link from the github and immediately figured that's a 1000 better than @app.route("xxx") def post|get ... - but it has gotchas, AIUI just using rt creates a post and get handler by default - but it has benefits that i can use the function itself as the way to resolve the path (think url_for in other frameworks like django) - the docs are mostly littered with the awkward "you'll have lots of functions called get or post with a decorator specifying the route" approach.
The types .pyi is good enough for my use case (letting my editor look up what functions exist etc.) but it's incomplete if you want something like pyright to be happy on its strictest settings.
Their development process seems quite intriguing - all written in notebooks!
Their coding style is different from the approach you'd more commonly see (e.g. Black style formatting) but actually quite nice, it's more like Peter Norvig style (which i see as gold standard).
[1] i just want a python SSR webapp with html, minimal css and minimal js - to make it performant i'll lean on reverse proxying and etags in front of it