GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — GitHub - tmux-python/libtmux: ⚙️ Python API / wrapper for tmux

BranchesTags
Open more actions menu

Latest commit

 

History

3,186 Commits
3,186 Commits

Folders and files

NameName
Last commit message
Last commit date
.github
.github
 
 
.vim
.vim
 
 
docs
docs
 
 
src/libtmux
src/libtmux
 
 
tests
tests
 
 
.codecov.yml
.codecov.yml
 
 
.gitignore
.gitignore
 
 
.nvmrc
.nvmrc
 
 
.prettierrc
.prettierrc
 
 
.python-version
.python-version
 
 
.tmuxp.yaml
.tmuxp.yaml
 
 
.tool-versions
.tool-versions
 
 
.windsurfrules
.windsurfrules
 
 
AGENTS.md
AGENTS.md
 
 
CHANGES
CHANGES
 
 
CITATION.cff
CITATION.cff
 
 
CLAUDE.md
CLAUDE.md
 
 
LICENSE
LICENSE
 
 
MIGRATION
MIGRATION
 
 
README.md
README.md
 
 
TODO
TODO
 
 
conftest.py
conftest.py
 
 
justfile
justfile
 
 
pyproject.toml
pyproject.toml
 
 
uv.lock
uv.lock
 
 

Repository files navigation

⚙️ libtmux

Drive tmux from Python: typed, object-oriented control over servers, sessions, windows, and panes.

libtmux logo

tests libtmux libtmux.org License

🐍 What is libtmux?

libtmux is a typed Python API over tmux, the terminal multiplexer. Stop shelling out and parsing tmux ls. Instead, interact with real Python objects: Server, Session, Window, and Pane. The same API powers tmuxp, so it stays battle-tested in real-world workflows.

✨ Features

  • Typed, object-oriented control of tmux state
  • Query and traverse live sessions, windows, and panes
  • Locate yourself from inside a pane with from_env()
  • Raw escape hatch via .cmd(...) on any object
  • Works with multiple tmux sockets and servers
  • Context managers for automatic cleanup
  • pytest plugin for isolated tmux fixtures
  • Proven in production via tmuxp and other tooling

Requirements & support

  • tmux: >= 3.2a
  • Python: >= 3.11 (CPython and PyPy)

Maintenance-only backports (no new fixes):

  • Python 2.x: v0.8.x
  • tmux 1.8-3.1c: v0.48.x

📦 Installation

Release:

$ pip install libtmux

With pipx:

$ pipx install libtmux

With uv / uvx:

$ uv add libtmux
$ uvx --from "libtmux" python

From the main branch (bleeding edge):

$ pip install 'git+https://github.com/tmux-python/libtmux.git'

Tip: libtmux is pre-1.0. Pin a range in projects to avoid surprises:

requirements.txt:

libtmux==0.50.*

pyproject.toml:

libtmux = "0.50.*"

🚀 Quickstart

Open a tmux session

First, start a tmux session to connect to:

$ tmux new-session -s foo -n bar

Pilot your tmux session via Python

Use ptpython, ipython, etc. for a nice REPL with autocompletions:

$ pip install --user ptpython
$ ptpython

Connect to a live tmux session:

>>> import libtmux
>>> svr = libtmux.Server()
>>> svr
Server(socket_path=/tmp/tmux-.../default)

Tip: You can also use tmuxp's tmuxp shell to drop straight into your current tmux server / session / window / pane.

Run any tmux command

Every object has a .cmd() escape hatch that honors socket name and path:

>>> server = Server(socket_name='libtmux_doctest')
>>> server.cmd('display-message', 'hello world')
<libtmux...>

Create a new session:

>>> server.cmd('new-session', '-d', '-P', '-F#{session_id}').stdout[0]
'$...'

List and filter sessions

Learn more about Filtering

>>> server.sessions
[Session($... ...), ...]

Filter by attribute:

>>> server.sessions.filter(history_limit='2000')
[Session($... ...), ...]

Direct lookup:

>>> server.sessions.get(session_id=session.session_id)
Session($... ...)

Control sessions and windows

Learn more about Workspace Setup

>>> session.rename_session('my-session')
Session($... my-session)

