13 ms·
Building a fullstack app with Flask and Htmx
- slig 5y agoThe 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 5y ago[deleted]
- jacktheturtle 5y agoThis 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.
- sixhobbits 5y agoif you don't want fancy partial-page reloads and UI interaction, then just Flask + HTML also works.
- dannywarner 5y agoAgree. Simple Flask and HTML gets you a long way and is easy to deploy and manage.
- jacktheturtle 5y agoMight want to give this a try. Thanks for sharing!
- dfinninger 5y agoFlask 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-part-i-hello-world 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 5y agoI work at a company pulling real cash, built mostly on Flask. Flask is one of the things I like the most about the stack.
- toastercat 5y agoEven better: Bottle.py; single-file dependency, includes routing and a simple templating engine.
- atoav 5y agoNot 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.
- toastercat 5y agoI 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.
- lambdaba 5y agoMeteor does this, in JavaScript, with built-in database and no writing of APIs, code is shared between client and server.
- jacktheturtle 5y agoI should give this another shot. I haven't touch it since 2017
- erokar 5y agoI think Rails is the best fit for this, alternatively something like SvelteKit + Supabase (the latter if you need a db).
- jacktheturtle 5y agoRails 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.
- boundlessdreamz 5y agoYou can use bulltettrail https://bullettrain.co/ https://bullettrain.co/ which was recently made opensource (+ paid pro features) for an easier ramp
- jms55 5y agoElixir + 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.
- danpalmer 5y agoOne 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?
- ramchip 5y agoPhoenix LiveView works great for this.
- toastercat 5y agoReplace 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 5y agoThis 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.
- mekoka 5y agoIt 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.
- sgt 5y agoA 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 5y agoI 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 5y agoI 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.
- CuriouslyC 5y agoThe 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.
- kareemm 5y agoWe use HTMX at Savio (https://www.savio.io 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.
- dopeboy 5y agoWe 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?
- kareemm 5y agoIt 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.
- brtkdotse 5y agoBy 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.
- Darmody 5y agoI 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.
- yakshaving_jgt 5y agoI 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.
- sixhobbits 5y agoThey 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-django-developers/htmx-alpine/ https://www.saaspegasus.com/guides/modern-javascript-for-dja... [1] https://www.saaspegasus.com/guides/modern-javascript-for-django-developers/client-server-architectures/ https://www.saaspegasus.com/guides/modern-javascript-for-dja...
- pythonaut_16 5y agoThis 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 5y agoIt'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 5y agoHTMX 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.
- Townley 5y agoI 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
- zdragnar 5y agoBack 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 5y agoPreact / 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.
- digisign 5y agoThe use case here is to add some interactivity to your page, not implement an ecosystem inside it.
- bityard 5y agoI'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.
- tomatowurst 5y agoI 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.
- pythonaut_16 5y agoI'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 5y agoHTMX + Alpine JS seems to be prevalent.
- tomatowurst 5y agotrying 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 5y agoHTMx 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/ https://htmx.org/extensions/web-sockets/
- tomatowurst 5y agoI 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 5y agoGood question - if you do some digging, I'd love to read about how they stack up!
- recursivedoubts 5y agohtmx 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 5y ago
- bulatb 5y agoThis 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 5y ago>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.
- deleted 5y ago[deleted]
- jameslao 5y agoI 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-and-htmx https://www.crocodile.dev/blog/css-transitions-with-tailwind...
- batterylow 5y agoSounds like my stack for https://PlotPanel.com https://PlotPanel.com. It's Alpine.js, htmx, Tailwind CSS, and Django on the back-end. Going to have a read of your article!
- batterylow 5y agoI built https://PlotPanel.com 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!
- number6 5y agoWow 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?
- batterylow 5y agoIt's indeed all Tailwind CSS! This was my first Django project and I started with Django 4. It has form templates that I've overridden to use Tailwind elements. This was quite tricky and meant learning more about Django than I'd expected!
- ricopags 5y agoWent to sign up to tire-kick but no free tier. It isn't evident what data sources the plotpanel site works with.
- batterylow 5y agoThere’s a link just above the tiers “or start your free trial”!
- weakSignal 5y agoYou did impressive work mate.
- batterylow 5y agoThank you - that's very kind of you!
- rufugee 5y agoI 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/ 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 5y agoThis 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.
- zakki 5y agoDo you have a good resource for learning Rails? I have never learned it.
- deleted 5y ago[deleted]
- hokumguru 5y agoI found this youtube channel to be quite nice: https://www.youtube.com/c/CJAvilla https://www.youtube.com/c/CJAvilla
- hifix 5y agoAs a complete beginner to the Rails world (but not web dev in general), the official Getting Started guide at https://edgeguides.rubyonrails.org/getting_started.html https://edgeguides.rubyonrails.org/getting_started.html was a short and sweet way for me to get an introduction to how it works. After that I went through a number of Chris Oliver's GoRails tutorials (https://gorails.com https://gorails.com) which I found really helpful too.
- danjac 5y agoThis 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.
- qatanah 5y agoSomething I've wanted to comment on this as well. It's best to use render_template() when rendering the views so it doesn't tangle w/ a lot of python controller logic.
- nop_slide 5y agoI'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 5y agoRecently 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 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 https://github.com/mikeckennedy/jinja_partials Maybe that's what you're looking for?
- nop_slide 5y agoThis is great, thanks!
- nop_slide 5y agoDoes 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 5y agoThis worked for me https://www.npmjs.com/package/reload https://www.npmjs.com/package/reload
- nop_slide 5y agoDoesn'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 5y agoYou 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 5y agoI have been using Parcel (https://parceljs.org 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.
- hestefisk 5y agoFunny how things come full circle. This is certainly a blast from the past (Rails, circa 2007:)).