A Bakebook is an ordinary Python class, and an ordinary Python class can live in a package. That is how tasks are shared in bakefile: a reusable task library is just a Python package - write tasks once, publish, and every project installs it like any other dependency. No include files, no templating, no copy-paste.
Make reaches for include, Just for modules, Task for includes. bakefile uses the mechanism Python already has.
Publish the Bakebook as a package
Put the Bakebook in its own package and publish it - public PyPI, a private index, a git reference, or a local path all work (see Where to publish). The package declares bakefile as a dependency and ships the class:
Nothing else is required. It is a normal Python package whose export happens to be a Bakebook.
Naming convention: use bakelib as the key when naming shared Bakebooks. Either name the package bakelib-fastapi (imported as bakelib_fastapi), or keep it as a module inside a package you already publish:
The key mirrors bakefile’s own bakelib, so anyone reading a bakefile.py can spot shared books at a glance.
Where to publish
Four places a shared Bakebook can live. From the consumer’s side all four install the same way - only the reference changes.
Public PyPI
For Bakebooks anyone can use. Publish with uv publish or twine, then depend on it by name. bakefile’s own Spaces ship this way.
Private index
Same package, same tooling, different index. Any PEP 503-compatible registry works:
- GCP Artifact Registry
- AWS CodeArtifact
- Azure Artifacts
- GitLab package registry
- Self-hosted devpi or pypiserver
With uv, declare the index once in the consuming project and pin the package to it:
The explicit = true + sources pin keeps the private index from shadowing public PyPI for everything else.
Git
No registry at all. Reference the repository with a PEP 508 direct URL - by tag, exact commit, or branch:
A bare URL with no @ref also works - it tracks the repository’s default branch. With a lockfile (uv.lock), uv records the exact commit either way, so the pin only moves when the lock is upgraded.
For private repositories, use SSH instead: bakelib-fastapi @ git+ssh://git@github.com/my-org/bakelib-fastapi.git.
With uv, the pin can also live in [tool.uv.sources] instead of the dependency string:
This keeps the dependency by-name, so the consumer project itself stays publishable to PyPI, which rejects direct-URL dependencies. tag swaps for rev (exact commit) or branch.
The same string works in a PEP 723 # dependencies block. If the Bakebook lives in a monorepo subdirectory, add a fragment: #subdirectory=packages/bakelib-fastapi.
Local path
The Bakebook lives beside the consumer - a monorepo subdirectory or a sibling checkout. No publishing at all:
editable = true installs the Bakebook in place, so edits to it are immediately live in every consuming project - the loop to use while authoring it. This is the same pattern bakefile’s own python-package example uses.
Depend on it from any project
A standalone bakefile.py lists the package in its PEP 723 block, next to bakefile:
Run bakefile sync to install the declared dependencies into the bakefile’s own environment.
A Python project instead lists it in pyproject.toml, next to bakefile:
The python-package example shows a full project consuming a Bakebook this way.
Inherit, override, compose
Subclassing is the whole API:
- Inherit every task by subclassing the Bakebook.
- Override a task by redefining its method.
- Compose task sets through multiple inheritance.
Inherited Bakebooks inherit configuration too, and subclasses can override individual fields. See Bakebook for the mechanism and Commands for decorator options.
Prebuilt Bakebooks: bakelib Spaces
bakelib Spaces follow the same shape. They are Bakebooks published as part of bakefile and installed as a dependency with the lib extra:
Use a Space as-is, or inherit and override it like any other Bakebook. Publishing your own Space for your organization works exactly like publishing your own Bakebook. Last modified on August 25, 2026