Skip to content(if available)orjump to list(if available)

Modern JavaScript for Django developers

Modern JavaScript for Django developers

162 comments

·January 15, 2025

nilsbunger

This is an excellent article, and SaaS Pegasus is a great solution for people starting a project.

But some of the advice here is dated. The architectural patterns are still valid, but the specifics have changed:

* Vite instead of create-react-app (which is unmaintained now) / webpack / babel / Parcel / etc.

* Django-ninja as a lightweight API service.

I think these are important to call out because they really simplify the frontend compared to the previous options.

blopker

I agree with you on Django Ninja, so refreshingly simple compared to DRF. I think Django core needs to adopt something like it.

However, Vite is pretty complicated. I prefer just esbuild if I don't need all the extra features of Vite, which is usually true with Django. I wrote a post[0] with an example repo[1] if anyone wants to see how everything wires up.

With Solidjs, the minimum JS payload is around 9kb, and you get access to the whole JS ecosystem if you want it.

[0] https://blopker.com/writing/07-django-islands-part-1/ [1] https://github.com/blopker/typesafedjango

michaelcampbell

> I agree with you on Django Ninja, so refreshingly simple compared to DRF. I think Django core needs to adopt something like it.

I was going to ask about this with respect to DRF, but you answered it. I am re-learning Django after having been away from it and Python for ~4 years now, and my previous experience was with DRF in a somewhat toxic group so I had less than ideal feelings about it. I know PTSD is a real thing and I don't mean to sound glib about it, but I think I actually had the beginnings of it from that experience.

scrollaway

Adding to the pile that agrees with you on django-ninja.

It's also worth noting that what Django brings to the table is getting less and less relevant in a world where frontend and backend are split.

For example, we use django-ninja. As we started using it, we migrated away from allauth and into authlib for authentication, which doesn't have a tie-in to Django.

We don't use templates, which means we don't use forms. We're moving away from external django apps because they consistently need to be extended, so we tend to copy the code into our codebase and extend directly.

The settings are untyped, which is a PITA; so we replaced them with pydantic-settings: That allows us to use .env files, type them, and we just expose them in settings.py into globals() through a couple lines of code.

Our management scripts make more sense as poetry script, so we don't go through manage.py but instead `poetry run <command>`, which is more standardized and doesn't depend on Django.

We don't even use the django dev server: In order to be more consistent between production and development, we're using uvicorn in "development" mode as a dev server which works just as well. `poetry run dev` is how we run it.

So what does that leave us with?

1. An ORM/data model definition system, which is mostly untyped and the source of many of our issues. This model system also contains weird quirks that have nothing to do with the sql model itself (for example you can't create a UUID field whose default is generated by the db; only in python). This also includes a pretty solid migrations system. 2. The great admin dashboard, which depends on the former.

I see the way the wind is blowing. And for #1, we have this now, which we haven't tested yet but makes complete sense: https://sqlmodel.tiangolo.com/

We still need migrations and and admin dashboard. Once we have those, we will likely migrate away from Django entirely and our stack will look like a few prepackaged bits of FastAPI, SQLModel, authlib, and maybe some standardized db tables.

halfcat

So you’re living out the trope of reinventing Django but lower quality :-)

Maybe ask around about SQLModel. It sounds like the perfect solution, but I’ve never encountered someone that used it and didn’t have the opinion that it isn’t ready for production.

scrollaway

Why lower quality?

Django suffers a lot from having packaged into itself the whole templating and forms systems. It solved a pain point years ago, but it's irrelevant now and it carries that legacy due to backwards compatibility.

Furthermore, Django also suffers due to its legacy of being database-agnostic... which was more relevant in a world where mysql was still seen as a serious competitor to postgres; but now, it's more annoying than anything else.

bkovacev

What seems to differentiate django-ninja over Flask or FastAPI or any Starlette derivative? You mention lightweight as well, can you expand further?

nprateem

Ninja lets you use django. There's less config vs DRF

bkovacev

Aside from the obvious that ninja let's you use django.

null

[deleted]

