# Django Packages: a directory that compares Django apps in grids

> Django Packages is a Django site and open source project that indexes reusable apps and lets people compare candidates side by side in editable comparison grids. It runs on Docker with Postgres and Redis, and it publishes package data fetched from PyPI, GitHub and Bitbucket.

**djangopackages/djangopackages** — Django Packages is a directory of reusable apps, sites, tools, and more for your Django projects.

- Repository: https://github.com/djangopackages/djangopackages
- Website: https://djangopackages.org
- Stars: 958 · Forks: 199
- Language: Python
- License: NOASSERTION
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/djangopackages-djangopackages

## Choosing between Django packages without reading every source tree

Django Packages solves a narrow, real problem: Django has a large third party ecosystem, and picking a package often means comparing a dozen candidates that all claim to do the same thing. The project describes itself as a directory of reusable apps, sites, tools and more for Django projects, and its stated purpose is to help people identify and compare good apps, frameworks, plugins and other types of packages.

The unit of comparison is a grid. A grid holds a set of packages and a set of features, and people can add packages to it and add or edit grid features. The feature list calls this a comparison grid with wiki-like editing capability. That wording matters, because it implies the grid is not a fixed table maintained by the site owners. Anyone can change it, in the same way a wiki page can be changed. The value of the project therefore depends on whether enough people actually edit the grids, since a grid nobody maintains is just a static table that goes stale.

Alongside the grids there are two search features, described as basic search with autocomplete for both packages and grids, plus an add package form and an add grid form so that a new catalogue entry can be created without going through the site maintainers. The homepage also features the latest packages, and there is an I use this button, which makes the directory carry a lightweight popularity signal of its own rather than relying only on download counts.

## Package details are fetched from public forge and index APIs

The directory does not ask authors to fill in a description by hand. The feature list states that package info is stored after being fetched from public APIs, and it names three of them: PyPI, GitHub and Bitbucket. A fourth, GitLab, is listed as coming soon. That single line tells you the data pipeline depends on external services and their rate limits, since every metadata refresh is an outbound API call to a forge or to the Python package index.

The consequence is that the index only covers what those APIs expose. A package that exists only on GitLab, or on a private Git host, has no path into the directory today. The same applies to a project that is not published on PyPI at all. That is a coverage limit worth stating plainly rather than a defect, because the alternative would be manual curation by the maintainers, which is a different and much more expensive operating model.

The Django application itself is split into app level directories that mirror the site's structure: package for the indexed packages, grid for the comparison grids, searchv3 for search, profiles for user accounts, favorites, feeds, classifiers, banners, blog, homepage and products. There are also apiv3 and apiv4 directories, which suggests the site exposes versioned API surfaces alongside the HTML pages, and a classifiers app, which is where the taxonomy used to sort packages would live.

## Four commands and Docker give you a running local copy

The readme points to the hosted documentation for detailed installation instructions and then gives the short path for development. Clone, copy the environment file, build the images and bring the stack up.

```shell
git clone git@github.com:djangopackages/djangopackages.git
cd djangopackages
cp .env.local.example .env.local
docker compose build
docker compose up
```

The site then answers on http://localhost:8000. The compose file makes that port explicit, mapping `8000:8000` for the django service.

Tests run through the same stack, which saves you from installing the Python environment separately.

```shell
docker compose run django pytest
```

The pyproject file configures pytest with `DJANGO_SETTINGS_MODULE = "tests.settings"`, a `tests/` directory that is present in the repository, and a `conftest.py` at the top level, so the test settings are kept separate from the production settings in `settings.py`.

The readme also mentions an override file for conflicting port situations, which remaps Django to port 18000 and Postgres to 45432. Worth flagging: the snippet shown for that override is the same two compose commands as the normal path, so the file to copy is not named in the readme, and you will need to find it in the repository before relying on that workflow.

## Postgres, Redis and a django-q worker sit behind the pages

The compose file is the best single description of how the site runs. Six services are defined. The django service builds from `./dockerfiles/django/Dockerfile-dev` and runs `/start-dev.sh`. A django-q service runs `uv run python -m manage worker worker`, which is the background job runner for the project. A tailwind service runs `uv run python manage.py tailwind --skip-checks watch` to rebuild styles on change, matching the `tailwind.config.js` and `tailwindcss.css` entries at the repository root.

The data stores are declared as plain images rather than built services. Postgres uses the `pgautoupgrade/pgautoupgrade:17-alpine` image and is checked with `pg_isready`, retried 30 times at three second intervals. Redis uses `redis:7` with a `redis-cli ping` health check. The django service waits for both to report healthy before it starts, which is what the `depends_on` conditions express.

There is a docs service too, running `zensical serve -f docs/mkdocs.yml --dev-addr 0.0.0.0:4000` and exposed on port 4000 under the `docs` compose profile. Because it sits behind a profile, it does not start with a plain `docker compose up`.

A `justfile` sits next to the compose file with a `bootstrap` recipe that creates a virtual environment with `uv`, runs `uv sync`, copies `.env.local.example` to `.env.local` if it is missing, and forces a rebuild of the images. The same file defines `DATABASE_URL` with a fallback of `postgres://djangopackages:djangopackages@postgres/djangopackages`.

