[HN Gopher] Building a fullstack app with Flask and HTMx ___________________________________________________________________ Building a fullstack app with Flask and HTMx Author : sixhobbits Score : 164 points Date : 2022-03-29 14:49 UTC (8 hours ago) (HTM) web link (codecapsules.io) (TXT) w3m dump (codecapsules.io) | [deleted] | Darmody wrote: | I love htmx. It allows me to write code on the server and forget | about most of the boring client stuff. | | If you're a PHP dev check Yoyo Framework. It's like Laravel | Livewire without all the bloat from Laravel. | danjac wrote: | This code looks like it has an XSS vulnerability in the submit() | method: returning plain f-string i.e. return | f"<tr> <td>{title}</td> | <td>{author_name}</td> <td>...." | | Probably safer (and more maintainable) to just return a Jinja2 | template instead. | batterylow wrote: | I built https://PlotPanel.com with Django, htmx, Alpine.js, and | Tailwind CSS. I was new to all 4 of those technologies and learnt | whilst on the project, it was a great experience. It was my first | time using the Stripe API too, which has the nicest documentation | I've ever seen! | weakSignal wrote: | You did impressive work mate. | reducesuffering wrote: | Looks very nice. How long did this take you? What's your | deployment stack: Heroku, DigitalOcean, AWS, containers, CI? | number6 wrote: | Wow that looks amazing! Is it all tailwind CSS? | | How do you work with components e.g. buttons in django + | tailwind? Do you {% include %} them or are all of them uniquely | designed? | jacktheturtle wrote: | This seems like a good simple stack. Can it get more simple? I've | been trying to envision the best stack for small weekend projects | that will see 3-4 users a month. | | Ideally: Monolithic, 1 Language, No need to write your own APIs. | Just direct access from the View. | erokar wrote: | I think Rails is the best fit for this, alternatively something | like SvelteKit + Supabase (the latter if you need a db). | jacktheturtle wrote: | Rails is awesome, I'm a huge fan. I just think there's a huge | ramp up out of the box. I wish I knew how to go from rails | init -> dashboard w/ login faster. | mekoka wrote: | It really depends what you mean by _simple stack_. | | You mentioned "weekend projects", which indicates that you | value development productivity. You want to be able to do more | with your allotted time. The way we tend to envision a "simple | stack" is to mean a combination of lighter and possibly | specialized tools. But does that necessarily translate into | quick development? Your choice of tools still relies on your | experience with them individually. | | I often see people advocating for microframeworks when this | question comes up. As a long time user, I would say sure, but | with the caveat that they come with very few batteries, and | sometimes fewer opinions. To me this is also the promise of | many future decisions to be made, _by you_. How much time does | a single decision typically cost you? | | Also, the size of your project's audience, doesn't imply that | the app needs considerably less dependencies, than something | more ambitious popularity wise. The difference usually lies in | the infrastructure that will eventually specifically address | scalability. | | I think a good simple stack for week-end projects should aim to | get you from install to development fairly quickly. Don't waste | time making too many technical decisions beyond the choice of | tools. Spend half an hour setting up a container, design your | database, and get to work. If some other people have already | spent time working out what's best in 90% of cases, use that | experience first. Find out later that your case falls within | the 10% that doesn't apply. | | --- | | Now, for some more practical recommendations. I think Django's | opinionated batteries make it a more compelling solution for | "week-end" type projects. Does it matter that it installs | megabytes on disk, of which you end-up barely using a few | KBytes? For most cases I don't think it does. | | My stack suggestions for week-end type projects on the back-end | will be heavily Python-centric (except for Ruby-On-Rails): | | - Django|RoR, Postgres: Opinionated batteries. Just hop on the | train and simply let it drive you. | | - Flask, Psycopg2, Postgres: when you're already comfortable | replacing most things Django offers for free, with your own | assortment of best-of-breed tools and practices (testing, | templating, etc). Working with Psycopg2 implies that you're | reasonably comfortable working directly with SQL, and willing | to spend some additional time working out the various kinks | that inevitably need addressing, when managing your own | connections to the database. | | - Flask|Django, Postgres, SQLAlchemy: Only if you already know | SQLAlchemy. If you don't, just trust that you won't learn it in | a week-end. | danpalmer wrote: | One of the benefits of PHP is the single page idea, where the | file system directly matches the URL structure. | | For quick and dirty projects I've always wondered what a Python | version would look like. | | Maybe Jinja2 pages, a place to define extra code to be run or a | custom ninja tag for longer sections of Python, and a binary to | launch the whole thing as a server? | sixhobbits wrote: | if you don't want fancy partial-page reloads and UI | interaction, then just Flask + HTML also works. | keb_ wrote: | Even better: Bottle.py; single-file dependency, includes | routing and a simple templating engine. | atoav wrote: | Not sure if bottle is really "better" -- it has different | pros and cons compared to Flask, so whether it is better | depends entirely on the usecase. | | If you e.g. have a use case where your dependency-situation | is one where you won't benefit from bottle being single- | file (because you e.g. have a ton of other non-single file | dependecies), then choosing it over the widely used Flask | might not be show you any benefits at all. | keb_ wrote: | I was responding to the request in the top comment for | something simpler that can be used for weekend projects. | In this case, Bottle.py is "better" in that it is more | simple than Flask; not that Bottle.py as a web framework | is objectively better than Flask. | | For the record, I've used both, and Bottle is much faster | to get started with. The docs are also much leaner. | dannywarner wrote: | Agree. Simple Flask and HTML gets you a long way and is easy | to deploy and manage. | jacktheturtle wrote: | Might want to give this a try. Thanks for sharing! | dfinninger wrote: | Flask will take you pretty far. I'm not sure I would | build a build a business around it, but it's the easiest | thing I've found for just getting some code up on the | web. | | This tutorial is a pretty in-depth guide that | incrementally adds more features to a flask app: | https://blog.miguelgrinberg.com/post/the-flask-mega- | tutorial... | | By no means do you need to use everything in here, but I | reference it from time to time. This is plenty: | from flask import Flask, render_template app | = Flask(__name__) @app.route("/") | def index(): return "<h1>hello world<h1>" | @app.route("/foo") def foo(): return | render_template("foo.html", vars={"foo": "bar"}) | if __name__ == "__main__": app.run() | bckr wrote: | I work at a company pulling real cash, built mostly on | Flask. Flask is one of the things I like the most about | the stack. | lambdaba wrote: | Meteor does this, in JavaScript, with built-in database and no | writing of APIs, code is shared between client and server. | jacktheturtle wrote: | I should give this another shot. I haven't touch it since | 2017 | ramchip wrote: | Phoenix LiveView works great for this. | keb_ wrote: | Replace Flask with Bottle.py. It's a single-file dependency | (don't even need pip) and includes routing, and a templating | engine. Super simple to prototype and iterate a backend API. | farmin wrote: | This is what I started doing. Bottle has user auth plugin | called cork that is handy too. All very simple to understand. | I did start using jinja instead of the built in template | engine though. | jms55 wrote: | Elixir + Phoenix/Phoenix LiveView is very good at this. | LiveView lets you change state on the server, and have it | reflected on the client. Or, when the client does an action, do | something on the server (that can then trigger another state | change on the client, etc). All of this is purely using Elixir | - no need to write JS 99% of the time. | Townley wrote: | I developed almost exclusively in django for many years before | moving to react or vue for frontends. | | The switch from django templates was painful and a tremendous | learning curve, so I get the value proposition of drop-in | interactivity tools like HTMx. But when you compare the two | frontend ecosystems (javascript vs htmx) it's night and day. The | support, the DX tooling, the variety of libraries... that's not | to say HTMx couldn't one day mature to a comparable place, but it | seems unlikely, and in the meantime investing in "eating the | elephant" by learning a JS framework seems worthwhile for anyone | planning to spend a significant amount of time building frontends | digisign wrote: | The use case here is to add some interactivity to your page, | not implement an ecosystem inside it. | zdragnar wrote: | Back when I was learning AngularJS (the 1.x days) I spent what | felt like hours staring at some code wondering why the hell it | wasn't working. | | I eventually realized I had a typo in a template that was all | too easy to overlook. Since there wasn't any tooling to catch | it, it behaved like an html attribute and did nothing. | | I seriously don't know that I would want to go back to such an | anemic dev experience unless it is for a toy project. | christophilus wrote: | Preact / React + TypeScript largely does away with this. For | most of my projects, fixing the compiler errors means the UI | largely works (other than plain logic errors). I did | AngularJS, too, and it's a totally different, terrible | ballgame. I recommend giving Preact a try. | slig wrote: | The first time I read about HTMX here on HN I didn't get it, | thought it was pointless. Then it clicked, and I think it's | awesome. Fits nicely with Django, super easy to understand and | the docs are great. | [deleted] | yakshaving_jgt wrote: | I can't work out what problem this solves. Personally, I'm not a | fan of SPAs, but there's still a middle ground between that and a | more traditional full-page reload, server-side rendered approach. | React, Elm, _etc_ , should all allow for smaller parts of a page | to be dynamic while the rest remains static. | felipeccastro wrote: | HTMX is a middle ground - using it involves not having "full- | page reloads" like traditional server rendered apps, but still | having the productivity of server only apps. | | The main advantage I see with this approach is you'll have only | one set of models/actions in the server, instead of models in | server + models in client. The logic won't be spread between | client and server, which make for easier testing among other | benefits. For larger apps, this is a significant win. | sixhobbits wrote: | They do, but they have a steeper learning curve and cause more | separation between back and front end. Sometimes that's good, | sometimes it isn't. | | [0] and [1] are relevant sections of a much longer guide that | go into more detail about the tradeoffs. | | [0] https://www.saaspegasus.com/guides/modern-javascript-for- | dja... | | [1] https://www.saaspegasus.com/guides/modern-javascript-for- | dja... | pythonaut_16 wrote: | This is also one of the use cases that Vue targeted | specifically and it greatly accelerated its adoption. | | Vue positions itself for anything from jQuery replacement all | the way to a full SPA and everything in between. | zdragnar wrote: | It's how Facebook originally (still?) used react. | | Anything works that way as long as it doesn't come with a | built in router and you are careful not to accidentally | bundle two different versions of your runtime. | Dauros wrote: | HTMX helps you create an SPA-like experience without using a | full SPA framework. You can utilize the full power of your | favourite backend framework (e.g form validation, template- | system, authorization, etc.) without writing JS code directly. | Some examples: | | - Infinite scroll: HTMX detects the specified viewpoint and | requests the next batch of content. The backend returns only | the rendered partial HTML content that HTMX appends to the | bottom of the page. | | - Next page of a paginated content: if the users clicks on the | 'Next page' button, the backend returns only the rendered HTML | content of the next page, HTMX replaces only this part of the | page. | | - Form submission/validation: you can skip most of the frontend | validation and use the backend for it. If the form has an | error, HTMX replaces the new rendered form with the inlined | error messages. Otherwise it can forward the user to the next | page or shows some success message. | | - Inline edit: e.g. click on the row in a table to load a small | form just for that line. After the submission the backend | returns the updated rendered table. | | - Chained select input elements: when the user selects | something in the first dropdown, it triggers an HTMX request | that loads just the next select element that reflects the value | of the first one. | | - Background task with progress bar: just return a delayed, | automatically triggered HTMX request from the backend until the | task is finished. The status (e.g width) of the progress bar is | also calculated on the backend. | | - Search preview: with the builtin debounce filter trigger a | search request that returns the search suggestions. | | - Multiple small(er) updates on the page: one HTMX request can | return multiple HTML partials that updates any part of the | page. If you couple it with the builtin automated | polling/websocket, you can build a live dashboard easily. | | Of course you can do any of these with a SPA framework coupled | to the backend API. But with HTMX you don't have to write a | single line of JS, just put some htmx-something="..." | attributes in the backend template files. | nop_slide wrote: | I've only used HTMX for a tiny project along with FastAPI, it was | basically just a single form page that would send the response in | JSON to the server. | | Things I liked were that it felt really lightweight, easy to | setup, and basically just worked how the docs described. | | However one thing I'm still trying to wrap my head around is how | to better handle "intermediate" pieces of HTML i.e. partials. In | SPAs you create a component that renders the template on the fly | and is reused, but in HTMX you would need to hit an endpoint to | get something like a partial. | | This sort of had me pause because I'm so used to keeping my | backend routes very "RESTy" (in the loose sense). But when using | HTMX I was wondering if I need to make some routes like | `/contact-form/modal` just to retrieve something like a success | modal. | | The article kinda displays what I mean with how all of the book | routes return the buttons for the form. Also the `/get-book- | row/<int:id>` and `/update/<int:id>` routes both return the same | type of buttons. Those buttons seem prime candidates to be | extracted into a common template of sorts. | | Does that make sense? If so does anyone have a good example of a | larger HTMX app which handles these scenarios? | pythonbynight wrote: | Recently saw Michael Kennedy's presentation at Python Web | Conference where he talks about this. He also has a course on | using Flask + HTMX. Even if you don't take the course, you do | have access to the github repo for that course. | | https://github.com/talkpython/htmx-python-course | | He wrote a small library extending Jinja that does what you're | referencing here, I believe. It's a little different than Jinja | macros and include (you can reference the github issues for a | discussion on that). | | https://github.com/mikeckennedy/jinja_partials | | Maybe that's what you're looking for? | bityard wrote: | I'm not a fan of Javascript but my simple projects often need | some interactivity that just HTML and CSS alone can't provide. | Things like, "when the user clicks thing thing, update this other | thing." | | I thought HTMX was going to be that silver bullet that let me get | away with never writing JavaScript again, but after using it in a | few places, I'm a bit more selective in which projects I adopt it | for: | | If you're doing anything fancy before or after a request, you | either have to use Javascript anyway, or pull in hyperscript as | another dependency and then you also have to learn hyperscript. | (Some of the demos on the HTMX site require hyperscript.) | | Browser-native prompt dialogs send the contents of the prompt as | a custom request header instead of POST data, which means you | have to modify your backend routes, making HTMX much less plug- | and-play. If there's a good reason for this design decision, it's | not mentioned in the docs or examples. | | If you already know how to use querySelector(), fetch(), and | innerHTML in Javascript, HTMX isn't going to offer you much | except cleaner-looking code at the cost of adding a dependency to | the project. | kitd wrote: | HTMX has quite a few before/after events that you can respond | to: | | https://htmx.org/reference/#events | tomatowurst wrote: | I am trying to understand better your pain points here. What | other fancy cases are you referring to when you say before or | after a request? Are you talking about dom events? | | Do you see any other scenarios where this stack setup | struggles? If you were to design this how would you do it? | Since I do think it is helpful in some cases like creating | forms and basic navigation. | recursivedoubts wrote: | there is no silver bullet: htmx and hypermedia are a tool, and | give you a pretty low-complexity solution to many problems, but | eventually you will run into something that needs a more | elaborate front end solution and using Alpine, vue or whatever | makes sense. | | Hopefully by staying close to HTML's semantics and design | philosophy, using htmx doesn't introduce a lot of conceptual | load on top of what is already there, and saves you complexity | where the more elaborate client-side stuff isn't needed. | clairity wrote: | yes, and jquery is still useful in cases like this, despite the | disdain most modern front-end devs have for it. the added | weight is also not a big concern for any site not meant to | serve millions of requests a day. it just has all of the core | convenience methods you'd want, and a sane dev UX (unlike plain | js). | | i'd add that stimulus is another great alternative for | sprinkles of front-end interactivity without going all-in on js | tooling and a js framework. it pairs nicely with rails 7's new | turbo feature to provide a full server-side rendering | experience, similar to htmx. | pythonaut_16 wrote: | I'm not super familiar with HTMX but lots of people in the | Elixir/Phoenix/Liveview world are using Alpine JS for these | types of problems. | | Liveview(HTMX analog) for anything with data and state that | needs to go to and from the server; Alpine JS for client side | interactions with ephemeral state like opening a modal. | adfm wrote: | HTMX + Alpine JS seems to be prevalent. | reducesuffering wrote: | It's hilarious to me that HTMX is JS code and Alpine.js is | HTML. | sgt wrote: | A good (more conventional) alternative is to just use Django. You | get all of this functionality built in, plus much more. | | Also possible to use HTMx so you avoid JavaScript as much as | possible, | andybak wrote: | I think Flask here is just a placeholder for "a simple backend | framework". I agree that Django probably ends up the simpler | choice once you need the stuff you'll almost certainly need. | But that would have spoiled the flavour of this tutorial. | saila wrote: | I think that is exactly the problem with Flask. Look how | simple it is! Except, as you say, you almost always need at | least some of that stuff, and wiring it together yourself | is/becomes an unholy mess (IME). And getting set up with | Django is just as simple, so I don't buy that argument | anyway. | gen220 wrote: | What problems do you run into with Flask (presumably + | SQLAlchemy)? | | IME, this stack has been pretty simple both at-scale and | at-home. At scale, my experience is mostly using it in REST | APIs serving a react frontend. | | At-home, I've used it to setup numerous graphql services | (with the graphene plugin). | | Admittedly, there's probably 100 different ways to | configure anything wrong, especially for any framework | written in Python. But once you witness a "golden path", | and stick to it, it's pretty straightforward. (The Flask | docs have improved a lot in this regard, in the last few | years) | saila wrote: | I'm working on multiple Flask apps currently and I have a | lot to say about it, but regarding docs, the main Flask | docs might be fine, but the docs for some of the | extensions we use are quite bad. | | Also, there's nothing about these apps that requires the | alleged flexibility of Flask, so there's a lot of issues | with dependencies and integrating extensions. That's a | lot of extra work and probably weakens security for no | benefit at all. | | Upgrading a big Django app is much simpler IME. | gen220 wrote: | I think part of the reason the Flask extension ecosystem | is so weak, is that most problems solved by an extension | have solutions that are relatively small / cheap to build | in-house. | | These things are difficult both to depend upon externally | and to maintain, due to the dependency/upgrade issue you | mentioned. | | For an example in a similar ecosystem: at a previous | company, at one time we used SQLalchemy-continuum for | audit tables. We found some bugs and were not able to | upstream them. When we wanted to upgrade SLQLAlchemy to | X.Y, we were stuck with this dependency that required | SQLAlchemy X.Y-1. | | After a few years, we realized it was cheaper to cook up | a SQLAlchemy-Continuum subset that met our needs, so it'd | be easier to keep in line with SQLAlchemy. | | It's a very different mindset from Django; I think | there's an appropriate context for each. | digisign wrote: | May have changed, but when I tried it, the first day with | Flask was incredible. The second day, when you're ready | to implement log-in and password pages, maybe email | reset... you are on your own. There's six and a half | third-party extension options with different overlapping | scopes to research, the author of the best one has taken | off for the Bahamas for two years... | gen220 wrote: | Ah yeah, fair enough. The places I worked at-scale had | their own o-auth setups (built mostly with FOSS) wired up | to flask with some relatively small libraries [1]. | | I personally wouldn't want my web framework to implement | login/password/email-reset for me, although I understand | Django offers it to varying degrees. It's a space where | "best practice" has evolved dramatically in the past | decade. | | [1]: https://flask-oidc.readthedocs.io/en/latest/ they | looked a lot like this, fwiw. Although to your point, | this too, hasn't been updated in 5 years. :) | CuriouslyC wrote: | The problem with Django is that it's so opinionated. If you | don't really use the admin interface and you want to do | things your own way you will spend way more time wrestling | with Django than you saved using a few plugins. Also, the | ORM is hot garbage that you have to carry with you to some | degree if you do actually use the admin at all. | saila wrote: | I rarely use the Django Admin except maybe for poking | around in the early stages. I've never tried to build a | full blown app/site with it. | | I think the right comparison here is to Flask-Admin, | though, not Flask itself, and I'll just say that the app | I have to deal with that's built on Flask-Admin is a | nightmare, certainly no better than an equivalent app | using Django Admin would be. | | Re the Django ORM, SQLAlchemy is certainly better in many | ways, but the Django ORM is pretty good these days (and | has been for a while IMO). | | If I _know_ I'll have complex database requirements that | Django can't easily handle, I'd much rather use Pyramid + | SQLAlchemy than Flask. | sgt wrote: | First thing I do is disable the admin interface. I think | most serious Django devs view it as a gimmick. | andybak wrote: | Not all of us. | andybak wrote: | > the ORM is hot garbage | | It really is not. | peller wrote: | I had the same pain points with Flask, so I built Flask | Unchained to integrate many of the best extensions (IMO) to | all work together out of the box in a reusable way: | | https://github.com/briancappello/flask-unchained | nop_slide wrote: | Does anyone have a nice dev tool setup which adds auto page | refresh and production processed assets? | | One thing I noticed after making a small FastAPI/HTMX app was | that I missed the hot reload of React. Also I noticed when I | deployed to a live version of the site I found myself needing to | hard refresh my browser because my assets didn't have hashes | appended to bust the cache. | | Just curious if anyone has some cool setups :) It would be | awesome if there was a way to integrate ParcelJS as it has a nice | reload server. | vosper wrote: | This worked for me | | https://www.npmjs.com/package/reload | nop_slide wrote: | Doesn't this just serve your files? | | I was hoping to look for a way to get auto reload to work | while being served by your Flask/FastAPI server. Maybe it's | not a big deal to dev using "reload" but have your prod app | served by Flask/FastAPI. | vosper wrote: | You can have the site reload whenever your backend server | code changes. That's how I was using it. Perhaps I'm | misunderstanding what you're asking for. | tga wrote: | I have been using Parcel (https://parceljs.org) for building JS | and CSS (from SASS) asset bundles for Django apps. It is | pleasant to use because it takes almost no configuration to get | going. | rufugee wrote: | I recently switched back to Rails after 7 or so years seeking | (part-time) a better option, and wow....Rails and Ruby are still | beautiful and my productivity has spiked tremendously. I'm | finding https://hotwired.dev/ to be awesome, and was able to | develop an interactive data grid in less than an hour. | | If you haven't tried Rails lately because it's no longer cool, I | encourage you to look again. I've tried many different | frameworks, including Flask, but nothing touches Rails (IMHO) in | terms of productivity. | schlch wrote: | This is exactly my experience. During the last years I mostly | wrote ts, python and some golang. About a year ago a friend | asked if I'd like to join his startup. I was skeptical at first | because his personal philosophy includes avoiding js as much as | possible and (almost) exclusivity relying on the rails way of | doing things. The rails community seems like a cult to me at | times. One year later and I'm not exactly in love with ruby the | language but I seriously love the productivity that comes with | using rails. It is the most complete framework I have used and | from my observation it seems to raise in popularity again. | kareemm wrote: | We use HTMX at Savio (https://www.savio.io), which started as a | pure Django app. | | Our operating theory was that using a JS FE framework was | overkill for a CRUD app. So we went with stock Django and server- | rendered HTML. | | It became clear that parts of our UX would benefit greatly from | client-side interactivity, which is what we eventually expected | to happen. We sprinkled in HTMX (on top of our Jquery) on certain | pages and it's been a breath of fresh air. We even built a nice | Kanban board w/ HTMX and a Jquery plugin. Key benefits include: | | 1. When you're looking at a template the HTMX syntax makes it | obvious what happens | | 2. HTML is rendered server-side in templates (imho where it | should be) and is sent down the wire | | 3. We get a lot of stuff for free from Django (routing, back | button handling, etc) that we don't need to build with a FE | framework | | Even though we're devs we believe the best code is no code (in | the literal sense, not the de rigeur "No Code" sense). | Maintenance costs are important to us. Getting stuff for free is | important to us. Building for a specific use case is incredibly | important to us. | | With that in mind, the Django + sprinkled HTMX experiment has | been pretty successful thus far. | recursivedoubts wrote: | very glad you are finding htmx useful :) | | regarding point 1: | | _1. When you 're looking at a template the HTMX syntax makes | it obvious what happens_ | | I am trying to codify this design principle under the term | "Locality of Behavior". I have written an essay on this idea | here: | | https://htmx.org/essays/locality-of-behaviour/ | | there are other newer libraries that exhibit this | characteristic as well: tailwinds and alpine.js for example | kareemm wrote: | Hah. My co-founder uses your phrase "locality of behaviour" | all the time. I was trying to remember it when I wrote that | first item in the list but couldn't. I very much appreciate | you using it in htmx - makes understanding code so much | easier. Thank you! | dopeboy wrote: | We use django + react. I've long been curious about HTMX but | one thing has been holding me back that I'm trying to get | others' opinion on: the npm ecosystem is incredibly rich. I'm | thinking of drop in components like maps, UI libs, etc. | | Don't I need to spend a lot more effort using their original JS | incantations and integrating that w/HTMX? | felipeccastro wrote: | I've been wanting to do this switch too and have the same | concern. One option worth investigating is Shoelace - | https://shoelace.style/, a library of nice looking web | components that you can just add to your page without setting | up a whole build pipeline. | digisign wrote: | Not certain, but should be easy to make a new folder, fire | up the django tutorial, and drop in htmx and shoelace from | their cdn links into the main template to start | experimenting. Looks feasible. | brtkdotse wrote: | By pulling in React you're now on the hook for another | tooling+build pipeline for JavaScript. HTMX is a single | JavaScript import meaning you can forgo the whole js tooling, | which in my book is a _massive_ win. | kareemm wrote: | It obvs depends on what you're trying to do. In general we | aim to use well documented, well maintained, and popular | dependencies if we take them on at all. We haven't run into | any issues where it felt like we were doing more work than | necessary to get HTMX up and running. | tomwojcik wrote: | I agree npm is wonderful and if you need npm just stick to | React but you mentioned UI libraries. I use Django + HTMX | stack in side projects. I've been using Material UI with | React before, but I don't see a need for something similar in | Django + HTMX stack. Just add some css like bulma and you're | done. | robertoandred wrote: | You don't need to build routing or back button handling with FE | frameworks. | xcubic wrote: | You dont'? | qudat wrote: | It's handled for your with a library like react-router. | xcubic wrote: | That is precisely the point. You have to add more stuff | on top. | cactus2093 wrote: | That's an interesting perspective, although I definitely have a | negative gut reaction to that "where it should be" comment. | It's so nice having a separation of concerns where that the | backend doesn't deal with any view/presentation/styling | concerns and only exposes an API, and then the clients consume | that API (doesn't matter if those clients are FE web apps or | iOS or Android apps or 3rd party developers accessing your | API). | | Another advantage is there are some cool no-code solutions | where you can build internal admin tooling on top of your API, | which kind of gets you some similar benefits to the django | admin interface system. I haven't really used this approach in | production but it makes a lot of sense. | | But in some cases this can definitely come with more overhead | than a quick Rails or Django app, and if you have a very read- | heavy traditional website and no other clients then that | overhead might not make sense. Sounds like you've found a | platform that works well for your use case. | CraigJPerry wrote: | >> It's so nice having a separation of concerns where that | the backend doesn't deal with any view/presentation/styling | concerns and only exposes an API | | You're just casually glossing over the fact that now you've | created a distributed system - state still exists server side | but now there's a distributed eventually consistent subset of | state living in the user's browser (i don't mean trivial UI | state like is the dark theme enabled, i mean application | state). | | And you've opened this can of worms only for the trade off | that you get to move view templating from the server side to | the client side. | | There's one case where there's obvious clear benefits of | choosing the client side rendering trade off and it's if | you're building a client side app. Something that should be | an intensive desktop app but you choose to deploy via browser | instead. Maybe a music mixing or live DJ'ing app or a photo | or video editor. Delivering these apps via web has some neat | benefits in app distribution and cross platform | accommodations. It wouldn't be possible to build them without | client side rendering so it's a clear win. | | Most web apps are not that though. Most are like you | describe, a UI to some APIs. The state really lives server | side - my bank account UI, my blog posts, my ... etc etc For | these cases, you can reduce complexity by ditching the client | side rendering. | theptip wrote: | I've only prototyped adding HTMX to my Django app (currently | using React & DRF), but there seems to be a great alignment | between Django and HTMX. HTMX wants you to send back a partial | HTML tree for the node being updated, and Django's template | inheritance machinery lets you very cleanly separate the | "parent page" from "partial sub-tree" (since you can just say | `{% include "foo_table_fragment.html" %}` in the parent page | template, and then render the "foo_table_fragment.html" | template directly on the GET/POST with HTMX headers). | | It's all very easy to wire in to a normal Django page to | gradually add interactivity (say, partial updates to | filter/sort a table to instead of full-page reload). | number6 wrote: | Can you elaborate on the render fragment on GET/POST part? | That sounds interesting! | brylie wrote: | See the following video tutorial starting at 9:18 for an | example of rendering a template fragment in a Django view | that gets returned to HTMX | | https://youtu.be/H_m1g8XOtHY | jameslao wrote: | I use HTMX + Alpine.js for a project I'm working on. It's been | pretty nice and I think my only complaint is that the requests | are form encoded instead of JSON. There is a HTMX extension that | can JSON encode the requests, but all values get encoded as | strings so its not great if you want lists, numbers, etc. | | I also use Tailwind CSS and I found a way to make that work | nicely with HTMX for CSS transitions which I wrote about [0]. | | [0] https://www.crocodile.dev/blog/css-transitions-with- | tailwind... | batterylow wrote: | Sounds like my stack for https://PlotPanel.com. It's Alpine.js, | htmx, Tailwind CSS, and Django on the back-end. Going to have a | read of your article! | tomatowurst wrote: | trying to figure out how this compares to Phoenix's frameworks | LiveView, does HTMx use websockets to communicate state change? | Seems like I could just end up using HTMx in lieu of learning | Elixir and Phoenix | sixhobbits wrote: | HTMx supports web sockets [0], but my understanding is that it | isn't really an alterantive to something like LiveView. | | HTMx is more about simplicity - an easy alternative to AJAX | that doesn't require a full-blown front-end framework. It isn't | really designed for optimized real-time communication and long- | running connections, but you could probably use it for that if | you wanted. | | [0] https://htmx.org/extensions/web-sockets/ | tomatowurst wrote: | I see its more fair to compare to AJAX...then I'm curious in | what ways does liveview create "magic" over HTMx here, to my | knowledge the mechanics here with HTMx seem a lot simpler and | less bloat doing the same things. | | With LiveView, it seems to be just sending application state | up and down the websocket wire, does HTMx not do this as well | if it was setup that way with WS? | sixhobbits wrote: | Good question - if you do some digging, I'd love to read | about how they stack up! | recursivedoubts wrote: | htmx is a lower-level extension of HTML, with no server-side | component to it | | it tries to extend HTML as a hypermedia, which makes it more | general (it can be used with any backend that produces HTML) | but also more work to achieve things that, in live view, work | magically | tomatowurst wrote: | what sort of magic does LiveView do here that HTMx doesn't? | seems like the difference here is that the article sends a | server rendered partial HTML down the wire with HTMx | sprinkled on it that gets rendered on the client side. From | my basic understanding, LiveView sends HTML to client first, | establishes bi-directional WS connection, and proceeds to | send JSON data to the client and synchronizes the app state | via sending diffs over WS. | recursivedoubts wrote: | yep, exactly, so LiveView needs to have that web socket | doing diffs between the client and server side | | htmx is just html++: any element can make any sort of HTTP | request (GET, DELETE, etc.) based on any event and replace | any other element in the DOM. | | much simpler and "dumb" when compared w/ liveview, with no | particular server-side implementation implied | deniz-a wrote: | The way I think about it is htmx takes the "full page refresh" | user experience & programming model, and expands it to "partial | page refresh" and goes from there. It also patches some | annoying gaps in html, like forms only being able to GET and | POST. Finally, it lets you trigger these requests with things | other than clicking a link/submitting a form. | | LiveView tries to replicate the architecture of a native app | toolkit and slap a network boundary in the middle of it, | whereas htmx tries to keep the programming model of Web 1.0 | apps while radically expanding the user experience | possibilities | bulatb wrote: | This is not a better way of making apps. Or a worse way. In | solutions there is no such thing as good or bad--only more and | less fit for the problem. | | If your problem and requirements are such that you will always be | outside the part of the solution space that SPAs are meant for, | HTMX and progressive enhancement are great. If not, you may | discover the transition like a boat discovers the transition | between water and ice. | | If you don't immediately know the shortest path from your | requirements to that transition, but you're sure that SPAs are | Bad and this is Good, please take a moment to consider why you | think that. | traverseda wrote: | >If your problem and requirements are such that you will always | be outside the part of the solution space that SPAs are meant | for | | That seems like a very very strong claim. "You should do an SPA | in case you ever need to make an SPA". Like what do you think | actually needs to be an SPA? | | Here's my list of popular sites that _don 't_ need to be an SPA | but are anyway | | * Reddit, nothing about it lends itself to being an SPA at all. | | * Facebook, I think they went the SPA route in order to make it | more difficult for ad blockers | | * instagram | | * Netflix (don't know how related this choice is to DRM | constraints honestly) | | * pinterest | | * paypal | | * gmail | | Here's my list of sites that _do_ need to be an SPA, or are at | least easier if you make them as an SPA. | | * Google maps | | * Google docs | | * Photopea | | * Discord (This is almost all achievable with something like | HTMX, save the webrtc stuff, but I think it would be more of a | pain and would rely on a lot of complicated session management | stuff happening on the server) | | * AirBnb, which I'll give a pass since it makes such heavy use | of maps. | | My take away is that if you're reaching for the standard SPA | toolkit you _might_ be better off using something like QT or | Godot engine, writing native code, and compiling it for the | web. Anything that uses maps or rich text editing probably | should be done as an SPA, although if you can make it so that | just the one component is "rich" you should probably do that. | | Using more complicated _components_ can be a reasonable idea, | like using a graphing widget or a maps widget, but you can do | those things without making your entire app an SPA. | | I just don't buy the "you might need to make your app an SPA | some day to you might as well take on the technical burden from | that decision _now_ " idea. Very very few projects need to be | an SPA, and when you have one it's probably pretty obvious. | caymanjim wrote: | Non-SPA feels slow. It doesn't matter that much if it's | slower or not, because the perception is slow. If I'm on a | page, click on something, and in the background it loads some | new content and updates part of (or even the entire) page, at | least while I'm waiting, there's usually something else to | read or potentially interact with in some way. Maybe there's | a spinner for requests over ~200ms. It feels like the app is | doing some work but it otherwise present. If every click | results in a new page render, my browser immediately clears | the page and I'm left looking at a blank page waiting for | content to render. Even if that somehow takes half the time, | it feels like an eternity, and there's nothing for me to look | at while I wait. And that full-page redraw is visually | distracting. | e67f70028a46fba wrote: | Many SPAs I use feel glacial compared with MPAs. You can | tune either approach and htmx apps take away the clunkiness | of full page refreshes. | bulatb wrote: | > I just don't buy the "you might need to make your app an | SPA some day to you might as well take on the technical | burden from that decision now" idea.* | | I'm not selling that idea. "Boil the ocean now in case you | want a cup of tea tomorrow" is a fantastically effective way | to fail. | | _> > If your problem and requirements are such that you will | always be outside the part of the solution space that SPAs | are meant for | | > That seems like a very very strong claim._ | | By that wordy garbage I was trying to contrast the very | extreme, where HTMX is an obvious fit, with points further | down the spectrum where it's not so clear. You could go full | SPA on an HTMX-shaped problem, if you wanted to, or full | progressive enhancement on an SPA-shaped problem; I can't | think of any technical thing that would stop you. There would | just be consequences and it's up to you if they're worth it. | | _> Like what do you think actually needs to be an SPA?_ | | I think a move to SPA gets more attractive when you have 1) | ad-hoc client-only state 2) that shouldn't be explicitly | reflected in your server-side data model 3) produced without | coordination by different independently-enhanced components | sharing a page 4) which causes unexpected interactions | between them. | | SPA is not the only way to solve that, solving it is not the | only benefit of SPA, you could just ignore it and accept the | combinatorial growth of your state space, a hundred other | caveats. It's an engineering question which should get an | engineering answer maximizing benefit by balancing tradeoffs, | but IMO that's not the treatment it usually gets. | traverseda wrote: | >I think a move to SPA gets more attractive when you have | 1) ad-hoc client-only state 2) that shouldn't be explicitly | reflected in your server-side data model 3) produced | without coordination by different independently-enhanced | components sharing a page 4) which causes unexpected | interactions between them. | | That's a lot of what I was thinking about when I was | thinking if discord really needed to b an SPA, all that ad- | hoc client state would need to be reflected on the server. ___________________________________________________________________ (page generated 2022-03-29 23:00 UTC)