Capricorn2481

I use both at work. I'm not sure I see any reason why you would use Vite over Webpack, other then a sense that Vite is newer. Is there a reason? They both seem perfectly fine but Webpack is mature with lots of support.

MrJohz

All the different configuration you need for Webpack is built-in to Vite. This includes built-in support for a lot of stuff that would come as separate plugins in Webpack (CSS loading, Typescript support, asset bundling, minification, autoprefix/browserslist-based downleveling, env replacement, etc). But more importantly, it includes fairly optimal configuration.

There's usually an optimal way to bundle your code, and one of the issues with Webpack was that finding that optimal way through a maze of documentation and third-party plugins. Vite does that work for you, because it's mostly a solved problem and it's not that hard. For example, rather than having a number of different CSS plugins that you need to enable and disable in different configurations — just use Vite, which will do hot-reloading of CSS in development and link to the CSS files as external files in production.

In my experience, there are typically two types of Webpack configurations: fairly basic ones that include some essentials but are fairly unoptimised (either while developing or in production), or complex ones that include everything but are brittle and painful to update. Vite gives you the power and optimisation of the latter with the configuration ease of the former.

Also, to be clear, I'm not trying to hype Vite up. There are other similar tools out there, and Vite isn't even the first tool to work like this — Parcel is older and also pretty good at doing zero/minimal-config builds that work how you expect out-of-the-box. Any of these tools are good, although Vite seems to be the most popular right now and so has the most support/documentation/information. But I would generally encourage any project using Webpack to migrate away from that where possible (and where time allows), because these low-config tools are such a timesaver in the long-run.

diggan

> All the different configuration you need for Webpack is built-in to Vite. This includes built-in support for a lot of stuff that would come as separate plugins in Webpack (CSS loading, Typescript support, asset bundling, minification, autoprefix/browserslist-based downleveling, env replacement, etc). But more importantly, it includes fairly optimal configuration.

We're just walking around in circles. Webpack originally came to be because the current (at the time) solutions were too opionated, and what was "fairly optimal configuration" changed so quickly that it seemed favorable to split out the parts that could change, so we could still use webpack but the specific areas within could move forward without waiting for the rest.

Of course this time, we really have found the optimal-optimal configuration that will surely never be updated, because this time we really did it properly.

> Also, to be clear, I'm not trying to hype Vite up.

If your comment contains all praise for a tool without bringing up any of the tradeoffs/drawbacks, then that pretty much labels your comment as "hype" for that particular tool. And if you find that you cannot find any of the tradeoffs/drawbacks, then it's clear as day that you've fully drank the koolaid :)

homebrewer

You must work on small projects or use top tier hardware exclusively because the development startup time of vite vs webpack is simply not comparable. The project I spend most of my time on maintained both build systems for a couple of years, and I used them interchangeably: under Webpack, the development build loaded in about two minutes (sometimes more), vite takes 3-5 seconds. Webpack configs have since been removed.

I also agree with everything MrJohz said about zero (or close to zero) configuration required to use vite.

diggan

> under Webpack, the development build loaded in about two minutes (sometimes more), vite takes 3-5 seconds.

Now it was some time ago since I last used webpack, but if it takes 2 minutes for your build to load (or run?), something is severely wrong and it's not because of webpack.

Migrating your build tool because you're hitting some edge-case or bug you don't understand doesn't bode well for your future use of other tools.

hu3

Isn't Vite faster and less complex? That's my impression.

fmnxl

Having used HTMX and Unpoly with Django, for over 2 years now, I prefer using Unpoly more these days.

Unpoly feels just like Django, it is a more of a framework than a thin layer, but that means it comes with a lot of productive features built-in, albeit opinionated.

It covers 95% of the use-cases of a typical web app, with its layers and forms concepts. E.g. I love creating "subinteractions" with unpoly, where a complex process can be divided into smaller modal forms for creating the "related" objects of a model, which then updates the main form of the model itself. Unpoly makes these simple, and its documentation caters for exactly these scenarios.

spapas82

