Open-source project
wagtail/wagtail avatar
wagtail/wagtail

Wagtail: a Django CMS that models pages in code and leaves the front end to you

A Django content management system focused on flexibility and user experience

20,728 stars4,747 forksPythonBSD-3-Clause

At a glance

What is it?
Wagtail is the Django CMS for teams that want a page tree, structured content blocks and a content API without giving up template control. The version floor is narrow, the front-end work is entirely yours, and the search backends are not in the install.
Who is it for?
Adopt Wagtail if your team can write Django models and templates and wants page structure, rich text and a content API without assembling them from separate services. Do not adopt it for a fixed-deadline site with no Python capacity, because no public page renders until you write the template for it yourself.
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 1 day 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 November 13, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • wagtail/wagtail20,728 ★ · +226
Star history
Repository2026-09-212026-11-13
wagtail/wagtail20.5k20.7k

226 Stars in the last 53 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

The page tree is the product, the templates are your bill

Wagtail is a Django application that hands editors a page tree, rich text, an image library and structured content blocks, then steps back on the public site. Two lines at the top of the feature list state the bargain: a fast, attractive interface for authors, and complete control over front-end design and structure. The first is the product. The second is what you pay for it.

The reader who benefits has Python and Django on staff. Every structural decision in Wagtail is expressed as a Django model, so the person who can follow a model definition is the person who benefits. Hand the same CMS to a team that only wants to publish pages, and the flexibility becomes the cost: there is no drag-and-drop site builder in the feature list to fall back on.

The central fact for a reader evaluating this: nothing renders a public page until you write a template for it. Templates, routing and the front end are all code, which is what makes the CMS a poor match for a marketing site with a fixed date and nobody who writes Django.

The dependency list is the closest thing to an architecture diagram

pyproject.toml describes the design better than any summary sentence does. django-treebeard is the page tree, the path structure that lets a page hold children and resolve a route back to its root. django-modelcluster covers pages whose data spans several related models, which is how one page type can hold repeatable child objects without a table per page. modelsearch is the search abstraction, and Willow with a heif extra sits next to Pillow>=9.1.0 for image handling.

The API side is just as visible: djangorestframework sits beside django-ninja and pydantic, with floors at djangorestframework>=3.18.0,<4.0 and django-ninja>=1.6.3,<2.0. The Makefile's v3 API snapshot target serialises the schema with django-ninja's NinjaJSONEncoder. draftjs_exporter covers rich text output, and django-tasks covers work that should not happen inside a request.

The alternative to weigh here is Django's own admin, which arrives with Django itself. It is generated from registered models and gives you a CRUD screen over your tables. It gives you no page tree, no StreamField blocks and no delivery layer. Wagtail is installed alongside that admin rather than over it, so a project can keep both, and the feature list puts it as "Embraces and extends Django".

wagtail start writes a project, and six commands are the whole tutorial

Setup is seven lines, and the README asks for them inside a virtual environment:

sh
pip install wagtail
wagtail start mysite
cd mysite
pip install -r requirements.txt
python manage.py migrate
python manage.py createsuperuser
python manage.py runserver

Read the order rather than memorising it. The generator runs first and produces a directory named after your site, and from that point on the dependency set is a file inside your project rather than something wagtail looks up for you. That is the point where a starter template becomes yours to fork. The README does not enumerate what lands in the generated directory, so the honest way to see it is to run the block and look.

`createsuperuser` is where the editor interface becomes reachable, and `runserver` is the only command in the list you would never ship. After that, the README routes new users to the Zen of Wagtail for what Wagtail is not, and sends anyone with an existing Django project to the Wagtail Integration documentation instead of the tutorial. That routing is a fair signal about retrofit.

The version floor is narrow and SQLite needs an extension most builds skip

The supported set is stated plainly: Django 5.2.x, 6.0.x and 6.1.x, Python 3.11, 3.12, 3.13, 3.14 and 3.15, and PostgreSQL, MySQL, MariaDB or SQLite with JSON1 as database backends. The SQLite clause is the one that catches people out. JSON1 is a SQLite feature that not every build enables, so a workstation whose Python links a SQLite without it can fail on a page type that uses structured fields while the same code runs clean against the PostgreSQL box in production.

The floor has moved. Wagtail 8.1 shipped on 2026-11-02, requires-python is >=3.11, and the classifier list already carries Django 6.1. The README notes that previous versions additionally supported Python 2.7 and 3.8, so the version of Wagtail you can install is a function of the Python and Django you are stuck with.

That is why the README points you at Compatible Django / Python versions in the release notes rather than promising a range here. If you are on an older stack, that page, not the front page, decides your upgrade path.

Packaging a source distribution shells out to npm

setup.py is short, and one override in it changes who can build this project:

python
class sdist(base_sdist):
    def compile_assets(self):
        try:
            subprocess.check_call(["npm", "run", "build"])  # noqa: S603, S607 - no untrusted input. Starting process from partial path is fine.
        except (OSError, subprocess.CalledProcessError) as e:
            print("Error compiling assets: " + str(e))  # noqa: T201
            raise SystemExit(1) from e

    def run(self):
        self.compile_assets()
        super().run()

A failure in the asset build is fatal, and `SystemExit(1)` is how it surfaces. A developer install goes through the same toolchain:

bash
pip install -e .[testing,docs] --config-settings editable-mode=strict
npm install --no-save && npm run build