Create new window in the background (don't switch to it):

>>> bg_window = session.new_window(attach=False, window_name="bg-work")
>>> bg_window
Window(@... ...:bg-work, Session($... ...))

>>> session.windows.filter(window_name__startswith="bg")
[Window(@... ...:bg-work, Session($... ...))]

>>> session.windows.get(window_name__startswith="bg")
Window(@... ...:bg-work, Session($... ...))

>>> bg_window.kill()

Split windows and send keys

Learn more about Pane Interaction

>>> pane = window.split(attach=False)
>>> pane
Pane(%... Window(@... ...:..., Session($... ...)))

Type inside the pane (send keystrokes):

>>> pane.send_keys('echo hello')
>>> pane.send_keys('echo hey', enter=False)
>>> pane.enter()
Pane(%... ...)

Capture pane output

>>> pane.clear()
Pane(%... ...)
>>> pane.send_keys("echo 'hello world'", enter=True)
>>> pane.cmd('capture-pane', '-p').stdout  # doctest: +SKIP
["$ echo 'hello world'", 'hello world', '$']

Traverse the hierarchy

Learn more about Traversal

Navigate from pane up to window to session:

>>> pane.window
Window(@... ...:..., Session($... ...))
>>> pane.window.session
Session($... ...)

Know where you're running

Learn more about Locating yourself

Code running inside a pane — a script in a split, a tmux hook, an agent — can ask where it is. tmux writes TMUX and TMUX_PANE into every pane it spawns, and Server, Session, Window, and Pane each read them back:

>>> socket_path = server.cmd(
...     "display-message", "-p", "-t", session.session_id, "#{socket_path}"
... ).stdout[0]
>>> monkeypatch.setenv("TMUX", f"{socket_path},1,{session.session_id}")
>>> monkeypatch.setenv("TMUX_PANE", pane.pane_id)

>>> Pane.from_env()
Pane(%... ...)
>>> Session.from_env().session_name == session.session_name
True

In a real pane tmux has already set those two variables, so from_env() takes no arguments and there is nothing to arrange — this README is not running in a pane, so the example sets them first. Outside tmux there is no pane to return, and from_env() raises NotInsideTmux.

Core concepts

libtmux object tmux concept Notes
Server tmux server / socket Entry point; owns sessions
Session tmux session ($0, $1,...) Owns windows
Window tmux window (@1, @2,...) Owns panes
Pane tmux pane (%1, %2,...) Where commands run

Also available: Options and Hooks abstractions for tmux configuration.

Collections are live and queryable:

server = libtmux.Server()
session = server.sessions.get(session_name="demo")
api_windows = session.windows.filter(window_name__startswith="api")
pane = session.active_window.active_pane
pane.send_keys("echo 'hello from libtmux'", enter=True)

tmux vs libtmux vs tmuxp

Tool Layer Typical use case
tmux CLI / terminal multiplexer Everyday terminal usage, manual control
libtmux Python API over tmux Programmatic control, automation, testing
tmuxp App on top of libtmux Declarative tmux workspaces from YAML / TOML

Testing & fixtures

Learn more about the pytest plugin

Writing a tool that interacts with tmux? Use our fixtures to keep your tests clean and isolated.

def test_my_tmux_tool(session):
    # session is a real tmux session in an isolated server
    window = session.new_window(window_name="test")
    pane = window.active_pane
    pane.send_keys("echo 'hello from test'", enter=True)

    assert window.window_name == "test"
    # Fixtures handle cleanup automatically
  • Fresh server and session fixtures per test, each on an isolated tmux socket; derive windows and panes from session
  • Temporary HOME and tmux config fixtures keep indices stable
  • TestServer helper spins up multiple isolated tmux servers

When you might not need libtmux

  • Layouts are static and live entirely in tmux config files
  • You do not need to introspect or control running tmux from other tools
  • Python is unavailable where tmux is running

Project links

Topics: Traversal · Filtering · Pane Interaction · Workspace Setup · Automation Patterns · Context Managers · Options & Hooks

Reference: Docs · API · pytest plugin · Architecture · Changelog · Migration

Project: Issues · Coverage · Releases · License · Support

The Tao of tmux — deep-dive book on tmux fundamentals

Attribution

Please use the following BibTeX template to cite libtmux in scientific discourse:

@misc{libtmux,
   author = {Tony Narlock},
   year = {2016},
   note = {https://libtmux.git-pull.com},
   title = {libtmux: python wrapper for tmux}
}

Contributing & support

Contributions are welcome. Please open an issue or PR if you find a bug or want to improve the API or docs. If libtmux helps you ship, consider sponsoring development via support.

About

⚙️ Python API / wrapper for tmux

libtmux.git-pull.com

Topics

apiclilibrarypythonpython-3terminaltmux

Resources

Readme
MIT license

Contributing

Contributing
Activity
Custom properties

Stars

1.2k stars

Watchers

15 watching

Forks

128 forks
Report repository

Releases

Used by

Contributors

Languages

You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.