The funny thing is that unpoly was originally written for ror, but I also agree that its a great fit for Django and its philosophy.

SCUSKU

The one thing I couldn't get past when looking into Unpoly is that if you're in a deeply nested modal/layer, and then refresh the page, it just shows you the most recent modal as a full page. My expectation is that when you refresh, instead it would keep you on the base page, and then wipe all the modals.

spapas82

Unpoly by default changes the browser's history to the url of the modal. Thus when your refresh you'll get exactly that. You can modify that behavior with up-history, see here https://unpoly.com/history-in-overlays

fmnxl

You can set up-history="false" and there'd be no navigation when opening the modal, so when you refresh the page it'd refresh the parent layer not the modal.

What's more arguable I think is how pressing the browser Back button doesn't preserve the layers, but opens the previous page as a full page. I think that can be changed in a config somewhere, though.

JodieBenitez

Same here... Unpoly is a perfect match for Django.

openrisk

The problem in this space is that a quarter of century(!) after Fielding's dissertation [1] we don't have a serious follow up on "Architectural Styles and the Design of Network-based Software Architectures". A blueprint of a class of well constrained designs that can optimized and adapted according to use case.

The missing abstraction gap goes beyond Django (on the server side), and beyond Javascript on the client side. With the hardware and network capabilities of today it should be much easier to create wonderful networked software and mind blowing experiences but the appification of the Web is denying its very essence. The Web has become in essence a conduit for delivering proprietary apps.

What would a worthy follow up look like? It needs to take into account the mobile revolution that happened in the meantime, which sort of requires taking into account clients of very diverse capabilities. It needs to take into account WASM, GPU etc.

[1] https://ics.uci.edu/~fielding/pubs/dissertation/fielding_dis...

skydhash

The solution is to design protocols, not software. MPD is a great example of networked software. You can select any client you like or develop one yourself. As long as you want to enforce restrictions on client, everything nice about networked software goes away.

singhrac

I've tried several boilerplates like SaaSPegasus and one thing I can't really get around is that I feel like the experience of developing in a docker-compose with two build-and-serve containers (e.g. one with gunicorn auto-reload and the other running something like esbuild for the frontend) is very clunky in VSCode?

I feel like I'm doing something crazy, this must be a problem many other people have, but things like language server integration on the JS and Python side separately do not mesh well.

If anyone sees this and has a minimal open source boilerplate to recommend I'd love to try it.

omarspira

So I actually recently dealt with this, sharing this as hopefully it helps you.

https://github.com/ospira/docker-django-react-example

In essence, you need two instances of VSCode running connected to two separate Docker container instances. As I understand it, it's one remote container per VSCode window. Thus, I found this to be best, even though it isn't strictly speaking necessary, but it ends up feeling that way because as you said the language server integration (intellisense and extensions) will not work properly if not connected to the right container.

If you load this up in vs code it should prompt you properly given the presence of the files in `.devcontainter` dir. Having two windows in VSCode is kind of annoying at first, but I found it was actually fine, especially on macOS where tabbing to the other VSCode window (as opposed to ungrouped alt+tab on windows) was painless, and also kept me more organized not having backend and frontend code right next to each other.

omarspira

Btw, two addendums:

1. I fixed some things in that repo, now it should work out of the box. Apologies if the initial version had some bugs, was taking it out of another project, and the first effort at cleaning it up was too hasty. Note it is still however just meant as an example.

2. You actually can run more than one container per window - see here https://code.visualstudio.com/remote/advancedcontainers/conn.... However, I opted for the double window method because I found that cleaner than toggling between in one window. In my template I assume the two windows method because it will load up the proper subfolder (django or react) of the workspace/monorepo depending on which dev container you connect to.

singhrac

This was very kind of you, and I’ll give it a shot soon!

tubs

Why do you need docker to run esbuild? It’s a static binary.

qwertox

Not everyone is aware of this fact. I include myself in the list of those who didn't know that. Most likely because I didn't bother to inform myself because my expectation of the JavaScript ecosystem is that you first need to install npm via node, and then have it pull a huge amount of files just to then have a tool with which you can bundle stuff without then understanding where you need to "install" it. It's a chaotic ecosystem, much worse than Python, and I know and love Python.

