235

Modern JavaScript for Django developers

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.

2 days agonilsbunger

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

2 days agoblopker

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

2 days agomichaelcampbell

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

2 days agobkovacev

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

2 days agonprateem

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

2 days agobkovacev

The ability to use django is the main attractor. The other frameworks are great but make you reinvent Django if you require auth, orm, admin, etc

2 days agoWD-42

That would have been my argument exactly - I am not saying that Django fits every use case, but with my limited exposure to projects that have ended up using non-Django Python API framework, they ended up recreating the batteries included approach, with probably way too many issues waiting to be discovered with manually rolled out auth, middlewares and ORM.

2 days agobkovacev

It's such a shame Pyramid isn't more popular. I think you'll find what they have recreated is not Django, it's Pyramid.

The thing is, Django isn't just a web framework. Django is a CRUD app framework. It's great for building CRUD apps, but that's about it. In other words, it makes the easy stuff easy, but doesn't help with the hard stuff (in fact, it often hinders it).

I think the real reason for using Django is the "app" ecosystem. You wouldn't be able to get Django-style packages with Pyramid. It's possible with Django, though, because it's a CRUD app framework.

If you're not using "apps" then I guess the only other reason is the community support that you probably won't get from Pyramid + SQLAlchemy or similar.

2 days agoglobular-toast

The apps are a major sell like with any ecosystem. But don't forget you also get a stable, mature project, excellent documentation, a pool of developers, etc.

2 days agonprateem

> But don't forget you also get a stable, mature project, excellent documentation, a pool of developers, etc.

You get all of that with any of Pyramid, Flask, FastAPI etc.

As for "pool of developers", I would expect any backend web developer to be able to pick up anything in a couple of days at most.

18 hours agoglobular-toast

Oh but you wouldn't reinvent Django, you'd build a properly architected, simple system.

2 days agoglobular-toast

Of course you would.

2 days agoWD-42
[deleted]
2 days ago

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.

2 days agoscrollaway

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.

2 days agohalfcat

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.

a day agoscrollaway

Backward compatibility is great. Your team needs to learn one thing, and it will work with minor modifications and get security updates until after you’ve retired.

SQLModel uses SQLAlchemy, which is database-agnostic. Not sure why this is a problem though. The benefit of the ORM is not being agnostic, it’s in managing schema changes under source control and automatic admin interface.

In my experience, the FastAPI-grab-bag always ends in regret, wishing we’d just used Django. It just works, and it has things you don’t even know you’ll need. If you get to the point where Django is the problem, you’re still glad you picked Django because you’ll be able to modify it to suit your needs. It brings convention without being enforced, and it’s pluggable. You can just not use forms (I never have), or templates (I like htpy), or not use the ORM, or use a different ORM. Django is just a request-response handler that’s already thought of everything you might need. If you want the FastAPI/pydantic approach you can use Django-ninja.

You can piece together your own car, but you’ll get a lot further if you just pick a Toyota Land Cruiser and drive it for a couple decades.

a day agohalfcat

Being database-agnostic is not a problem per se. SQLAlchemy provides highly postgres-specific classes for the databases. The way Django implemented database-agnosticism is bad, because it's lowest-common-denominator which dragged all implementations down with it. They are pulling back from that now with a contrib.postgresql module but it's too late, there's a lot of old cruft now that forced design to be less-than-optimal on postgres.

I've done all four approaches on four different startups. Pure Django; DRF+React; FastAPI+React; Django-Ninja+React. The last one is the best, but from my experience, it does seem like SQLModel/FastAPI/React will be the route to go towards, but with some solid libraries to replace the still-useful batteries in Django: Authentication, Administration, Migration.

15 hours agoscrollaway

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.

2 days agoCapricorn2481

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.

2 days agoMrJohz

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

2 days agodiggan

Yes, exactly. It's not about popular use cases that make webpack better. The best way to claim that some other tool is better would be to have a side by side comparison of some not so straight forward configs.

2 days agoveidelis

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.

2 days agohomebrewer

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

2 days agodiggan

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

I suppose the patronizing attitude is the price for you sharing your wisdom with us.

