Public vs internal API¶
You can import anything from the libtmux namespace and build on it: those
names are the public API — documented, and changed only through a deprecation
process announced ahead of time. (libtmux is pre-1.0, so a minor version can
still carry a breaking change; pin a version when you need to lock things
down.) See the public API reference for the
stability policy. Anything with a
leading underscore in its module path — libtmux._internal.*,
libtmux._vendor.* — is implementation detail that can change without warning.
If you only reach for the public API, that’s the whole story, and you can stop
reading here.
The boundary¶
The rule is mechanical: if you can import a name without a leading underscore anywhere in its module path, it’s public. The table maps each import prefix to exactly what you can count on.
Import path |
Status |
Stability |
|---|---|---|
|
Public |
Covered by deprecation policy |
|
Internal |
No guarantee — may break between any release |
|
Vendored |
Not part of the API at all |
The authoritative list of what’s stable lives in Public API.
Why the split¶
Staying on the public API buys you a predictable migration path: when a public
name changes, it goes through a deprecation process first — a warning for at
least one release, documented in the changelog — rather than vanishing without
notice. (libtmux is pre-1.0, so a minor version can still carry a breaking
change; pin a version when you need to lock things down.) Reaching into an
internal module buys you none of that — a refactor of
query_list ships with no deprecation cycle, so an import
that works today can break on the very next release. That freedom is the point: internal modules let the library iterate on
implementation details without dragging downstream users through a migration for
each one.
The same line keeps the public surface intentionally small. Every public module is a commitment to maintain, so internal modules earn promotion only through proven stability and real user demand.
What _internal/ contains¶
The _internal/ package holds the machinery the public objects run on —
implementation details you never need to understand to use libtmux:
query_list— the filtering engine behind.filter()and.get()on collectionsdataclasses— base dataclass utilities used by the ORM objectsconstants— internal constants not meaningful to end userssparse_array— the sparse-index mapping behind indexed hooks and options
These are documented in Internals for contributors, but downstream projects should not import from them.
What _vendor/ contains¶
The _vendor/ package holds vendored third-party code — copies of external
libraries bundled directly so libtmux can avoid adding dependencies. You’re not
meant to import from it; it isn’t written by the libtmux authors and isn’t part
of the API.
How internal APIs get promoted¶
Most readers never need this section — it’s for contributors and for anyone tempted to depend on an internal name. An API travels three stages on its way to the public contract:
Internal: lives in
_internal/, no stability promiseExperimental: documented, usable, but explicitly marked as subject to change
Public: moved to a top-level module, covered by the deprecation policy
Promotion happens when an internal API proves stable across multiple releases and users ask for it. If you depend on an internal API, file an issue — that signal helps prioritize promotion.
Once a name is public and later has to change, it doesn’t vanish quietly; it moves through a deprecation cycle first. For the platforms and tmux versions that stability is promised against, see Compatibility.