``` Major features:

- Extreme speed without needing a cache - JavaScript, CSS, TypeScript, and JSX built-in - A straightforward API for CLI, JS, and Go - Bundles ESM and CommonJS modules - Bundles CSS including CSS modules - Tree shaking, minification, and source maps - Local server, watch mode, and plugins ```

No word of it being a single executable, on the landing page, in the "major features"-list.

`npm install --save-exact --save-dev esbuild`. We have different expectations on how to download a binary.

Edit: I found an instruction on how to get the binary [0], why is this so hidden?

[0] https://esbuild.github.io/getting-started/#download-a-build

xdennis

Nothing is perfect but it's ridiculous to say Node is more chaotic than Python. What's the Python package manager of the month? uv? poetry? pipenv? conda? pip? pyenv? setuptools? virtualenv? venv? pdm? easy_install? pymgr? mamba?

Some only create environments, some only install, some don't even resolve packages, some don't create lock files, some only install python, AND NONE OF THEM agree where to install!

Where does npm install? node_modules and it's been that way from the start.

*I added a fake one to see if people can spot it.

singhrac

That’s a good question since usually these are built into the docker-compose by default. I think my answer would be that it’s to get the same build environment on my Mac as on prod (i.e. a Linux server), but in practice I don’t think platform-specific details matter.

If that’s the case, why not run Python/gunicorn locally as well, and drop docker entirely?

silviogutierrez

I wrote about docker development (and a library that solves this for Django here): https://www.reactivated.io/documentation/why-nix/#native-per...

globular-toast

I don't use vscode but never had this kind of problem. Does vscode try to run language servers inside the containers or something? I don't even know how that would work, to be honest. I run language servers outside of containers and it all works just fine.

giancarlostoro

Having done Blazor with C#. I just want Django to have its own version of Blazor. You never have to touch JavaScript, and / or if you do, its very sparingly. Your front-end either runs AJAX style, or fully in WASM depending on your needs.

I have built some wonderful UIs with Blazor in drastically less time than I would have spent building a JavaScript UI.

HTMX and might be the closest thing to what I'm describing that is actually available for Django today, though minus the WASM capabilities.

leetharris

Laravel has something like this called Livewire. It's excellent.

Laravel is so much better than Django, but I just can't go back to PHP at this point.

https://livewire.laravel.com/

adamrt

I've heard people complain about Django many time on HN. I started using it back in the 0.96 version, so maybe its just a familiarity thing.

But I built 3 large successful applications in it in that time. I loved it. I don't use it regularly anymore since I mostly moved away from webdev, but I recently came back into contact with my largest project I build in 2018/2019 and its been running perfect this whole time and was a pleasure to dive back into.

Django just felt logically organized, documentation was on point, core was very readable (at least then).

I always just felt so productive in it. I know everyone has different opinions, experiences and products they are building, but I'm always surprised with the negative comments. I definitely prefer SSR with its reasonable though, so maybe thats part of it.

oooyay

Most of the complaints I've read about Django on HN have to do with ASGI support - which Django added. They're valid but outdated complaints.

kstrauser

My complaint with Django is/was that it's fantastic for building brand new apps starting from scratch, but less pleasure to integrate with existing databases. The last time I tried to add Django models to a DB we were already using, there was an impedance mismatch which made it hard to fully model, and I gave up trying to get the admin to work well with it. The ORM and admin are 2 of Django's biggest draws, perhaps the biggest. Without them, it's not so pleasant.

That's when I first came to love Flask. SQLAlchemy will let you model just about anything that looks vaguely database-like, and Flask doesn't really care what ORM (if any) you use.

TL;DR Django's opinionated. If those opinions match what you're trying to do and you can stay on the golden path, it's freaking great! Once you get off in the weeds, it quickly becomes your enemy.

pier25

> I just can't go back to PHP at this point

Same.