FWIW I will also echo that webpack is very slow for me. For my current project, the initial build times were ~10 minutes and eventually balooned to 15+ after which I switched to rspack (~10seconds build times now). This comes with some caveats like I had ts typechecking vs swc (but I have ts watching separately, and it takes longer than rspack but is still around ~20s). For webpack 4, speed-measure-plugin used to work well (a long time ago I remember sass-loader being a bad bottleneck), but for v5 I've spent a decent amount of time trying to figure out issues, and it wasn't a simple process. The stats.json that gets generated was malformed for me, and I had to either modify it by hand, and even then it was pretty opaque. And I wasn't about to dive into profiling the node runtime to sort out the webpack issue because that time would be better spent on something like optimizing the chunks.

And I was using webpack because while the inital build times were slow, the incremental builds were really fast. Vite is horribly slow on refresh if there are a lot of files.

2 days agopreommr

> I suppose the patronizing attitude is the price for you sharing your wisdom with us.

Beats passive aggressiveness I suppose?

> FWIW I will also echo that webpack is very slow for me.

Judging by your description, and surely missing even more context, it sounds like individual loaders/modules are/were slow, rather than webpack itself. But since you switched webpack for rspack (with assuming, the very same loaders/modules) and it got faster, that would seem webpack being the slow part, so who knows what the core problem is/was.

Personally I haven't hit any performance issues with webpack + lots of code, but then I mainly do JavaScript and try to stay away from TypeScript, maybe this could explain the difference in experience.

In the end, we use the tools that work best, and if that happen to be Vite instead of webpack (or vice-versa) for you, then there isn't really much to discuss :)

2 days agodiggan

> like individual loaders/modules are/were slow, rather than webpack itself

tbh this is just nitpicking, I'm not a react developer to do CRA debugging for them. They're paid by Facebook a couple orders of magnitude more than what we're making here, and if they're fine with the intact CRA configuration being that slow, while a third-party alternative rips through the massive pile of shit I'm working on while not bringing any obvious downsides, I'll just switch to the alternative.

It's a well known problem: esbuild, which is the base of vite's HMR, boasts of speeds dozens to hundreds of times faster than webpack:

https://github.com/evanw/esbuild?tab=readme-ov-file#why

2 days agohomebrewer

Thank you, well said. I'd like to add that one should try to understand (not saying Homebrewer didnt) what was the cause/bottleneck. Such general statements about "performance" are of little value without deeper insights about some particular problem or use case.

2 days agoveidelis

I don't think so, it's just a massive intranet project with tons of third-party dependencies¹ that spews out a 20 MB minified JS build. I don't think we even modified the original CRA configuration. No typechecking, no eslint or anything else during the build process, they were all run separately when they were needed.

1: like support for various file formats that are constantly needed by every user and it makes no sense to lazy load them

2 days agohomebrewer

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

2 days agohu3

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

2 days agoopenrisk

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.

2 days agoskydhash

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.

2 days agofmnxl

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.

2 days agospapas82

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.

2 days agoSCUSKU

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

2 days agospapas82

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.

2 days agofmnxl

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

2 days agoJodieBenitez

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.

2 days agosinghrac

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.

2 days agoomarspira

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.

2 days agoomarspira

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

2 days agosinghrac

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

2 days agotubs

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

2 days agoqwertox

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.

2 days agoxdennis

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?

2 days agosinghrac

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.

2 days agoglobular-toast

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/

2 days agoadrianh

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.

2 days agocynicalpeace

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.

2 days agogiancarlostoro

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/

2 days agoleetharris

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.

2 days agoadamrt

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.

2 days agooooyay

Also I think most people don't know how much you can scale with gunicorn+gevent before attempting to migrate to ASGI.

2 days agofmnxl

ASGI support for Django landed in 2019. Those comments are very outdated

https://docs.djangoproject.com/en/5.1/releases/3.0/#asgi-sup...

2 days agoairstrike

tbf it was borderline unusable until they added async DB query support in 4.1 (2022) - before that you had to wrap every DB query with sync_to_async, async_to_sync and it generated too much boilerplate code..., and even in 4.1 the DB queries themselves were still sync/blocking, not truly async because at that point they didn't yet rewrite their database "backends" to use async querying, and I believe that as of now the Django's DB engine still doesn't support natively async DB queries/cursors/transactions/...

Also, lots of the "batteries included" into Django don't have async interfaces yet.., for example the default auth/permission system will get async functions like acreate_user, aauthenticate, ahas_perm only in 5.2 which is expected in April 2025, so as of now these still have to be wrapped in sync_to_async wrappers to work...

2 days agoblack3r

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.

2 days agokstrauser

