How to create packages and plugins? Is the process different? / Clarifying terminology

In Django, is there a difference between how someone creates a package meant for developers to use in a django project vs how someone creates a plugin/extension/app meant for users of a django app?

It’s clear to me how there would be differences in getting it so the end person (developer or non developer) would be able to install/use it (not that I know in detail how folks do that either), but it’s unclear to me to what degree it would differ on the creation side of things, if at all. I should probably also mention I ask about this stuff in the context of Django, but I’m also starting from a place of not understanding it in any context (aside from being the end user of other people’s creations).

Relatedly, is this terminology roughly accurate?

  • django app [in this context] - how someone can silo some code into a neat, self-contained thing so it can then be added in a reusable way to any django project’s installed apps with whatever other settings it might need to be used. Generally intended for all users to get its functionality when added to a django project.
  • package - meant for developers to use; it extends your project’s code if you opt-in to adding it. A package is a django app and a django app becomes a package by […providing some extra meta information about its packaging…somehow… …in some format…somewhere…] which then allows it to be considered a package ready to be used by others and listed on PyPI
  • plugin - meant for users to use; it extends the django project’s code if a user opts-in [which would add it for only their use and not other users…somehow…[I see the words API/webhooks being in these docs a lot so I think that’s related to this piece somehow?]
  • extension - a synonym of plugin, but it’s used for other domains that aren’t web apps (e.g. browsers, desktop apps)
    • e.g. Chrome extensions, Visual Studio Code extensions
    • Highly uncertain of this definition…mainly because I couldn’t find an example of a Django extension (since I’m pretty sure django-extensions is a package…so maybe extension is a synonym for both a plugin and a package?)
  • integration - meant for users to use, a third […thing…also made as a django app…?] that provides a bridge between two other projects by being kind of like a software equivalent of a dongle/adapter that has a side that adapts to each project; it can be made “officially” by either one of the two projects or it can be made by a third-party that is independent and unrelated to either project. Maybe created just like a plugin but so that it’s double-sided instead of single-sided?

Or are these terms more interchangeable in practice?

Asking because, in my quest to understand, I was trying to find example Django projects with documentation about how to create a plugin for their project because I figured that would make the distinctions more apparent, but then I got more confused about the terms. A few more examples below to give a sense why I’m getting confused as I search in the wild:

  • Wagtail names them “third-party packages” but they seem more aligned with what I thought was the definition of a plugin. Some of the descriptions of these packages call themselves plugins.
  • There was an example plugin package for Open edX, so that does make me think creating a plugin (for users) vs a package (for devs) would be a very similar process (or exactly the same?). Open edX also has “frontend plugin slots”
  • Saleor (first quote source, second quote source) uses almost all these terms, but distinguishes between them (which implies to me being that plugins and apps are actually very distinct beasts)
    • Extensions

      Saleor has two ways to extend its functionality:

      • Apps - technology-agnostic clients that can communicate with Saleor using API and webhooks.
      • Plugins - legacy extensions living in the core Saleor codebase.

      and

      Plugins Overview

      caution

      We are in the process of deprecating plugins in favor of apps. If you plan on building a new integration with Saleor, we recommend using apps instead.

      Plugins offer a mechanism to extend Saleor’s Python core with new functionality.

Relatedly, I also welcome recommendations for any related Django-specific how to/tutorials for creating packages and/or plugins (bonus if more beginner friendly but anything is helpful)

Keep in mind that Django is a Python library. Anything regarding the structure and organization of a Django project that isn’t unique to Django must comply with Python’s requirements.

When you’re talking about creating a separately-installable “thing” (“app”, “plugin”, “module”, “extension” - whatever term you want to use) that someone else can use with their project, you’re really just talking about a standard Python package that can be installed with pip (or uv, or …)

This implies (to me, at least) that from the “author’s” perspective, there is no structural difference between an “app”, “plugin”, “extension”, etc. They would all be created the same way, even though their functionality may differ.

The Django tutorial starts to cover this at Advanced tutorial: How to write reusable apps | Django documentation | Django. The organization of directories and additional files being created are going to be the same regardless of the type of package being created. Since Django is a Python library, the more detailed information found in the Python docs would also apply.

Now, how someone else uses your package is entirely up to you and how you design your package to be used. Django puts no requirements nor enforces any restrictions in that regard.

So from that angle, “package” would be considered the umbrella term covering all the other terms. Those other terms could be used to make distinctions based upon how you work with them - but there are no standard definitions so YMMV.

For example, consider all the following:

  • Wagtail
  • Django Rest Framework
  • Django Crispy Forms
  • Django Debug Toolbar
  • Django Extensions

These are all “packages” in that you install them using pip. They provide vastly different sets of functionality, and how you use them within your project differ. But they’re all integrated in your project by specifying them in your “INSTALLED_APPS” setting.

Being listed there is an indicator to Django that there’s something within that package that Django needs to be aware of. What that “something” is, is defined within the package.

However, it’s not required that all third-party packages being used by your project be listed there. If a package doesn’t have any “Django-specific” hooks - if it’s just “utility code” that you are using in your project - then it doesn’t need to be listed. (Consider a library that generates a PDF. You can import that library in your views.py, call it from a view, and return the PDF as a download file as the response without any reference to it in your settings.

Side note: When talking about a framework like Django, it (Django) is the “First party”. You, writing the code for your project, is the “Second party”. All code written by someone else is then the “Third party”. Every package you install that wasn’t written by you or “Django” would be considered a third-party package.

I like Ken’s answer more than anything I’d share.

When I’ve created projects, I’ve used the official tutorial: Packaging Python Projects - Python Packaging User Guide it doesn’t cover the Django aspect though. Then I copy what Adam Johnson does for his in terms of setting up precommit, tox, pyproject.toml, github workflows, etc. I think there are some copier / cookie cutter project templates, but I haven’t used them since it’s not something I do frequently.