During 2024 I evaluated multiple backend platforms/frameworks to get away from Node. Laravel is great and modern PHP (the language) is also surprisingly good but betting on PHP feels like betting on coal and the steam engine. The runtime and execution model are extremely outdated and resource hungry.

There are some efforts like FrankenPHP and Swole that package a PHP app to have a persistent execution model. But IMO unless PHP officially adopts this model this will always feel like a hack to me.

morbicer

The job market for php devs is also weird. Very few talented people. Because php jobs on average pay the worst, people who are motivated and smart often learn another language and abandon php. There are some very practical oriented and clever people willing to do php but you have to look very hard.

cjohnson318

I'm not sure why this has been downvoted so much, this guy states something that might upset some people, but then goes on to provide a pretty sober list pros and cons. This is the kind of content that we want to encourage on HN.

rob

What did you end up going with if not PHP/Laravel?

nop_slide

I thought the same. I evaluated the "big 3" (Laravel, Django, Rails) last year and decided to go all in on Rails for solo side web projects.

Was really wanting to like Django since I'm a python dev for my day job, but it didn't have nearly the amount of DX and tools baked in as Laravel/Rails.

Rails has been super fun, I hadn't touched it in 10 years and the additions that versions 7/8 have brought are awesome.

7bit

I tried Latavel, but there were some points that made me want to drop it very fast.