> If those opinions match what you're trying to do and you can stay on the golden path, it's freaking great!

That's a great summary. I wrote a few significant flask apps many years ago as well and I'm a huge fan of SQLAlchemy. My flask apps were greenfield so I ended up building crappier versions of alot that Django provides. I still enjoyed it but I wasn't as productive. But with a legacy integration, it would be hard to beat SQLAlchemy (I think its great for greenfield too). I've basically landed on your comment above as well.

2 days agoadamrt

> less pleasure to integrate with existing databases

Why even do that? Our app integrates with multiple databases and the Django ORM only knows about one of them. For the rest, we use plain SQL.

2 days agojgalt212

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

2 days agopier25

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.

2 days agomorbicer

Sounds like a great market for motivated, practically minded devs then right?

2 days agojoshlemer

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.

2 days agocjohnson318

It’s downvoted because even if PHP has hacky behavior; he’s running with the assumption other frameworks don’t have their own hacky behavior, or other frameworks are worse.

This is not necessarily warranted. Modern PHP is faster than Ruby in many benchmarks; and Rails is still running GitHub and Shopify. Square uses Laravel in a backend serving 100M+ requests per day, with no plans to rewrite. To compare it to a Steam engine and Coal; that’s unfair stereotyping.

On that note, JavaScript’s amount of churn could be an entire discussion by itself. I’ll take some quirky behavior that just keeps working over mindless churn any day.

2 days agogjsman-1000

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

2 days agorob

Dotnet for backend and SvelteKit for frontend.

2 days agopier25

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.

2 days agonop_slide

And Phoenix/Elixir has LiveView, also excellent.

2 days agolawn

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.

2 days ago7bit

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?

2 days agograemep

Wsl2 is the way. And for php development, use ddev.

2 days agonchmy

I could solve these issues with the suggestions you made, but why? I can develop stuff in many languages directly in Windows just fine, and I frankly am not willing to jump through hoops so I can do the same stuff with PHP -- that I can conveniently with Python, JS, dotnet, Java, Elixir, Rust, C/C++ and many other languages. I never found anything so complex and buggy as PHP.

2 days ago7bit

Certainly if you do not like PHP. However, if you wanted to use it there is no real reason not to.

My usage of PHP has been using software written by other people but customising - and there is a lot of useful stiff written in PHP. I prefer Python if doing something from scratch, but I would rather write a small amount of PHP to add a bit of functionality rather than write 10× the amount of Python because I need to write everything from scratch.

2 days agograemep

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.

2 days agolowercased

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

2 days agorunekaagaard

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

a day agogiancarlostoro

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.

2 days agoselecsosi

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?

2 days agoneonsunset

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.

a day agogiancarlostoro

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.

2 days agocwales95

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.

2 days agolastofus

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.

2 days agocwales95

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.

2 days agoskuxxlife

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.

2 days agojilles

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.

2 days agoazemetre

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

2 days agodrdaeman

"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"

2 days agoriskable

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/

2 days agoandy800

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.

2 days agoazemetre

As a CEO of HTMX, I'm qualified to say that recursivedoubts is best described as a grug-brained developer.

https://grugbrain.dev/

2 days agoandy800

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.

2 days agoharrall

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.

2 days agoevantbyrne

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.

2 days agoandy800

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

2 days agodimgl

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

2 days ago65

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.

a day agodimgl

[dead]

2 days agocanadianfella

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

2 days agoggregoire

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

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

2 days agoryannevius

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

2 days agobkovacev

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

2 days agogodtoldmetodoit

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

2 days agowinrid

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

2 days agoanentropic

Old is a harsh word, maybe mature would be a better fit, not everything new and shiny is gold, and yet not everything old sucks.

Not arguing here about types and Pydantic being faster than the built in ModelSerializers. However, for serializer speed improvements and performance in DRF I would advise dropping ModelSerializers and either going for Serializers or plain dict. Haki Benita has a beautiful article on that [0]. I was able to accomplish sub 200 response times on a fairly large response from tables that had tens of millions of records.

I think you have no objective reason other than your styling and rather personal preference for function based views?

[0] - https://hakibenita.com/django-rest-framework-slow

2 days agobkovacev

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.

2 days agoholler

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.

2 days agoggregoire

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

2 days agodarkteflon

Doesn't seem impossible to make it work with Django, but I doubt you can reuse Django Auth.