## Calendar versions with a bumpver tag, and no GitHub releases

Versioning here is unusual and easy to trip over. The pyproject file configures bumpver with `version_pattern = "YYYY.MM.INC1"` and a current version of `2026.10.28`, which is a calendar-style scheme with an increment counter. The bump recipe in the justfile runs `uv --quiet tool run bumpver update`, and the configured commit message includes a `[skip ci]` marker with the note that committing is enabled while pushing is disabled for GitHub Actions.

Against that, the `project` table in the same pyproject file lists `version="2025.10.10"`. Two version fields in one file, a year apart, with different patterns to read. The bumpver block is the one that also names the file it rewrites, `core/__init__.py`, so it is the authoritative source for the package version that the code reports, while the project table is what tooling reads when the distribution is installed. Anyone pinning this project in a requirements file needs to know which of the two they are getting.

There are no GitHub releases for the repository, but a `CHANGELOG.md` exists at the top level. So version history is available in the repository, just not through the release page. The readme points at the documentation site for anything not covered there.

The licence situation is stated simply in the readme, which says the code is open source and licensed under the MIT licence, with the licence text in a `LICENSE.md` file at the repository root.

## Where the directory stops being enough

The limits of the project are visible in its own feature list. Search is described as basic. There is no ranking model, no faceting and no stated relevance tuning, so if you know the name of a package, the directory will find it, and if you do not, the autocomplete list is the whole discovery surface.

GitLab support is marked as coming soon, which leaves a real gap given how many internal and public Django projects live on GitLab. The metadata pipeline also depends on the availability and rate limiting of PyPI, GitHub and Bitbucket, and no fallback path is described for when those APIs are unreachable.

The grid model has a social dependency. Wiki-like editing means the quality of the comparison depends on who is editing. There is no description in the readme of moderation, review, or versioning of grid revisions, so the practical question for an adopter is whether they trust the current contents of a grid they did not write.

The documentation also points at the hosted site for the canonical information. The repository contains a `docs/` directory and a `docs` compose profile, and the readme links to `https://docs.djangopackages.org/en/latest`, so the docs are readable without running anything. But what the readme does not document is the API contract of the apiv3 and apiv4 apps, or how the upstream PyPI and GitHub credentials are configured in the deployment, which is the first thing you would need if you wanted to run your own instance rather than read the public one.

## A curated catalogue compared with searching the index directly

The alternative to a directory like this is the raw search on PyPI itself, which lists package names and versions but offers no side by side feature comparison and no way to note which packages your team has actually settled on. The difference in approach is editorial versus raw. A grid records a human claim about what a package does and how it differs from its neighbours, and it is editable by anyone who cares enough to edit it. PyPI search gives you the index and nothing else, so the comparison work falls back to reading each project's documentation yourself.

A third approach, closer to the code, is to pin your choices in a `requirements.txt` and treat that file as the shared catalogue. The difference there is ownership. A pinned file records a decision your team made, with no shared editing surface and no external discovery value. Django Packages inverts that: the catalogue is public and collaborative, and your team's decisions live in a grid you can edit.

The trade is that the collaborative catalogue carries no guarantee of accuracy and no versioning of its own, while the pinned file carries no discovery and no external contribution. For a single team that already knows its stack, the pinned file is cheaper and more durable. For a team hunting across unfamiliar territory, or for anyone trying to give a wider community a shared map of the Django ecosystem, the grids are the part that has no substitute.

## Conclusion

Django Packages suits teams choosing between several Django packages and teams that want a self-hosted catalogue of their own, while it is the wrong fit for anyone needing deep API access, non-Django ecosystems or a published package index. Before adopting it, check whether the grid editing model in the grid app matches how your team documents decisions, confirm that the PyPI, GitHub and Bitbucket API fetches still work under GitLab support, which the feature list marks as coming soon, and read CHANGELOG.md before pinning a version, since the last push was on 2026-10-20 while the pyproject version field still reads 2025.10.10.

## FAQ

### How do I run Django Packages locally for development?

Clone the repository, copy `.env.local.example` to `.env.local`, then run `docker compose build` and `docker compose up`. The site answers on http://localhost:8000.

### What does Django Packages use for its database and background jobs?

The compose file defines Postgres using the `pgautoupgrade/pgautoupgrade:17-alpine` image and Redis using `redis:7`, with a django-q service running the worker process for background jobs.

### Which package sources does Django Packages index?

Package info is fetched from public APIs for PyPI, GitHub and Bitbucket. GitLab support is listed as coming soon, so GitLab-only projects are not indexed today.

### How do I run the Django Packages test suite?

Run `docker compose run django pytest`. Pytest is configured in pyproject.toml with `DJANGO_SETTINGS_MODULE = "tests.settings"`, so the tests use a dedicated settings module rather than `settings.py`.

### What licence is Django Packages released under?

The readme states that the code is open source and licensed under the MIT licence, with the licence text held in the `LICENSE.md` file at the repository root.

## Sources

- [djangopackages/djangopackages on GitHub](https://github.com/djangopackages/djangopackages)
- [Issues](https://github.com/djangopackages/djangopackages/issues)
- [Project website](https://djangopackages.org)
- [README](https://github.com/djangopackages/djangopackages/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/djangopackages-djangopackages