If you install Wagtail from PyPI this code never runs for you. If you vendor it, build an sdist or mirror the source, the JavaScript toolchain becomes a packaging dependency, and package.json demands node >= 24. The same manifest sets the browser floor at Firefox ESR, the last two Chrome and Edge versions, iOS 17 and Safari 16, which is the list your editors' devices get held to whether or not the Python side cares.

Neither search backend is in the install

One line of the feature list promises "Powerful, integrated search, using Elasticsearch or PostgreSQL". The dependency list backs up only the second half. pyproject.toml pins modelsearch>=1.3.2,<1.4 and declares no Elasticsearch client among its dependencies, so `pip install wagtail` leaves you with no connection to an external search service. Multi-site and multi-language are named in the same list and the manifest says nothing about either needing an extra package.

The consequence is operational. Running Elasticsearch means a second service, an index that has to be kept in step with page saves, and a failure state where search quietly returns nothing while every page still renders. Staying on PostgreSQL avoids the service but inherits the same staleness problem in a different form.

The README does not say which configuration key selects the backend, how the index is built, or how to recover when it drifts. If search quality is a requirement rather than a nicety, that gap is the first thing to close before you commit, and the docs at docs.wagtail.org are where to look.

Editing a page model edits the published API schema

The Makefile has a target whose only output is two JSON files:

make
OPENAPI_SNAPSHOT := wagtail/api/v3/tests/snapshots/openapi.json
OPENAPI_SNAPSHOT_CUSTOM_PAGE_MODEL := wagtail/api/v3/tests/snapshots/openapi_basepage.json

Both are generated by importing the v3 API from a live Django app under DJANGO_SETTINGS_MODULE=wagtail.test.settings and serialising the result with NinjaJSONEncoder. The help text calls the target "regenerate the v3 API OpenAPI snapshot for CI", which means the schema is treated as a contract checked by a test.

For an adopter this is the important structural fact. The shape of the Content API is derived from your own page models, so adding a field to a page type is an API change whether or not you meant it as one. A decoupled front end written against the v3 API has to be reviewed whenever content models move, and the README describes no deprecation window or consumer versioning policy. The tool Wagtail offers for catching the break is a snapshot diff inside its own test suite, not a published compatibility matrix for your frontend.

Quarterly features, and Long Term Support is the cheap option

Feature releases land every three months. Selected ones are designated Long Term Support releases and receive maintenance updates for an extended period to address security and data-loss related issues. Read that as the whole upgrade policy: every other release ships features and stops. v8.1 came out on 2026-11-02, after v8.1rc1 on 2026-10-21 and v8.0.1 on 2026-10-20, and the repository was last pushed on 2026-11-02.

The shape this gives a team is a quarterly upgrade queue, and the LTS flag is the decision that makes skipping cheap. A site that pins an LTS release still gets security and data-loss fixes, and a site that pins a feature release does not.

Nightly builds are published from main every night, with instructions at the nightly release index. They exist to try features before a release, and a moving build from a branch is not something to pin production to.

What the README does not give you is a rollback procedure for an upgrade, or a description of what a failed data migration looks like from the operator's side. That content lives in the release notes. Before you commit, read the upgrade notes for the exact pair of versions you are moving between, because the Django version moves in the same decision.

Editorial conclusion

Adopt Wagtail if your team can write Django models and templates and wants page structure, rich text and a content API without assembling them from separate services. Do not adopt it for a fixed-deadline site with no Python capacity, because no public page renders until you write the template for it yourself. Verify three things first. Check the Compatible Django / Python versions page in the release notes against the Django and Python you already run, since the supported set is Django 5.2.x, 6.0.x and 6.1.x on Python 3.11 through 3.15 and the floor has moved since earlier releases took Python 2.7 and 3.8. Confirm the SQLite build on your workstations has JSON1 before choosing it for local work, because SQLite is supported only with that extension. Then read the upgrade notes for the exact pair of versions, since feature releases land every three months and only releases marked Long Term Support keep getting security and data-loss maintenance afterwards.

Frequently asked questions

What is Wagtail CMS?

A content management system built on Django and released under a BSD-3-Clause licence, focused on flexibility and user experience. It gives authors an editing interface and gives developers direct control over front-end design and structure.

How do I install Wagtail?

Run pip install wagtail, then wagtail start mysite, then pip install -r requirements.txt inside the generated directory, followed by python manage.py migrate, python manage.py createsuperuser and python manage.py runserver. The README asks for this inside a virtual environment, and Wagtail requires Python 3.11 or newer with Django 5.2 or newer.

How do I use Wagtail CMS once it is installed?

Create a superuser to reach the editor interface, and build pages from Django models, with StreamField for structured content. The Getting Started Tutorial walks through creating and editing a first page, and anyone adding Wagtail to an existing Django project is pointed at the Wagtail Integration documentation instead.

What does Wagtail have to do with Django?

Wagtail is a Django application that extends rather than replaces Django, and the project says so in its feature list. It supports Django 5.2.x, 6.0.x and 6.1.x on Python 3.11 through 3.15, and the Wagtail Integration documentation exists for teams who already have a Django project.

Official sources

  1. License: BSD-3-Clause
  2. Project website
  3. README
  4. Releases
  5. wagtail/wagtail on GitHub
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/wagtail-wagtail.svg)](https://hysenlabs.com/projects/wagtail-wagtail)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/wagtail-wagtail.svg)](https://hysenlabs.com/projects/wagtail-wagtail)

Was this useful?