Quickstart: single package
Take one package from a code change to a published release with molt init, molt add, molt version, and molt publish.
Most Python projects ship a single package, and molt treats that as the default path -- not a stripped-down special case. This walkthrough is copy-pasteable end to end. If you manage a workspace of several packages, read the monorepo quickstart instead.
We will use a package called acme-core that starts at version 1.2.0.
0. Set up
Install molt (see Installation) and scaffold the project from its root:
That creates .changeset/ and a [tool.molt] block in your pyproject.toml. Your starting manifest looks like this:
1. Make a code change
Edit whatever you are editing. Say you add a --stream flag to the export API -- a backward-compatible feature, so a minor change.
2. Record a changeset
Run molt add and describe the change:
In a single-package repo, molt skips straight to two questions -- what kind of change is this, and what should the changelog say:
That writes a small Markdown file into .changeset/ with a random, human-readable name:
Commit this file in the same pull request as your code. It is the intent of the change, captured while you still have the context. Prefer to skip the prompts entirely (in CI, a script, or a bot)? Use the non-interactive form:
See Adding a changeset for the full flow, interactive and non-interactive.
3. Version the package
When you are ready to cut a release, consume every pending changeset in one step:
molt version reads the .changeset/ directory, works out the correct next version, and applies it. Three files change and one is deleted:
pyproject.toml -- the version is bumped (a minor, 1.2.0 -> 1.3.0):
CHANGELOG.md -- created if absent, with your summary folded in under the new version:
uv.lock -- refreshed so the lockfile matches the new version. Updating the lockfile is a molt feature; changesets leaves it stale, which is cosmetic in npm but load-bearing in Python.
.changeset/late-mangos-cheer.md -- deleted. The intent has been consumed into a concrete release, so the changeset is gone. Re-running molt version now would exit with code 1 and "No pending changesets found." -- there is nothing left to do, and molt never double-bumps.
Preview all of this before it touches disk with molt version --dry-run; see Dry runs and plans.
Now commit the release:
4. Publish
molt publish builds the package (an sdist and a wheel), uploads exactly the versions that are not already on the index, and creates an annotated git tag. In a single-package repo the tag is v1.3.0.
In CI, molt publishes through PyPI Trusted Publishing (OIDC), so there is no long-lived token to manage. Locally you can use an API token. Either way, push your tag afterward:
The whole loop
Where to go next
- The release workflow -- the mental model behind these four commands.
- Adding a changeset and Versioning -- the two verbs you run most.
- Quickstart: monorepo -- when one package becomes several.
- Publishing -- tokens, Trusted Publishing, and what gets uploaded.