Options reference
Every molt configuration option, grouped by what it controls, with its type, default, and one-line meaning.
Options are shown by their canonical snake_case name. Every option also accepts the changesets-compatible camelCase spelling as an alias; see The config file. Examples below use [tool.molt] TOML, but each has an exact .molt/config.json equivalent.
Change detection
A package is considered changed when it has at least one changed file whose package-relative path matches changed_file_patterns. Narrow it to skip noise like docs or tests:
Versioning and propagation
update_internal_dependents is molt's promotion of a changesets option that used to live behind the ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH wrapper. In molt it is a plain, stable, top-level option. "out-of-range" (the default) only pulls a dependent into the release when the dependency's new version would fall outside the dependent's current pin. "always" releases every internal dependent with at least a patch, even when it is still in range -- useful when you want lockstep movement. See Dependency propagation.
bump_workspace_sources_only is molt's rename of changesets' bumpVersionsWithWorkspaceProtocolOnly (which it still accepts as an alias). The Python analogue of npm's workspace: protocol is a dependency backed by [tool.uv.sources] with workspace = true; when this is on, molt only rewrites the pins of such dependencies and leaves externally-versioned ones untouched.
ignore accepts globs and expands them against your package names at load time. An ignore pattern that matches nothing is a warning, not an error -- molt simply drops it and continues:
Package grouping
Each group is a list of package names (globs are also accepted). The difference between the two -- and why molt keeps both, unlike changesets' near-identical published definitions -- is explained in Linked vs fixed.
Private packages
Private packages -- apps and internal tools you version but never upload to PyPI -- are versioned by default so their internal dependency pins stay correct. Set private_packages = false to leave them out of versioning entirely:
Molt drops changesets' privatePackages.tag sub-option. It gated whether private packages got a git tag during version -- not an npm dist-tag. Molt decides that with molt git-tag, per run, rather than from config, so the option has nothing left to gate (research README section 4.4).
Changelog and commit
changelog selects the generator that turns changeset summaries into changelog entries. false disables changelog generation. A bare string names a generator; a [generator, options] two-tuple passes options to it. Generators are resolved as Python entry points (or module:attr references), not shell commands, so third parties can publish generators you install like any package:
See Changelog plugins for the generator contract and Changelog templates for shaping the output.
commit works the same way: false (default) leaves committing to you; true uses molt's built-in commit generator; a string or tuple selects a custom one.
format exists mainly for parity and taste. Molt emits correct, deterministic Markdown itself -- it does not need a formatter pass to clean up broken blank lines the way changesets does -- so the default is false. Set it to "mdformat" if you want written files normalized by an external formatter. Changesets' JS-specific format values ("auto", "prettier", "oxfmt", "deno", "dprint") are accepted for migration but do not pull in a Node toolchain.
Snapshots
Snapshots produce throwaway, timestamped builds for testing. Because PyPI versions are immutable and it rejects local-version suffixes, molt's snapshot model is reshaped from changesets': suffixes compose a PEP 440 .devN-style build and snapshots target a separate index by default rather than burning a public version number. The template understands the placeholders {tag}, {commit}, {commit-short}, {timestamp}, and {datetime}:
See Snapshot releases for the full model and how it differs from changesets.
Backends (molt-native)
These have no changesets equivalent. They select the pluggable backends that make molt work across Python's fragmented tooling.
ecosystem defaults to "auto", which detects a uv workspace and otherwise treats the root as a single package. Set it to "uv" to pin the backend and skip detection:
"auto" and "uv" are the only values molt accepts today. Poetry, Hatch, PDM and setuptools are scheduled after the 0.1 release; naming one is an error that says so, rather than a silent fallback that would discover the wrong set of packages. The backend seam exists from day one precisely so adding them is an implementation, not a redesign.
If your repo has no uv workspace, you do not need this option at all — a single-package repo is a first-class case, not a degraded one. Most Python projects are single-package; the ratio is inverted versus JavaScript.
See Ecosystems. forge selects the release-automation backend; GitHub ships first, but the seam exists from day one -- see Forges.
Dropped from changesets
Molt deliberately does not carry these changesets options, because they encode npm/JavaScript concepts with no Python analogue. Configs that still contain them are accepted (the keys are ignored with a warning), so migration does not break.
The $schema key is not a behavioral option -- it drives editor autocomplete for .molt/config.json and is documented under JSON schema.
Where to go next
- The config file -- where these options live and how validation reports problems.
- Dependency propagation -- what
update_internal_dependenciesandupdate_internal_dependentsactually do. - Linked vs fixed -- choosing between the two grouping options.
- JSON schema -- get these options autocompleted in your editor.