PostgREST uses the roles and privileges of PostgreSQL to verify if a request is allowed. So, while you can indeed add a PostgREST on top of the schemas generated by Django ORM, you would still have to manually create those roles, grant them some privileges and them assign those roles to your existing users (I'm not familiar with Django but, I guess, that would mean adding a field "role" to the Django model, applying the migration and then manually filling the column "role" in DB with the role you wanna give to each user). And then you would need a login endpoint that returns a JWT token containing the role assigned to this user, and then use this JWT token for all your requests. That's how auth and permissions work in PostgREST and it's one of the big benefits of using it IMO.

Also, I personally like to make views and expose those views to the PostgREST API, instead of exposing directly the tables. But exposing the tables generated by Django ORM would work too.

a day agoggregoire

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

2 days agoyoyohello13

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

2 days ago0xblinq

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.

2 days agoDangitBobby

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?

2 days ago0xblinq

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.

a day agoDangitBobby

> the lack of hot-reloading is painful

This works perfectly fine for me, both in the Rails and the Adonis projects. In both cases using Vite. Sounds to me like a misconfiguration somewhere.

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

How's that "custom code" for flash worse than having to add custom code for routing, authentication, sessions, validation, etc?.

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

Ha! bingo!... you're like half a year late on this. Remix is not the thing they push for anymore. It's having a "nap" they said. Now you're supposed to be using react router in "framework mode". This is exactly what we're talking about here.

a day ago0xblinq

I used Inertia years ago, pretty sure vite wasn't a thing at the time. You can try to blame me if you want, I don't mind, there's a chance hot-reloading would have been possible with more time commitment. At the time, there was only one (unofficial) Django app for Inertia support and it required some fiddling and enhancements to even get working. Ultimately I think I just have solutions to the problems it solves that I prefer and won't be looking back.

It's worse because the frontend people working on the app all had experience with the React stuff you mention but none of the special Django or Inertia stuff we had to do to make it work. Also it was much easier to find glue code online for those solutions at the time.

a day agoDangitBobby

I think a big part of your bad experience is probably due to the django adapter which seems to be the less well maintained out of all of them.

Even more, maybe it's not even the django adapter but the overal "assets" and frontend stuff integration in django which is somewhere between non-existent and 15 years outdated.

I can guarantee it works incredibly well with Laravel, Rails or Adonis.

a day ago0xblinq
[deleted]
2 days ago

Crazy that even this article is now dated. Many people have now moved on from webpack to vite.

2 days agojoshdavham

I like this setup, but I had kinda thought "modern" javascript had mostly moved to server-side rendered at this point and I didn't see anything about that in the syllabus. Anyone know if this tutorial addresses that kind of thing?

EDIT: Nevermind I guess this is the HTMX example? But how would this compare to manually building something with next.js as part of your front-end build and incorporating those assets into your templates?

2 days agosailfast

You can do essentially the same thing with Next or Nuxt.js

With Next.js now it is very easy and elegant to load up data from your Django server in a React Server Component. You can also build entire static pages manually from the same API.

Here is an excerpted example from the same simple template I posted in response to an earlier comment - https://github.com/ospira/docker-django-react-example/blob/m...

If doing this as part of a production pipeline you would have to ensure some version of your Django API (hopefully the latest one) is present before deploying the Next.js app, so that the data is available for Next to do things like fully static pages.

2 days agoomarspira

I've been working on a Django + Vite + HTMX + Alpine project for the past year or so

Using django-htmx and django-vite libs (the latter forked to add Jinja support)

Been pretty happy with it

The main wart I find is the lack of type-safe templating in Python, feels primitive and clunky compared to what you have with TSX in a React project

Been using Jinja macros as 'components' which... works. The syntax is kinda ugly to read though, and haven't found any really great linter.

2 days agoanentropic

Kotlin is an awesome back-end language with strong typing, tons of libraries and multiple HTTP frameworks (http4k, ktor, vert.x, many more) and templating options (jte is terrific, and fully typed). Guessing it's too late to switch now but worth checking out.

2 days agoandy800

> lack of type-safe templating in Python

Try htpy. It moves templating into python where it can be linted/typed: https://htpy.dev/

2 days agomixmastamyk

Yeah this is probably the way to go in future...

The only thing putting me off currently is https://htpy.dev/faq/#how-does-htpy-performance-compare-to-d...

It would be awesome if Python community can get something with these ergonomics that also has performance of Jinja

2 days agoanentropic

I played with the benchmark and the extra delay was not significant, maybe 20ms for a substantial page? I profiled the code and did not find it doing anything particularly wrong. However it uses generators to build the page lazily from fragments at runtime, whereas jinja gets a boost from “compiling” them somehow.

I believe one could prerender the static parts of the page and get most of the speed of jinja, but the improvement still won’t be noticeable unless the project is very performance sensitive.

a day agomixmastamyk

I can also highly recommend JinjaX [0] as a way to introduce a much more ergonomic component syntax in Jinja2 templates. We have been using it for almost 2 years and have only recently started to write new templates in htpy as a way to attain greater type safety.

[0] https://jinjax.scaletti.dev/

2 days agojakobgm

I looked closely at it for this project... in some ways very appealing!

However to me it seemed like it would mostly improve the ergonomics of using components, whereas the ugliest template code I had was in the component definitions themselves and I think it wouldn't help much there.

Also, for my specific case we were deploying to AWS Lambda and I wanted to pre-compile all the Jinja templates. But JinjaX instantiates its own jinja env so our pre-compilation step (from top-level Django jinja env) couldn't reach the JinjaX defs. Probably there is a way to hack that into working.

2 days agoanentropic
[deleted]
2 days ago

I wish there was some way to just get react-style data bindings, html generation from JS, and code organization, while still hosting from purely a flask/django backend. The traditional split of a flask API and a react frontend consuming it, just feels like overkill.

Plus native JavaScript+html is just so close to a complete solution these days. I don’t miss components at all. I just want better code organization.

2 days agochis

I have found that inertia.js is a great solution, it basically allows you to program in your traditional back end multi-page application, MVC kind of style, but with all the benefits of an SPA. So, you get to skip writing an API and just pass data into a view like in the old days, but the view is a React component (or Vue or Svelte)

2 days agojoshlemer

I don't understand the second sentence. As someone developing web apps for over 20 years, components ARE the better code organization.

2 days agomorbicer

Well there's a cost to that abstraction, e.g. you'd have to pass the context into the component, so every time you need to modify the component's schema/props you'd need to change it twice, both in the parent and the component.

You must have seen some huge React components with 20 different props or even more, and you'd need to think about memoizing those props to prevent a re-render, etc etc.

I've also been a web dev for over 20 years, and 10 years with React. I'd say that going back to native HTML APIs for handling stateful things like forms and form validation is a breeze, rather than writing components and endless abstractions. It's enough for the vast majority of the time.

2 days agofmnxl

Those are just shitty codebases. I maintain a React app that's over 10 years old, almost milion lines of code and we have zero components with 20 props, no issues with performance or whatnot.

I am an oponent of over-abstraction but components are very light abstraction and provide just sensible encapsulation and reusability.

2 days agomorbicer

Show me this amazing site of yours. With that amount of talent maybe you should go over to Next.js and solve their RSC issues.

2 days agofmnxl

I'm really curious too, the only codebase I've seen that was like their description with react treated different pages/routes as one massive separate component.

Not exactly utilizing the benefit of JSX but it's a pattern you might blindly fall into if you only came from a templating background.

2 days agoazemetre

I can't, our app is enterprise SaaS built as SPA. Nextjs is imho garbage. The only reason I can imagine it is so popular is that average React devs are indeed very bad with code organization. If I needed server rendering I would go with Astro + interactive islands.

2 days agomorbicer

I see, you're talking about a fully client-rendered SPA. I guess you can always count on your users running modern PCs, with fast internet and no SEO needs. Things aren't that nice in the outside world lol.

2 days agofmnxl

Check out https://django-bridge.org/

It allows you to use a regular Django backend with views, forms, urls, etc but render the UI with Javascript

2 days agokaedroho

You might like Vike (it'd be an Express backend but generally people like Express)

https://vike.dev/

2 days ago65

Claude suggests preact+htm, to get pleasant html generation and react-style imperative state transitions but avoid a build stage. I will give it a shot

2 days agochis

This guide is a bit over two years old. Can someone comment on whether it still holds up and the tools recommended are still being recommended today?

2 days agocdfuller

Author here. I would say the core principles still hold up well, though the tooling and libraries are constantly evolving.

An incomplete list of things I'd add / change today (and are on my roadmap to cover in more detail):

I would probably recommend Vite over Webpack as the main bundler/builder, as it's faster and rapidly taking over as the default tool to solve the same use cases.

The other gap that is missing is a treatment of the "nobuild" options that exist today. Essentially things like ES modules and import maps and other stuff that lets you (if you want) run a lot of modern JavaScript libraries with zero toolchain directly in the browser.

I'd also want to revisit the fully decoupled approach a bit more. With the advent of LLM-based tools that can generate complete front ends for you, as well as libraries like shadcn, there is a larger upside to adopting the complexity of the decoupled API set up, even if it definitely still is slower and more painful for anything that touches the backend.

Django ninja has been gaining traction against DRF as an API library and the developer experience and performance are definitely better, though DRF still has way more batteries in terms of 3rd party library support for various use case.

The Django + HTMX + Alpine stack has only gotten more widely adopted since I published Part 5, and I'd say that part has held up quite well in the "low to no JavaScript" ecosystem for Django, and is the default choice for many Django devs now.

2 days agoczue

The low javascript django approach definitely appeals when starting a project, but I'm trying it and feel like I hit an awkward patch very quickly: submitting nested forms.

For example, an Allergy can have many Reactions, a Reaction can have many Manifestations. The form layout looks like it should capture which Reaction a Manifestation has a foreign key on:

Allergy

-Reaction 1

--Manifestation 1

--Manifestation 2

-Reaction 2

--Manifestation 3

But when you actually click submit, it's not easy to figure out which Reaction a Manifestation is on. Asking other places it seems like there isn't great html support for nested forms. So any solution is either going to serialize the form on the client side to a json before sending, or some inline formset factory solution. I feel like submitting nested forms must be a common case, but none of these have the simplicity I hoped for of django taking the request.POST and giving me the allergy, its reactions, and for each reaction their manifestations.

Do any of the solutions in your guide fit particularly well? Would your client send it as a json? Feel like you must have come across this and curious what your choice would be. In any case thanks for the article.

9 hours agodematz

Can you explain further on the performance aspect of Django Ninja vs DRF?

2 days agobkovacev

It is built to fully support asynchronous endpoints, and uses pydantic models for validation and parsing - lightweight and nicely fast

2 days agoe-brake

Excellent article - thank you for posting.

2 days agograjaganDev

> A Crash Course in Modern JavaScript Tooling. Don't worry—it's not as bad as it sounds.

Then proceeds to introduce the same confusing garbage JavaScript tooling that you find in all other modern JavaScript documentation.

In all seriousness, this is a really nice write up, I like the structure and it actually makes me want to give want to give VueJS and Django another go (being sort of locked in on VueJS because that's what our internal framework uses).

One thing that always have me a bit concerned is how to do localization. Django have built in localization support, but how well will that carry over to the JavaScript part of the code?

2 days agomrweasel

My opinionated view, based on the ancient katra of code practitioners - seek smaller code, fewer dependencies :

When moving from PHP, better to ditch 'modern' over-engineered compiled javascript, and instead use javascript at first procedurally to get acquainted, then gradually use functional idioms from a good example library such as Ramda.js to reap language and productivity benefits over PHP-the-language.

I live in hope that tomorrows code thought leaders choose vue.js over the byzantine-borg-machinery that is the modern react ecosystem.

The good parts of Javascript [ which dont include prototype OOP ] make for a very productive language.

The node.js ecosystem is incredible for getting stuff done, I just hope we dont kill it via forced 'modernization'. We have a generation of javascript developers who have only known javascript as a compiled language.. and the current will use LLMs to spew out react apps, not apps that use standard web apis. The react+build+bundle ecosystem is so verbose that you almost need an LLM AI assistant frontend to do the grunt work.

Its a sad quirk of history that python has become the lingua franca for AI .. javascript is a better language, and great at all that wrangling of data before you pass it to the matmull compiler [ a case where you actually need compilation to better fit the lower level NPU/GPU ]

While Im channeling my inner boomer, I have to say, hand on heart : callbacks are more elegant than async/await/promises/then .. and they are a better conceptual match for the underlying reality. The future has been here for some time and it is multicore - perhaps our sequential mindset is preventing us from adapting as an industry to software that makes use of very many cheap cores?

2 days agojgord

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.

a day agokerkeslager

Cory, your content is killing it :D

2 days agomlamina

Oh god not another plug for htmx

20 hours agosublinear

Oh yeaaaaaaaaah