I work on Windows and I chose a PHP variant (don't remember, maybe one that supports threads or async) that did not work on Windows very well. Starting up a Latavel server took minutes. Took me hours to finally find that the PHP binary itself was the root cause. It should not be that way.

Then installing Compose on Windows was horrible. I believe I had to install PHP and compose in C:\php or it just would not work. The compose "installer" did a bunch of stuff to my Windows which I did not want. Installing it manually was a pain in the ass.

All in all, the experience was exactly the same as in the 2000's (horrible).

After I setup my first Latavel project and had some question, it was really difficult to get answers. The docs are really good, but also fragmented as hell with all the approaches one could take to rendering content, depending on what you choose and how you approach it. The forums - although big - seemed dead when I stated my question.

I don't know man, my experience with Django is so much better.

graemep

You are not likely to deploy it to Windows in production, so develop on Windows? Does WSL not solve this problem? Or a VM of any sort?

lawn

And Phoenix/Elixir has LiveView, also excellent.

lowercased

Is unicorn close?

https://www.django-unicorn.com/

Wouldn't be WASM based either, but most of these types of tech aren't (yet?). I'm in the livewire camp with Laravel. I found a bit discussion of a webassembly version of livewire, but I don't think it's on the cards any time soon.

runekaagaard

We've rolled our own liveview and have happily used it in production for several years now: https://hypergen.it/

giancarlostoro

Oooh I am working on a brand new Django based project, thanks for this!

selecsosi

Typed view model bindings to templates was always amazing and 100000x more ergonomic than WPF (in my experience). That being said with so many things going to client apps, I'm less inclined to go w/ server side rendering and treat my backend as a data API so I'm not stuck building that twice.

neonsunset

If you liked Blazor (and it's interesting to hear perspective of someone "outside" the .NET bubble), is there a reason to prefer Python and Django?

giancarlostoro

I feel like I can build web apps drastically faster in Python than with C#. I find myself writing a lot less boilerplate and things, even when using a full stack framework like Django.

adrianh

Hi, I'm one of the creators of Django. For what it's worth, here's what I do for my product Soundslice (https://www.soundslice.com/). I've been working on it full-time for 12 years, so a lot of thought has gone into this.

Soundslice is very complex in its front-end JavaScript. It has an entire sheet-music rendering engine, capable of "responsive" sheet music [1], plus an integrated audio/video player for music practice, a full-fledged sheet music/tab editor [2] and a ton more [3].

In short: we don't use any JS frameworks. It's just vanilla JS — and in this day and age, that is totally fine for building a quality product.

We're disciplined in how the JS logic is structured, trying to find the right abstractions for the concepts of our app, and we use native JS/DOM APIs (which are full-featured these days).

Every web page on our site is served by Django — in other words, there's no single-page-app stuff. I've always found the idea of single-page apps to be "against the grain": it goes against how web browsers are optimized, and it goes against how HTTP/HTML were designed. Plus it adds a ton of complexity that mainly benefits the maintainers of front-end JS frameworks (it gives them power over you).

I think an entire generation of web developers has been misled into assuming JS frameworks are table stakes for building high-quality web apps — and that is 100% wrong.

The time-tested pattern of "serve the initial HTML (with Django or whatever), then add functionality with JavaScript" is solid and helps you build high-quality, maintainable websites.

On a meta note: for years I've sat on the sidelines and rolled my eyes at the frontend JS world, knowing it doesn't affect me or my product. But I've come to realize all web developers — including those who don't choose to use frontend frameworks — do indeed have a vested interest in pushing back against the bullshit. That's because the JS frameworks are making the web crappier, and that affects us all by giving the web a worse reputation. Sites load slower, UI is weird/buggy/non-standard, and the culture perpetuates (meaning it's harder to find developers who know "actual" JS instead of frameworks).

[1] https://www.soundslice.com/help/en/player/basic/100/resizing...

[2] https://www.soundslice.com/notation-editor/

[3] https://www.soundslice.com/features/

cynicalpeace

I basically agree with you, and I love developing a full stack via JS.

Fortunately, with AI, coding with frameworks is a lot less necessary and even more of a hassle now.

cwales95

I think this is a great resource but wish it had not chosen a hybrid architecture. All the guides on decoupled Django seem to choose hybrid. It makes sense because you get the CSRF / XSS safety benefits but I'd love to see how others tackle a fully decoupled Django stack e.g. oAuth, JWTs and how they do their CSRF / XSS security. It's an area I need to learn more about.

lastofus

Decoupled Django usually means that you are providing a client SPA with a API, such as a DRF powered REST API.

If you are using something like token auth (you mentioned JWT), then you are not using cookies, at which point CSRF is not needed. This is because the user's browser isn't automatically sending the cooking containing a session ID on every request to the server.

That said, you can implement session auth with DRF REST APIs, which accept a session cookie on requests. For this, I believe you would receive/send CSRF tokens via HTTP headers.

XSS is not something you would worry too much about in an API endpoint. It is something you should worry a lot about in your client side SPA though. If using something like React, your templates will be auto-escaped, and thus you have to go out of your way to make it a problem.

cwales95

Where I get confused is storing the tokens securely. There's a lot of conflicting information online. I've come across many examples where they suggest localStorage which is a horrible idea.

A lot of the advice I see now is about http-only cookies but I think I'd probably look more into oAuth in the future.

skuxxlife

The current best practice is to keep the token in memory only and store a refresh token in an HTTP-only cookie.

In my experience though, if you’re only doing web-based auth and don’t _need_ to use JWTs for a specific reason, just use regular session cookies, it’s way less hassle. Coordinating auth and refresh state across page refreshes and tabs is a pain, and using a refresh token means you’re using cookies and saved session state anyway, so you lose pretty much all of the unique benefits of using JWTs and still have all the downsides.

michaelcampbell

> All the guides on decoupled Django seem to choose hybrid

For someone ignorant (me), can you expand on what you mean by "Decoupled Django" and "hybrid"?

jilles

I don't think Alpine.js and HTMX qualify as "Modern JavaScript". There is an approach that is rarely talked about: render templates in Django and hydrate using your favorite JavaScript framework.

For example the Django template renders a <template id="abc"><button disabled>open modal!</button></template>. Then your JavaScript bundle can "hydrate". For example ReactDOM.render(<OpenModalButton />, '#abc'').

You just have to be diligent to make sure that the template and your front-end have somewhat similar markup to not have layout shift. It's really not that hard and works for a lot of use-cases.

Not saying this is a golden bullet, but you should be able to figure out which parts are static and just render them using Django templates. The dynamic parts you can render/hydrate using whatever front-end framework.

I built a Django app with very little JavaScript and only using HTMX and it was... alright. It works. I can say "no fancy build step!" but I totally miss the testability of modern frontend. Creating an image upload component was a pain. I don't think I would use HTMX again and instead go for the hybrid approach I described earlier.

azemetre

Why wouldn't Alpine.js and HTMX be modern javascript? They're both written with modern javascript.

React was created in 2013, Alpine in 2020, HTMX 2020. React is the elder of the bunch. React is the bloated tool nowadays.

drdaeman

Personally, I don't think the term "modern JavaScript" makes much sense - it's just a nice-sounding but mostly meaningless buzzword, but I can guess the reason about the disagreement.

Alpine and HTMX are entirely different architectural approach to script webpages, as compared to React/Vue/Svelte/Elm/... approach to build SPA webapps. And the latter approach was very frequently called "modern JavaScript" (and that's why I think it's more of a buzzword now, and less of an actually meaningful term).

riskable

"Modern JavaScript" === "Whatever just came out in the past week to six months and has had several articles written about it on the front page of Hacker News"

andy800

Somewhat pedantic - Using HTMX represents a modern approach to building a web front-end. However, I'm confident that recursivedoubts (creator of HTMX) would agree HTMX is not itself written in modern Javascript. No Typescript, no modules, no functional programming, no async, etc.

https://htmx.org/essays/no-build-step/

azemetre

That's poppycock. A library that doesn't require several dozen unrelated libraries to use is a good thing and something we should actually hold up as good engineering.

I'm also confident that recursivedoubts wouldn't like you calling his library not modern. That's just insulting.

harrall

Things aren’t that rigid. React is just a template library (it doesn’t have any franework stuff at all). You don't have to make an SPA with it.

In 2015 we were doing

$('[data-widget="colorpicker"]').each(() => ReactDOM.render(<ColorPicker />));

Basically what HTMX is trying to do but with jQuery + React. No SPA. Just static pages with dynamic elements.

evantbyrne

I can't speak for HTMX specifically, but going to progressively enhanced server-rendered HTML from React requires a certain amount of mental deprogramming. I've been using Turbo lately for side projects (e.g., Pocket SQL) and found it involves working much more closely with browser APIs, but also writing way less UI code. Pocket SQL required writing about 50 lines of JS and people probably wouldn't notice that it's not a SPA unless they looked under the hood.

andy800

This is often why people get frustrated switching HTMX for the first time. The idea isn't to "translate" the code, but to completely rethink concepts like state and pages and things like components. Not everyone is able to conceptualize their application outside the boundaries of a specific framework.

dimgl

I was doing with this Knockout back when I was using ASP.NET MVC! I'm surprised it's not a more common pattern.

65

Wouldn't this throw hydration errors if your SSR HTML does not exactly match your client side HTML?

dimgl

This implies that "hydration" exists exactly how it exists today in SSR. That's not the only way to hydrate a frontend client.

You could, for instance, as part of a server payload send back a JavaScript object full of state and the frontend will read from it and render accordingly. But that would require not using a framework and building it yourself, which I think developers nowadays aren't keen on doing.

ggregoire

I've seen some companies using React with Django REST Framework [1], to keep the benefits of Django while having a strong separation between front and back (separate projects, teams, deploys, etc).

[1] https://www.django-rest-framework.org

ryannevius

We use Django and django-ninja [1] and like it MUCH better than DRF.

[1] https://django-ninja.dev

bkovacev

Care to elaborate further? I keep reading on this, but no one actually mentions anything specific that ninja does better than DRF.

godtoldmetodoit

The main benefit most people see right away is the Pydantic integration & it requires less boiler plate for basic API's. Ninja is essentially FastAPI + Django.

I prefer Ninja over DRF, but I know plenty of orgs who still love their class based DRF views as once you are over the (significant) mental hurdle of understanding all the abstraction there, it does give you the common CRUD type operations on your models "for free".

winrid

DRF has more abstraction. When I was new to Django I found DRF hard to build a larger API with it and not make mistakes or have things get confusing. You're primarily working by extending classes etc.

With django-ninja you just define your APIs with annotated types as methods, there is no magic, and then you get a generated OpenAPI spec.

this was my experience anyway, I used DRF for this project [0] and ninja for this one [1]

[0] https://govscent.org/api/

[1] https://sidewaysdata.com/api/docs

anentropic

I haven't used django-ninja but to me it looks like the API is a bit nicer or more 'modern' looking (i.e. declarative via type annotations) and it's faster, both due to being based on Pydantic

DRF is old and API looks more like Django forms or class-based views, more of an OOP hierarchy going on, and DRF serializers are slow

holler

DRF has been around a long time at this point, and that's been a common stack (albeit with other frontend frameworks 10 years ago).

In recent times I'm a fan of Starlette, which is what the popular FastAPI lib is built on top of, and created by same author as DRF.

ggregoire

I used to make my APIs with Starlette/FastAPI, didn't know it was the same author!

Nowadays I just use PostgREST for all my new APIs. It's a phenomenal piece of software, save me so much time.

darkteflon

Are there any footguns to be aware of when integrating PostgREST with an existing “low-JS” Django project, do you know? I’m considering it for headless access to an existing Django-ORM managed Postgres instance by a data orchestrator (i.e., not for the web UI). I’d like to be able to keep using Django auth in particular and just wondering if there’s any risk of impedance mismatch (in which case I’ll probably go with django-ninja).

yoyohello13

BTW, this guy's Django templates are really good.

0xblinq

Check out https://inertiajs.com/.

I've never used it with Django (there's an adapter here https://github.com/inertiajs/inertia-django) but I did use it a lot with AdonisJS and Rails.

It's wonderful. The best of both worlds. TL;DR you can use React/Vue as your "template" layer and keep everything in your batteries included backend framework of choice, avoiding all the bull**t and madness going on with Next, Remix, React Router, etc, etc...

DangitBobby

I eventually came to regret using Inertia and just wished we had used e.g. django-rest-framework and React Router. React Router is excellent. I feel pretty much the same way you do about Next.js, though.

0xblinq

I have the exact opposite experience, but context is everything here I guess.

> React Router is excellent.

When you compare it to Next, etc... yes, I agree. The issue I have is the constant change of mind their devs have regarding how to do things, even when they say "it's stable"... it's not... every day they come up with "a better way" to do things which usually is not better, just different.

But using it when you already have django/rails/laravel/adonis means you have to do a ton more work and reinvent a lot of things (such as authentication, validation, etc).

Care to extend on what problems you found or what you didn't like about inertia?

DangitBobby

For me personally, the lack of hot-reloading is painful for portions of the app where it takes you a few steps to get to the UI state you are working on (e.g. rendering a model with tabs).

Having to add custom code to for flash, their special form handling, and other Inertia specific parterns that only I really understood made it difficult for some collaborators. I don't remember the specific of the form handling either but from what I remember it would have been difficult to instrument client-side validation such as react-hook-form as well.

> The issue I have is the constant change of mind their devs have regarding how to do things, even when they say "it's stable"... it's not... every day they come up with "a better way" to do things which usually is not better, just different.

It is annoying. They are pushing people towards Remix as well, which I have tried and prefer to avoid unless I absolutely must have SSR. But their docs for older versions are still around so you can stick to what you like.

kaedroho

Checkout https://django-bridge.org/

It's a similar concept to Inertia but designed specifically for Django

0xblinq

Well, something I do like about Inertia is that it's not tied to any specific framework, neither backend nor frontend ones. That's a big advantage in my opinion.

kerkeslager

The best thing about Django is I don't have to write much Javascript.

Introducing a whole JS build pipeline? I'm absolutely not doing that.

The vanilla JS language is pretty capable these days. There are a few things that are still terrible, but if you're just writing a few lines here and there, they don't really bite you. I can just src a JS file I wrote and get everything I want from modern JS. What I don't want from modern JS is a quarter million 0.x versioned unaudited dependencies for every minor thing that make breaking changes for no reason. The situation with Python packages is already tricky enough.