7 ms·
Show HN: Django Keel – 10 Years of Django Best Practices in One Template
After a decade of shipping Django to production, I got tired of solving the same setup problems on every new project.
Environment-first settings. Sensible auth defaults. Structured logging. CI from day zero. Pre-commit hooks. Docker. Security hardening. Every project meant two days of boilerplate before writing business logic.
So I built Django Keel: a production-ready Django starter that eliminates the yak-shaving.
GitHub: https://github.com/CuriousLearner/django-keel https://github.com/CuriousLearner/django-keel
*What you get*:
- 12-factor config with environment-based secrets
- Production-hardened security defaults
- Pre-wired linting, formatting, testing, pre-commit hooks
- CI workflow ready to go
- Clear project structure that scales
- Documentation with real trade-offs explained
*Background*:
I maintained a popular cookiecutter template for years. Django Keel is what that should've been from the start—battle-tested patterns without the accumulated cruft.
*Who it's for*:
Teams and solo builders shipping Django to production who want a strong baseline without tech debt.
Feedback welcome on what works, what doesn't, and what's missing. Issues and PRs appreciated.
- rbanffy 1y agoThis looks great - I have one concern with tools like this - what is the update flow when the template is updated? This is a thing I've been struggling with - what is the best way of delivering such templates. Is a template generator such as this? Would it be best to copy a baseline repo with all options set? Should we fork that base repo and rebase when the baseline updates?
- sanyam-khurana 1y agoGreat question because this has haunted me for over 10 years with cookiecutter. Most of the time I was copy-pasting newer features from running projects back into the template, and then copy-pasting in other running projects. But Keel is based on copier which has a "pull" based approach. It means unlike cookiecutter where you generate project from template once, you can run `copier update` to update your project with the latest addition to the template. (It takes care of merging based on the initial config that you selected). It's just running one command `copier update`. Docs here: https://django-keel.readthedocs.io/en/latest/?h=copier+update#template-updates https://django-keel.readthedocs.io/en/latest/?h=copier+updat... You don't need to fork it unless you want to make some improvements or build upon the base template itself.
- rbanffy 1y agoThe fork approach came up at work - because all projects have a lot of boilerplate in common (Terraform, K8s configs, secrets, etc) that can receive improvements upstream from the ops team and it'd be nice if the improvements were easy to apply. The `copier` thing is nice. I'll sure try it on my next Django project.
- sanyam-khurana 1y agoDefinitely, if you find anything that can be improved (even if "docs are not super-clear here), please feel free to raise a PR or report it as an issue.
- Hassankhalifa8 1y ago[dead]
- mahmoudhossam 1y agoCruft solves exactly this problem https://cruft.github.io/cruft/ https://cruft.github.io/cruft/
- stevesimmons 1y agoAs someone who up to now has mainly watched Django from the sidelines, as it were, this looks great. What's are your plans for supporting Django v6? (I appreciate it's just gone alpha now, and planned prod release is not for two months.) Likewise for Python 3.14.
- sanyam-khurana 1y agoPython 3.14 is there in the repo, though not added in the docs since I haven't tested it with all the infra stuff. The idea is to keep it updated to at the least previous 2 versions of Python/Django at all times so that it's easier for people to keep their projects updated.
- sanyam-khurana 1y agoHappy to let you know that I've just updated the template to use Python3.14 by default, along with matrix tests that also tests the template against Python 3.14 in here: https://github.com/CuriousLearner/django-keel/commit/87eae7eb35ac4401747e408b9cfccf3a5cc8029c https://github.com/CuriousLearner/django-keel/commit/87eae7e...
- rick1290 1y agolooks great
- stefantalpalaru 1y ago[dead]
- blorenz 1y ago15 years of Django for me personally. I use it now in my SaaS as a data backend with Strawberry GraphQL and lean heavily in on the admin. My frontend is React Router 7 framework mode. I’m going to be checking into Keel for my new toy projects. I wish it would use ty but easy enough to add myself.
- sanyam-khurana 1y agoInteresting! I've loved Strawberry GraphQL. If you end up adding anything, you may also choose to give back to the template so that others can use it. I do not understand what you meant by "ty", though?
- patrick91 1y agoI think it's ty the typechecker :D https://docs.astral.sh/ty/ https://docs.astral.sh/ty/
- sanyam-khurana 1y agoThanks, this seems interesting!
- blorenz 1y agoTy is the typechecker by Astral. https://docs.astral.sh/ty/ https://docs.astral.sh/ty/. Reviewing the dependencies in the jinja file -- how difficult is it to keep these up to date? I see Django Debug Toolbar is still ^4.3.0.
- tmarice 1y agoLooks great, looking forward to trying it. Interesting that you included Temporal for background task processing — did you ever use it in production in a Django project instead of Celery?
- sanyam-khurana 1y agoQuite honestly, I haven't. I've been playing with temporal, and since it's picking up pace, I thought to have an option to have Temporal in place of celery.
- ekinertac 1y agoencountered this post in reddit maybe an hour ago. the comment sections are very different. i'm gonna stick with HN for sure. good project though. using copier instead of cookiecutter is a good choice.
- sanyam-khurana 1y agoIt was all great on Reddit, though until some folks decided to downvote for no apparent reason and then deleted their accounts. I've chosen copier because of all the pain I've gone through for years just to keep my template and projects running in parallel updated.
- ekinertac 1y agoone small note, you should move quick start section in README to be seen earlier
- sanyam-khurana 1y agoThank you for your suggestion. I'll update the README so that people can hit the ground running faster!
- adastra22 1y ago> pytest - Comprehensive test suite (80% coverage minimum) Why would this ever be less than 100%?
- sanyam-khurana 1y agoIt's configurable. The minimum quality gate check is set at 80% here: https://github.com/CuriousLearner/django-keel/blob/main/template/%7B%25%20if%20dependency_manager%20%3D%3D%20'uv'%20%25%7Dpyproject.toml%7B%25%20endif%20%25%7D.jinja https://github.com/CuriousLearner/django-keel/blob/main/temp... Also, to answer why ever be less than 100% is that it depends. Usually, I prefer writing behavioural & integration tests, over chasing per-line coverage which might give a false confidence. I'm not saying getting 100% coverage is bad, but with my experience working on several different projects, I've seen that the last 10-20% is usually low-value surface. For critical modules like auth, money, policies (business-logic), should aim at close to > 95%. When you reach that 100% mark, in my opinion, you might have to write brittle tests which slows down your refactoring with little risk reduction. Again, to summarize, it's not a black/white answer on having 100% or no coverage, but this differs from project to project, and generally having anything above 80% that covers the core-business logic of projects tends to work in my opinion.
- adastra22 1y agoIt was not at all clear to me that number was for code coverage. It sounded like it was permitting up to 20% of tests to be failing.
- sanyam-khurana 1y agoInteresting. Do you have any opinion on what this should be rephrased to, so that it's clearer?
- adastra22 1y agoExplicitly say code coverage or lines of code?
- skinnymuch 1y agoNice. Batteries included for major frameworks is always great.
- sanyam-khurana 1y agoYes, I maintained a cookie-cutter template for over a decade, and it was a pain for me to get it updated. I wanted to get something newer, like a copier, which eliminates the pain of updating, while I can focus on building things. I have also added temporal (though still testing it) since it's getting a lot popular these days.
- rasulkireev 1y agoThis looks amazing, but... I have one worry. Granted I have not yet kick started a project with keel, so I might be wrong. I'm speaking from experience of building my own boilerplate. Giving so many options, makes the boilerplate very fragile. I recently starter removing optional bits from my boilerplate, cause it became much harder to manage and made the generation very fragile. Would love to hear your thoughts on this.