I spent a couple months last fall1 building a full stack Django+React “meta framework” that attempts to seamlessly integrate Django and React with minimal developer effort. All the decisions about how to structure a project are made by the framework (although many aspects can be overridden).
The big idea behind it is that you often don’t need a sophisticated or complex architecture separating the front end from the back end. In many cases such an architecture only adds overhead without providing any real benefit (NOTE: in many cases but certainly not all).
Additionally, when using Django on the back end, there’s always a question of how to integrate the front end—where do your JS files live, how do you get Django to load them, etc.
DjangoKit makes it easy to get started without requiring you to make too many decisions about project structure up front. To that end, it utilizes file-system based routing that automatically wires up Django and React views, using the latter in place of Django templates by default.
Is this a good idea? A bad idea? The worst idea? Is there any interest in a full stack Django+React “meta framework” like this?
Having created a proof of concept (still buggy and experimental), that’s what I’m trying to figure out.
If this sounds at all interesting, please have a look at the DjangoKit website (built with DjangoKit, naturally). If you have any feedback, you can use the contact form on the home page or submit an issue on GitHub.
Features
- Django on the back end
- React + React Router on the front end
- Automatic integration of back end and front end
- File system based routing
- Convention over configuration as much as possible
- Configuration using TOML files to override DjangoKit defaults
- Configuration using environment variables is also supported
- Scaffolding to generate projects, models, pages, etc
- Server side rendering support (needs work)
- TypeScript support (via
esbuild
) - A variety of customization knobs
- It’s just Django under the hood, so you can do anything you can do with Django
Background
Over the past few years I’ve been getting more and more into front end development. Most recently I’ve worked with frameworks like Gatsby and Next.js (on a project that migrated from Gatsby to Next) and have also been looking at Remix and SvelteKit.
Of these, I think I like Remix the best (so far), but the one issue I always run into with any JavaScript framework is building out the back end, APIs, tooling, etc.
It could just be due to being more familiar with Python—although I’ve been using JS for roughly the same amount of time—but I’ve never found a back end JS framework or ORM that I’m as productive with as Django, Pyramid, SQLAlchemy, etc.
Additionally, when it comes to writing command line scripts or any other kind of tooling, I tend to prefer Python. E.g., Typer is a really nice way to create command line interfaces and console scripts.
So while playing around with Remix a while back (by creating a very basic Twitter clone, as seemed apropos at the time), I decided to try building a similar type of full stack “meta framework” using Django for the back end, seamlessly integrating React & React Router for the front end.
The overarching goal was to create a framework that makes it really easy to get started on full stack projects without having to make a lot of decisions up front—you generate a project, start the dev server, and drop files in a specific directory, which are automatically routed without having to manually add Django URLconfs.
Architectural Notes
The default database back end is SQLite, although this can easily be changed to any other Django-supported back end. The idea behind this is that you can get pretty far with SQLite and that it simplifies deployment and makes backups easy.
There are no Django “apps” since, in many cases, Django projects don’t benefit from being split up into Django’s concept of “apps.” Reusable Django apps are good for sharing functionality between projects, but within a given project, splitting everything into apps often just adds unnecessary clutter.
In terms of implementation, a DjangoKit project is a single Django app, and the terms “project” and “app” are synonymous. If it’s beneficial to add more apps, you can add them as needed (since it’s all just Django under the hood).
File system routing is used by default. Pages (React) and view handlers (Django) are wired up automatically. The reason for this is again simplicity. Pages and their data providers / APIs are colocated and routed using conventions rather than requiring up front decisions to be made about URL routing schemes.
DjangoKit projects don’t need their own Django settings module by default. The reasoning behind this is that we’re trying to use conventions as much as possible, so only minimal project settings are needed to get up and running.
All Django settings can be set via TOML files. In cases where this isn’t sufficient, it’s possible to use a Django settings module as usual to dynamically compute settings (although that is a bit of smell IMO).
You can also specify that certain settings should be loaded from environment variables. Read more about settings here.
Dogfooding
While building the framework, I simultaneously built the DjangoKit website using the framework. This was tremendously helpful in working out various architectural issues, finding feature gaps, and uncovering bugs.
I also rebuilt a side project (MyStops) using the framework, and I think it turned out pretty well. The previous version used Django on the back end and Vue on the front end. The code was split into back end and front end sections and was structurally quite a bit more complex. The new version is streamlined and easier to work on.
Server Side Rendering
Server side rendering (SSR) has been one of the most challenging aspects of this project. In order to keep things simple, the builtin views simply call out to Node in a subprocess, but this isn’t ideal due to subprocess overhead.
This could be fixed by running a Node server to handle SSR, but that would add a decent amount of complexity. If there’s any interest, though, it wouldn’t be too hard to add.
Scalability
While many projects don’t need to worry too much about scaling, DjangoKit projects should scale just like any other Django project.
A Note About the Name
The name is play on SvelteKit. The djangokit.org
domain was available,
so I registered it and only afterward did I notice there’s already
a project named DjangoKit on PyPI. This is why the DjangoKit packages
have names like org-djangokit-xyz
on PyPI (i.e., to avoid naming
conflicts). If anyone out there feels strongly about this, I’m amenable
to changing the name.
Comments, Corrections, Suggestions
This blog doesn’t have a comment system, but you can send feedback via the contact form on the home page or leave a comment on the Mastodon post.
Footnotes
Footnotes
-
It just took a while to get around to writing this post. ↩