zostera/django-bootstrap4: a Bootstrap 4 template layer now in maintenance mode
Bootstrap 4 integration with Django.
At a glance
- What is it?
- django-bootstrap4 renders Django forms, buttons and markup with Bootstrap 4 classes through template tags. The package is in maintenance mode, receiving bug fixes and security updates only, and the project points new work at its Bootstrap 5 sibling.
- Who is it for?
- Adopt django-bootstrap4 for an existing Django project that already ships Bootstrap 4 and wants consistent form and button markup without hand writing the classes. Do not adopt it for a new project, since the package is in maintenance mode, the project recommends django-bootstrap5 instead, and the Bootstrap 4 asset line itself has been superseded.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 10 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 21, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What the template tags actually give you
django-bootstrap4 is a small integration layer whose whole job is to bridge Django's form rendering and Bootstrap 4's class names. The stated goal is to blend the two so that templates stay short, and the mechanism is a set of template tags loaded from a library named `bootstrap4`.
The visible surface in the example is small but covers the most common case. `bootstrap_form` renders a Django form with the Bootstrap classes applied, and a `buttons` block wraps a group of submit buttons so they get the right spacing and alignment. A typical form therefore becomes a handful of lines instead of a loop over fields with hand written wrappers.
The package is a Python library with the module layout to match: a `src/` directory holds the package source, `tests/` holds the test suite, `docs/` holds the documentation, and an `example/` directory contains a working Django project with its own `manage.py`, `settings.py`, `urls.py` and templates. The metadata declares the Django framework classifiers for 5.2, 6.0 and 6.1, so the intended target is a current Django on a current Python rather than the older versions the package started with.
The dependency list has exactly two entries, `Django>=5.2` and `beautifulsoup4>=4.10.0`. The second one is telling: the renderer parses and rewrites the generated HTML, which is how it can add the Bootstrap classes to widget markup rather than asking the developer to add them by hand in every template.
Installing the package and wiring it into a project
Installation is a pip install, and the project also mentions downloading or cloning the repository and running `pip install -e .` as an alternative.
pip install django-bootstrap4The app then has to be registered, because the template tags and the rendering hooks are provided by a Django application:
INSTALLED_APPS = (
# ...
"bootstrap4",
# ...
)Once the app is in `INSTALLED_APPS`, a template loads the library and uses the tags:
{% load bootstrap4 %}
{# Display a form #}
<form action="/url/to/submit/" method="post" class="form">
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<button type="submit" class="btn btn-primary">Submit</button>
{% endbuttons %}
</form>The two steps that catch people are the `INSTALLED_APPS` entry and the `{% load bootstrap4 %}` line, and both are stated plainly here. One thing the installation steps do not cover is the static assets: the package renders classes, it does not serve the Bootstrap 4 CSS and JavaScript, so the project has to provide those itself, and the template above already assumes the `form` and `btn btn-primary` classes are defined.
The other detail worth noting is the requirement wording. The package requires a combination of Python and Django that is currently supported, and the documentation points at the supported versions table on the Django site rather than naming a fixed combination, which is the sensible approach for a library that follows Django's release cycle.
Maintenance mode, and what it means for a new project
This is the single most important fact about the package, and it is stated at the top of the project documentation. Bootstrap 4 has been superseded by Bootstrap 5, and as a result django-bootstrap4 is in maintenance mode. It will receive bug fixes and security updates. No new features or enhancements will be added. The project recommends that new projects use Bootstrap 5 and encourages existing projects to consider migrating when feasible, and it points to a dedicated package, django-bootstrap5, for that.
What that means for a team is concrete. If you are starting a project now, the choice is not between the two packages, it is between django-bootstrap5 and hand written Bootstrap markup, and the sibling package is the path the maintainer recommends. If you already run django-bootstrap4, the package continues to work and continues to receive fixes, so there is no emergency, but the Bootstrap 4 asset line is the thing that will age.
The security update commitment is the part worth holding the project to. A package that renders user supplied form data and rewrites HTML is exactly the kind of dependency where a security fix matters, and the maintenance mode promise is the reason to keep it installed rather than fork it.
The development history supports the same reading. The latest tagged release on the project is v3.0.1 from 2021-05-20, with v1.1.0 from 2019 behind it, yet the version in the package metadata is 26.3, which shows the project moving to a date based scheme for its releases. A version number of 26.3 in the metadata and a v3.0.1 tag on the releases page are two numbering systems for the same project, and a user pinning a version should look at the metadata rather than at the tag list.
The packaging and the developer toolchain behind it
The project builds with `uv_build`, and the build requirements pin that backend to a version range. The runtime requirements are `requires-python = ">=3.11"` and a Django floor of 5.2, and the classifiers list Python 3.11 through 3.14, so the supported matrix is a moving target that follows new Python releases.
The tooling is consistent throughout. Linting and formatting are handled by ruff, configured in the project metadata with a line length of 120, the source directory set to `src`, and a rule selection covering isort, flake8, docformatter and pyupgrade, with the missing docstring rules turned off. Typo checking is a separate `typos` step.
The `justfile` is where the daily commands live. It exports the environment and loads the dotenv file, defines aliases so `just update` runs the upgrade recipe and `just tox` runs the tests, and reads the current version out of `pyproject.toml` with a sed expression so there is a single place where the version is defined. The recipes cover the whole loop:
uv sync --frozen --all-groupsinstalls the development environment from the lock file, `uv lock` regenerates that lock file without upgrading anything, and `uvx ruff format` and `uvx ruff check --fix` format and fix the code. The test recipes run the Django test suite through the management command, with a variant that produces a coverage report:
uv run --no-sync manage.py testThere is a tox configuration as well, invoked through `tox-uv` by the `tests` recipe, so the same suite can be run against multiple environments.
One recipe is worth calling out because it is unusual. The `lint` recipe runs a check that fails if any tracked file contains invisible or bidirectional control characters, using a `git grep` for a list of code points. The comments in the file explain the reason, that these characters do not show up in review, which is what makes them useful for hiding code, and they reference the Trojan Source problem. It is a small sign of how seriously the maintainers treat supply chain hygiene in a package that rewrites HTML.
The example app and how to try the change locally
A worked example ships with the repository, in the `example/` directory, and it is a complete Django project rather than a snippet. It has its own `manage.py`, `settings.py`, `urls.py` and a `templates/` directory, so you can start the project and click through the rendered form instead of reasoning about tag behaviour from documentation.
The documented way to run it is a single just recipe:
just exampleThat is a comfortable way to evaluate a change, because it exercises the same rendering path your own project would use, including the widget markup rewriting that the BeautifulSoup dependency implies.
For a project that wants to try the package before committing to it, the practical sequence is: install the package, add `bootstrap4` to `INSTALLED_APPS`, load the library in one template, render one form, and compare the HTML with what you write by hand. If the generated classes do not match a Bootstrap 4 stylesheet you already have, the mismatch is visible immediately in the example app rather than after a partial rollout.
The repository also carries the files that a maintainer would expect in a project with outside contributors: a contributing guide, a funding configuration, a changelog, a readthedocs configuration, an editor config, a tox configuration, and both `AGENTS.md` and `CLAUDE.md`, which are the instruction files used when an assistant works inside the repository.
What to weigh before you depend on it
The limitation is the one the project itself names. A package in maintenance mode will not gain the features a growing form needs, will not follow Bootstrap 5, and will not add support for new Django features that require template or widget changes. The dependency on BeautifulSoup also means the rendering path is HTML rewriting rather than native Django widget rendering, which is a design choice with a cost: it works across many widget types, but it also means the output is not produced by Django's own form rendering.
The second consideration is the version story. The metadata version and the GitHub release tags follow different numbering schemes, and a team that pins versions has to decide which one it tracks. Combined with a maintenance mode promise, the safest operational choice is to pin an exact version, subscribe to the changelog, and plan the move to the Bootstrap 5 package when the form work justifies it.
The third is the version support floor. The metadata requires Python 3.11 or newer and Django 5.2 or newer, which is a modern floor but still means an older Django upgrade in a project will eventually force a decision about this package as well.
On licensing, the package is BSD-3-Clause, with the licence and the author list files declared as licence files in the metadata. The project credits Dylan Verheul as the original author and Zostera as the developer and maintainer, and the AUTHORS file lists the contributors. BSD-3-Clause is a permissive licence, and reading the LICENSE file for the exact terms is the right step before you redistribute the package inside a larger product.
Editorial conclusion
Adopt django-bootstrap4 for an existing Django project that already ships Bootstrap 4 and wants consistent form and button markup without hand writing the classes. Do not adopt it for a new project, since the package is in maintenance mode, the project recommends django-bootstrap5 instead, and the Bootstrap 4 asset line itself has been superseded. Before upgrading an existing installation, check the supported Django and Python versions, confirm the Bootstrap 4 CSS is still bundled on your side, and read the changelog before the next Django upgrade, since bug fixes will keep arriving without new features.
Frequently asked questions
What does django-bootstrap4 do?
It integrates Bootstrap 4 with Django by providing template tags such as `bootstrap_form` and `buttons`, which render Django forms and buttons with Bootstrap classes applied.
How do I install django-bootstrap4?
Run `pip install django-bootstrap4`, add `"bootstrap4"` to `INSTALLED_APPS` in settings.py, and load the library in a template with `{% load bootstrap4 %}`.
Is django-bootstrap4 still maintained?
It is in maintenance mode. It receives bug fixes and security updates only, no new features are added, and the project recommends django-bootstrap5 for new work.
Which Python and Django versions does django-bootstrap4 support?
The package requires Python 3.11 or newer and Django 5.2 or newer, with Django framework classifiers for 5.2, 6.0 and 6.1 and Python classifiers from 3.11 to 3.14.
How do I run the django-bootstrap4 example app?
An example Django project is included in the `example/` directory, and the documented command to run it is `just example`.
What licence does django-bootstrap4 use?
BSD-3-Clause, with the licence and the AUTHORS file declared as licence files in the package metadata.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/zostera-django-bootstrap4)