Skip to main content

⚜ zoetty

What is zoetty?

zoetty turns terminal sessions into small, looping, animated clips made of plain SVG or HTML and CSS. No video, no GIF, no JavaScript.

Package version Python versions PyPI - License

zoetty init writes a starter clip spec, zoetty build renders it to SVG, and zoetty check confirms it is up to date

That's zoetty, recorded by zoetty. Every clip in this README is built from a spec in docs/clips/.

Why use zoetty?

Terminal GIFs go stale, weigh megabytes, look blurry, and have to be re-recorded by hand every time the output changes.

  • Real output - zoetty record runs your commands in a real terminal and keeps their colours.
  • Small and sharp - A clip is a few KB of text, crisp at any size.
  • Works in READMEs - The SVG is just an image: it plays on GitHub, PyPI and anywhere else that shows one.
  • Or in your docs - The HTML fragment drops into any page, with selectable text.
  • Kept in your repo - The spec is a short TOML file. When your tool changes, re-record and rebuild.
  • Checked in CI - zoetty check fails if a clip is out of date.

Install

uv tool install zoetty

Or with pip:

pip install zoetty

zoetty needs Python 3.12 or later, and runs on macOS and Linux.

Quick start

zoetty init docs/clips/hello.toml    # write a starter spec
zoetty build docs/clips/hello.toml   # render it to docs/clips/hello.svg

Then put it in your README like any image:

![What the clip shows](docs/clips/hello.svg)

A basic clip

Two commands, with their output written by hand:

title = "~/my-project"
label = "Typing two commands in a terminal: echo prints a greeting, ls lists three files"
cols = 60

[[run]]
cmd = "echo 'Hello from zoetty!'"
lines = ["Hello from zoetty!"]

[[run]]
cmd = "ls"
lines = ["[blue]docs[/]  README.md  [green]tool.py[/]"]

Typing two commands in a terminal: echo prints a greeting, ls lists three files

Recording real output

Give a run an output file and zoetty record runs the command for real and saves what it printed. input is typed into interactive programs, a line at a time, once each prompt is waiting:

title = "python"
label = "A Python REPL importing zoetty's markup parser and parsing some styled text"
cols = 64

[record]
env = { PYTHON_BASIC_REPL = "1" }

[[run]]
cmd = "python -q"
output = "captures/repl.ansi"
input = """
from zoetty.markup import parse, plain
plain(parse("[bold]zoe[/]tty"))
[s.styles for s in parse("[bold green]ok[/] done")]
"""
zoetty record docs/clips/repl.toml
zoetty build docs/clips/repl.toml

A Python REPL importing zoetty's markup parser and parsing some styled text

Long output scrolls once it passes rows, and [theme] recolours the whole window:

python -m this printing the Zen of Python, scrolling past the bottom of a ten-row terminal

See more examples, including the HTML output and hand-timed clips.

Use it with your coding agent

zoetty is easy for coding agents to drive: specs are small text files, and every command says what it did. Paste this into Claude Code, Codex, Cursor or similar:

Use zoetty to add an animated terminal demo of this project to the README.
Read https://phalt.github.io/zoetty/agents/ first and follow it: install zoetty,
write a clip spec in docs/clips/ that shows the most useful commands, record the
real output with `zoetty record`, build it with `zoetty build`, look at the result,
embed the SVG in README.md, and add `zoetty check docs/clips/*.toml` to CI.

Documentation

👉 Read the full documentation for the clip format, every command, embedding clips and more examples.

Want to help? See CONTRIBUTING.md.

Metadata

Release files for zoetty 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for zoetty 0.1.0
File Size Uploaded Provenance Actions
zoetty-0.1.0.tar.gz 133.0 kB Without provenance Details for zoetty-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for zoetty 0.1.0
File Interpreter ABI Platform Actions
zoetty-0.1.0-py3-none-any.whl Python 3 none any Details for zoetty-0.1.0-py3-none-any.whl

Total release size: 153.4 kB

Release files / zoetty-0.1.0.tar.gz

Download URL zoetty-0.1.0.tar.gz
Size 133.0 kB
Tags Source
SHA-256 checksum
How to use checksums
3b41117c9dae65d4eb46c2625680377146844ed4e8af4884557aaf1323b2c17f
BLAKE2b-256 checksum
How to use checksums
088855de4b2b30305c0797bdd4ccca59c71e42735d32780b246ff05c3feb32b8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / zoetty-0.1.0-py3-none-any.whl

Download URL zoetty-0.1.0-py3-none-any.whl
Size 20.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
61f9058d7fcf40ce6626f46da06f8d141811d71014ec227c4867ed473f9ee60a
BLAKE2b-256 checksum
How to use checksums
8cf4fae8d36f691f41a4c733daa9a6e2f503bf7d3ba920fb3a2afa451cb9e445
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for zoetty 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page