| Crates.io | ttyvid |
| lib.rs | ttyvid |
| version | 0.2.7 |
| created_at | 2025-10-13 23:12:18.863688+00 |
| updated_at | 2025-10-16 13:21:26.508764+00 |
| description | Convert terminal recordings to video (GIF/WebM) with embedded fonts, themes, and MCP server for AI assistants |
| homepage | https://github.com/watkinslabs/ttyvid |
| repository | https://github.com/watkinslabs/ttyvid |
| max_upload_size | |
| id | 1881295 |
| size | 45,190,466 |
Complete terminal recording and video generation tool. Record terminal sessions directly to .cast files, then convert to GIF/WebM with themes, animations, and custom fonts. High-performance Rust implementation with built-in PTY recording, full terminal emulation, TrueType font support, and 56+ embedded classic bitmap fonts.

Example: fdwm-x theme with animated window decoration overlay and 9-slice frame scaling

Example: Full-size terminal recording
--clonecargo install ttyvid
git clone https://github.com/watkinslabs/ttyvid.git
cd ttyvid
cargo build --release
The binary will be at target/release/ttyvid.
Use ttyvid directly from Claude Code and other AI assistants! The MCP server is built directly into ttyvid - no separate installation needed.
Configure Claude Code:
Add to your MCP settings (e.g., ~/.config/claude/mcp.json):
{
"mcpServers": {
"ttyvid": {
"command": "ttyvid",
"args": ["--mcp"]
}
}
}
Or if installed via cargo:
{
"mcpServers": {
"ttyvid": {
"command": "/path/to/ttyvid",
"args": ["--mcp"]
}
}
}
Start MCP server manually (for testing):
ttyvid --mcp
The server runs on stdio and implements the Model Context Protocol 2025-06-18, exposing these tools:
Core Tools:
record - Record terminal sessions directly to .cast, GIF, or WebMconvert_recording - Convert .cast files to GIF/WebM with full customization
get_version - Get ttyvid version informationDiscovery Tools:
list_themes - List all 10 available themeslist_fonts - List all 56+ embedded bitmap fontslist_system_fonts - List all available system TrueType fonts (monospace recommended)Analysis Tools:
inspect_recording - Analyze .cast files (dimensions, duration, event count, metadata)preview_frame - Generate single frame preview at specific timestamppreview_theme - Generate theme preview showing color paletteBatch Tools:
batch_convert - Convert multiple .cast files in one operationPlatform Optimization:
optimize_for_platform - Auto-optimize for Twitter, YouTube, LinkedIn, TikTok, GitHub, Instagram, Slack, DEV.to
fit_to_time - automatically speed up video to fit target durationstart_time / end_time - trim video to specific time rangeUse it naturally in Claude:
User: "List available system fonts"
Claude: [Uses list_system_fonts tool]
Claude: "Found 116 fonts including Liberation Mono, Noto Sans Mono, Source Code Pro..."
User: "Convert my recording.cast to GIF with fdwm-x theme at 30fps using JetBrains Mono"
Claude: [Automatically converts using ttyvid MCP tool]
Claude: "Done! Created output.gif with fdwm-x theme at 30fps using JetBrains Mono font"
User: "What's in this demo.cast file?"
Claude: [Uses inspect_recording tool]
Claude: "This recording is 80x24, runs for 45.2 seconds, and has 1,234 events"
User: "Optimize this for Twitter"
Claude: [Uses optimize_for_platform with platform='twitter']
Claude: "Optimized for Twitter! Created square 680x680 GIF at 10fps with simple theme. Ready to tweet!"
User: "Fit this 60 second demo into 30 seconds for Instagram"
Claude: [Uses optimize_for_platform with platform='instagram', fit_to_time=30]
Claude: "Optimized for Instagram! Sped up 2.0x to fit 60s into 30s, square 1080x1080 at 12fps."
User: "Trim the first 5 seconds and last 10 seconds, then optimize for YouTube"
Claude: [Uses optimize_for_platform with platform='youtube', start_time=5.0, end_time=-10]
Claude: "Optimized for YouTube! Trimmed to 5.0s-50.0s (45s total), 720p at 15fps."
Complete workflow:
# Step 1: Record a terminal session to .cast file
ttyvid record demo.cast
# ... interact with your terminal ...
# Exit shell (Ctrl+D or 'exit') to stop recording
# Step 2: Convert .cast to GIF or WebM
ttyvid convert -i demo.cast -o demo.gif
Direct conversion (without recording):
# Convert live terminal output via pipe
echo "Hello World" | ttyvid convert -o hello.gif
# Convert existing asciicast file
ttyvid convert -i recording.cast -o output.gif
Output formats:
# .cast file - Asciicast v2 format (compatible with asciinema)
ttyvid record output.cast
# GIF - Animated GIF with themes and effects
ttyvid convert -i recording.cast -o output.gif
# WebM - AV1-encoded video (requires --features webm)
ttyvid convert -i recording.cast -o output.webm
Advanced options:
# Clone your terminal appearance (auto-detect size, colors, and font)
ttyvid convert -i recording.cast -o output.gif --clone
# Use system font with UTF-8 support
ttyvid convert -i recording.cast -o output.gif --system-font "JetBrains Mono"
# Apply theme with custom settings
ttyvid convert -i recording.cast -o output.gif --theme fdwm-x --fps 30 --speed 1.5
Use system fonts instead of bitmap fonts for better UTF-8 character support:
# Use a specific system font
ttyvid convert -i recording.cast -o output.gif --system-font "JetBrains Mono"
# Use system default monospace font
ttyvid convert -i recording.cast -o output.gif --system-font monospace
# Keywords: "monospace", "default", or "system" all use system default
ttyvid convert -i recording.cast -o output.gif --system-font default
# Specify font size (in pixels, default: 16)
ttyvid convert -i recording.cast -o output.gif --system-font monospace --font-size 20
# Load font from file path
ttyvid convert -i recording.cast -o output.gif --system-font /path/to/font.ttf
List available fonts:
# List all system TrueType fonts
ttyvid list-fonts --system
# List embedded bitmap fonts
ttyvid list-fonts --bitmap
# List both
ttyvid list-fonts
Font features:
Font fallback chain:
Clone your current terminal's appearance for authentic recordings:
# Auto-detect terminal size, colors, and font
ttyvid convert -i recording.cast -o output.gif --clone
# Just use terminal colors (with theme or bitmap font)
ttyvid convert -i recording.cast -o output.gif --terminal-colors
What gets cloned:
ttyvid supports full 256-color terminal palettes with automatic terminal color detection:
256-Color Palette:
Color modes:
# Use theme's predefined palette
ttyvid convert -i recording.cast -o output.gif --theme fdwm-x
# Query and use your terminal's actual colors
ttyvid convert -i recording.cast -o output.gif --terminal-colors
# Clone terminal appearance (includes colors, size, and font)
ttyvid convert -i recording.cast -o output.gif --clone
Terminal color querying:
Implementation:
src/renderer/colors.rs:60-108 - Full 256-color palette with system/cube/grayscalesrc/renderer/colors.rs:19-58 - Live terminal color querying via OSC 4/10/11310+ Unicode characters supported for TUI applications like bpytop, htop, etc.:
Rendering modes:
ttyvid includes built-in PTY-based terminal recording, eliminating the need for external tools like asciinema.
# Start recording - launches your default shell
ttyvid record output.cast
# Record with custom shell
ttyvid record output.cast --shell /bin/zsh
# Record with specific dimensions
ttyvid record output.cast --columns 120 --rows 30
ttyvid record [OPTIONS] <OUTPUT>
Arguments:
<OUTPUT> Output .cast file path
Options:
-s, --shell <SHELL> Shell to execute [default: $SHELL or /bin/sh]
-c, --columns <COLS> Terminal width [default: 80]
-r, --rows <ROWS> Terminal height [default: 24]
-h, --help Print help
exit) to stop recordingPython uses buffered output by default, which can cause issues with terminal recording. Understanding Python's buffering behavior is essential for successful recordings.
Python Buffering Modes:
\n → Works perfectly ✅Example - Works Fine:
# Line-buffered: newlines trigger output
for i in range(5):
print(f"Frame {i}") # Has \n at end
time.sleep(0.5)
# ✅ Each frame recorded at 0.5s intervals
Example - Gets Buffered:
# Fully-buffered: no newlines
for i in range(5):
print(f"Frame {i}", end='') # No \n!
time.sleep(0.5)
# ❌ All output compressed into single event at exit
Workarounds (no code changes needed):
# Option 1: Use --python-unbuffered flag (easiest!)
ttyvid record output.cast --python-unbuffered -- python3 script.py
# Option 2: Set PYTHONUNBUFFERED environment variable
PYTHONUNBUFFERED=1 ttyvid record output.cast -- python3 script.py
# Option 3: Use python -u flag
ttyvid record output.cast -- python3 -u script.py
The --python-unbuffered flag automatically sets PYTHONUNBUFFERED=1 for the recorded process, forcing Python to use unbuffered I/O mode where all output is immediately visible to ttyvid's PTY.
Why this happens: Python detects it's connected to a PTY and uses line-buffering, but without newlines (\n), output stays in the buffer until the program exits or the buffer fills up.
echo -e "Hello \e[31mRed\e[0m World" | ttyvid convert -o hello.gif
ttyvid convert -i recording.cast -o output.gif
ttyvid convert -i recording.cast -o output.gif \
--theme windows7 \
--font IBM_VGA8 \
--fps 30 \
--speed 1.5
ttyvid convert \
--input recording.cast \
--output output.gif \
--theme mac \
--font Verite_9x16 \
--fps 30 \
--speed 2.0 \
--columns 80 \
--rows 25 \
--title "My Demo" \
--no-gaps \
--trailer
The --trailer option adds 1.5 seconds of the final frame at the end before looping, creating a pause effect for better viewing.
ttyvid record [OPTIONS] <OUTPUT>
Arguments:
<OUTPUT> Output .cast file path
Options:
-s, --shell <SHELL> Shell to execute [default: $SHELL or /bin/sh]
-c, --columns <COLS> Terminal width [default: 80]
-r, --rows <ROWS> Terminal height [default: 24]
-h, --help Print help
ttyvid convert [OPTIONS] --output <FILE>
Options:
-i, --input <FILE> Input asciicast file (reads from stdin if not provided)
-o, --output <FILE> Output file (.gif or .webm)
-t, --theme <THEME> Theme name or path [default: default]
-f, --font <FONT> Font name (bitmap font)
--system-font <FONT> System font name, file path, or TrueType/OpenType
Use "monospace", "default", or "system" for system default
--font-size <SIZE> Font size in pixels for TrueType fonts [default: 16]
--clone Auto-detect terminal size, colors, and font
--terminal-colors Use terminal's color palette
--fps <FPS> Frames per second (3-100) [default: 10]
--speed <SPEED> Speed multiplier [default: 1.0]
-c, --columns <COLUMNS> Terminal width in columns
-r, --rows <ROWS> Terminal height in rows
-l, --loop <LOOP> Number of loops (0 = infinite) [default: 0]
-d, --delay <DELAY> Delay before loop restart (milliseconds) [default: 100]
-g, --no-gaps Remove gaps in recording
--trailer Add trailer at end
--title <TITLE> Title text
--no-autowrap Disable auto line wrap
--no-cursor Hide cursor in output
--underlay <UNDERLAY> Underlay image path
--quality <QUALITY> WebM quality 0-100 [default: 50]
-h, --help Print help
-V, --version Print version
ttyvid list-fonts [OPTIONS]
Options:
--system Show system TrueType fonts
--bitmap Show embedded bitmap fonts
-h, --help Print help
Examples:
ttyvid list-fonts --system # List all system fonts
ttyvid list-fonts --bitmap # List embedded bitmap fonts
ttyvid list-fonts # List both
ttyvid --mcp
Start the Model Context Protocol (MCP) server for AI assistant integration.
The server runs on stdio and implements MCP version 2025-06-18.
Available MCP Tools (11 total):
Core Tools:
- record Record terminal sessions to .cast/GIF/WebM
- convert_recording Convert .cast files to GIF/WebM with full options
(themes, fonts, dimensions, speed, multi-format)
- get_version Get ttyvid version information
Discovery Tools:
- list_themes List all 10 available themes
- list_fonts List all 56+ embedded bitmap fonts
- list_system_fonts List all system TrueType fonts
Analysis Tools:
- inspect_recording Analyze .cast metadata (dimensions, duration, events)
- preview_frame Generate single frame preview at timestamp
- preview_theme Generate theme preview with color palette
Batch Tools:
- batch_convert Convert multiple .cast files at once
Platform Optimization:
- optimize_for_platform Auto-optimize for social media platforms
Platforms: twitter, youtube, linkedin, tiktok,
github, instagram, slack, devto
Parameters:
- input: Path to .cast file (required)
- output: Output file path (required)
- platform: Target platform name (required)
- theme: Custom theme override (optional)
- fit_to_time: Target duration in seconds (optional)
Automatically speeds up video to fit
- start_time: Trim start in seconds (optional)
- end_time: Trim end in seconds (optional)
Example: {"platform": "twitter"} → 680x680, 10fps, simple theme
Example:
ttyvid --mcp # Start MCP server on stdio
Integration:
Add to ~/.config/claude/mcp.json:
{
"mcpServers": {
"ttyvid": {
"command": "ttyvid",
"args": ["--mcp"]
}
}
}
This Rust implementation is significantly faster than the original Python/Cython version:
Recording:
Shell → PTY → Recorder → .cast file
Converting:
Input (stdin/cast) → Terminal Emulator →
Renderer → Encoder → Output (GIF/WebM)
All fonts are automatically embedded at compile time from themes/fonts/:
Built-in themes in themes/:
default - Classic terminal lookwindows7 - Windows 7 CMD style with dialog framemac - macOS Terminal style with window controlsfdwm - Floating window manager themefdwm-x - Extended window manager with animationsgame - Retro gaming console framebar - Status bar themeopensource - Open source branding bannerscripted - Script demonstration with annotationssimple - Minimal theme (terminal only)ttyvid features a powerful layer-based theme system that allows extensive customization of the final output with support for animated components, flexible positioning, and multiple scaling modes.
Themes are built from layers - individual image files (GIF/PNG) that are composited together:
Each layer can be:
Layers support multiple rendering modes for different visual effects:
mode: copy
Direct pixel-perfect copying from source to destination. Ideal for static decorative elements.
mode: tile
Repeats the layer image across the entire canvas. Perfect for textured backgrounds or patterns.
mode: center
Centers the layer on the canvas. Useful for logos or centered decorative elements.
mode: scale
Scales the layer to fit the destination bounds using nearest-neighbor interpolation.
mode: 9slice
nineslice:
outer_left: 10
outer_top: 10
outer_right: 10
outer_bottom: 10
inner_left: 20
inner_top: 20
inner_right: 20
inner_bottom: 20
Advanced scaling that preserves corners and edges while stretching the center. Essential for window frames and dialogs that need to resize without distorting decorative borders.
How it works:
mode: 3slice
Similar to 9-slice but for horizontal or vertical stretching only. Useful for title bars and status bars.
Layers support animated GIF files with full control over playback:
layers:
- depth: -1
file: layers/animated-background.gif
mode: center
animation:
speed: 1.5 # 1.5x speed multiplier
loop: true # Loop animation
start_frame: 0 # Start at first frame
Animation features:
Flexible positioning system with support for absolute and relative coordinates:
layers:
- depth: 1
file: layers/window-controls.gif
mode: copy
dst_bounds:
left: 10 # 10 pixels from left
top: 10 # 10 pixels from top
right: -110 # 110 pixels from right edge (negative = from right)
bottom: auto # Auto-calculate based on image size
Positioning options:
auto for automatic sizingCreate a custom theme with window frame and animated decorations:
name: my-custom-theme
background: 0 # Black background
foreground: 7 # White text
transparent: 0 # Transparency color index
padding:
left: 20
top: 40
right: 20
bottom: 20
title:
foreground: 15 # Bright white
background: 4 # Red
x: 30
y: 10
font_size: 1.5
layers:
# Background frame (underlay)
- depth: -1
file: layers/my-frame.gif
mode: 9slice
nineslice:
outer_left: 0
outer_top: 0
outer_right: auto
outer_bottom: auto
inner_left: 30
inner_top: 30
inner_right: auto
inner_bottom: auto
# Animated decoration (overlay)
- depth: 1
file: layers/spinner.gif
mode: copy
animation:
speed: 2.0
loop: true
dst_bounds:
left: -50
top: 10
right: auto
bottom: auto
Embedded layers (included in binary):
Custom layers (filesystem):
themes/layers/ or specify full paththemes/layers/your-layer.giflayers:
- depth: -1
file: layers/your-layer.gif
mode: 9slice
ttyvid -i test.cast -o output.gif --theme my-themeThe theme system is fully extensible - you can mix embedded assets with custom images, create complex multi-layer compositions, and animate individual components independently for professional-looking terminal recordings.
ttyvid includes GPU acceleration by default using wgpu for dramatically faster frame rendering with GPU batch processing.
# Default installation includes GPU support
cargo install ttyvid
# Build from source (includes GPU by default)
cargo build --release
# CPU-only build (opt-out of GPU for minimal binary)
cargo install ttyvid --no-default-features --features webm
GPU batch rendering provides significant speedups:
Both CPU and GPU modes feature enhanced progress display:
| Feature | Original (Python) | ttyvid (Rust) | Status |
|---|---|---|---|
| Terminal Emulation | Custom | Full ANSI/VT100 | ✅ |
| GIF Encoding | Custom | gif crate | ✅ |
| WebM Encoding | N/A | rav1e (AV1) | ✅ |
| Font Support | 50+ .fd fonts | 56 bitmap + TrueType | ✅ |
| UTF-8 Characters | Limited | 310+ characters | ✅ |
| Terminal Cloning | N/A | Full (size/colors/font) | ✅ |
| Theme System | Full with layers | Full with layers | ✅ |
| GPU Acceleration | N/A | Default (wgpu batch) | ✅ |
| Progress Tracking | Basic | ETA + Total Time | ✅ |
| Performance | Good | Excellent | ✅ |
| Binary Size | N/A (Python) | ~5-8 MB | ✅ |
| Dependencies | Python + libs | None (static) | ✅ |
# Debug build
cargo build
# Release build (optimized)
cargo build --release
# Build with WebM support (requires rav1e)
cargo build --release --features webm
# Run tests
cargo test
# Run with example
echo "Test" | cargo run --release -- -o test.gif
The project uses build.rs to automatically:
themes/fonts/ directoryTo add new fonts, simply place .fd files in themes/fonts/ and rebuild.
MIT
Contributions welcome! Areas of interest: