atanunq/viu
Terminal image viewer with native support for iTerm and Kitty
Healthy across all four use cases
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 5mo ago
- ✓10 active contributors
- ✓MIT licensed
Show all 7 evidence items →Show less
- ✓CI configured
- ⚠Slowing — last commit 5mo ago
- ⚠Single-maintainer risk — top contributor 82% of recent commits
- ⚠No test directory detected
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/atanunq/viu)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/atanunq/viu on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: atanunq/viu
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/atanunq/viu shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across all four use cases
- Last commit 5mo ago
- 10 active contributors
- MIT licensed
- CI configured
- ⚠ Slowing — last commit 5mo ago
- ⚠ Single-maintainer risk — top contributor 82% of recent commits
- ⚠ No test directory detected
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live atanunq/viu
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/atanunq/viu.
What it runs against: a local clone of atanunq/viu — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in atanunq/viu | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | Last commit ≤ 174 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of atanunq/viu. If you don't
# have one yet, run these first:
#
# git clone https://github.com/atanunq/viu.git
# cd viu
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of atanunq/viu and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "atanunq/viu(\\.git)?\\b" \\
&& ok "origin remote is atanunq/viu" \\
|| miss "origin remote is not atanunq/viu (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 174 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~144d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/atanunq/viu"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
viu is a Rust CLI terminal image viewer that renders images and animated GIFs directly in the terminal using native graphics protocols (iTerm, Kitty, or Sixel) or falls back to Unicode half-block characters. It wraps the viuer crate to provide a lightweight frontend that auto-detects terminal capabilities via $TERM and $COLORTERM environment variables and adapts rendering (truecolor, ANSI256, or basic blocks) accordingly. Simple monolithic CLI structure: src/main.rs is the entrypoint parsing CLI args via clap, src/app.rs contains core application logic, src/config.rs handles configuration. All graphics rendering delegated to the viuer 0.11 library dependency. No plugins, no internal module hierarchy—entirely single-purpose CLI.
👥Who it's for
Terminal power users and systems administrators who need to view images in headless/SSH environments, developers working in terminal-first workflows, and CLI tool builders who want to embed image rendering. Anyone using Kitty, iTerm, or standards-compliant terminals (with fallback support for older terminals).
🌱Maturity & risk
Production-ready with stable 1.6.1 release. Single active maintainer (atanunq), healthy dependency stack (viuer, crossterm, clap, image crates all maintained). Presence in official package repos (Homebrew, Arch Linux, NetBSD) indicates maturity. No visible CI test runs in .github/workflows/rust.yml snippet, which is a minor gap.
Low risk overall: minimal dependency surface (5 main dependencies, all actively maintained), but single-maintainer model means feature requests may have slow turnaround. No evidence of breaking changes in changelog. Primary risk is reliance on viuer crate (upstream) for core graphics protocol implementation; if viuer hits a major breaking change, viu must update. No test files visible in src/ directory suggests limited test coverage.
Active areas of work
No specific recent activity visible in provided data. Last version bump to 1.6.1 with edition 2021. Repository appears stable/mature with no breaking changes indicated. The README mentions experimental Sixel support (behind feature flags sixel and icy_sixel), suggesting periodic refinement.
🚀Get running
git clone https://github.com/atanunq/viu.git
cd viu
cargo install --path .
viu img/giphy.gif
Or install directly: cargo install viu
Daily commands:
# Development build
cargo build
./target/debug/viu <image-file>
# Release build
cargo build --release
./target/release/viu <image-file>
# With experimental Sixel support
cargo run --features sixel -- <image-file>
🗺️Map of the codebase
- src/main.rs: CLI entrypoint with clap argument parsing; defines all user-facing flags (--width, --height, --once, --frame-rate, etc)
- src/app.rs: Core application logic bridging clap args to viuer calls; handles file I/O, stdin, and main rendering loop
- Cargo.toml: Dependency manifest; critical for understanding version constraints on viuer (0.11) and feature flag configuration (sixel/icy_sixel)
- src/config.rs: Configuration structure; likely contains Dimension, FrameRate, or display option structs passed to viuer
- .github/workflows/rust.yml: CI/CD pipeline (if populated); defines build and test commands for PRs
🛠️How to make changes
For CLI features: modify src/main.rs (uses clap derive macros) and src/app.rs. For config: extend src/config.rs. To add new terminal protocol support: file a feature request upstream at viuer repo since viu delegates all rendering. For dimensions/scaling logic: check viuer integration points in src/app.rs. To add tests: create tests/ directory with integration tests (currently absent).
🪤Traps & gotchas
- Terminal capability auto-detection is implicit: viu silently adapts rendering based on $TERM and $COLORTERM without user control; if detection fails, fallback to blocks may appear wrong. 2. GIF behavior differs by input: single GIF loops indefinitely (until Ctrl-C), multiple files display each GIF once only—easy to be surprised. 3. iTerm ignores runtime flags: --frame-rate and --once have no effect on iTerm (iTerm handles GIF internally); undocumented in CLI help. 4. stdin + GIF interaction unclear: README says GIFs can come via stdin but doesn't specify behavior (loop or single-frame?). 5. No feature flag defaults: Sixel is opt-in (behind feature gate), so binary from cargo install won't support Sixel unless compiled with --features.
💡Concepts to learn
- Terminal Graphics Protocols (iTerm2, Kitty, Sixel) — viu's entire value proposition depends on selecting and executing the correct protocol based on terminal capability; understanding these is essential to contributing graphics support or debugging rendering failures.
- Environment Variable-based Feature Detection ($TERM, $COLORTERM) — viu's auto-detection logic relies on parsing these environment variables to decide rendering strategy (protocol vs fallback); incorrect detection is the root cause of most rendering issues.
- Unicode Half-block Characters (▄ U+2584) for Fallback Rendering — When native protocols unavailable, viu degrades to combining Unicode blocks with color (truecolor or ANSI256); understanding block placement is key to fixing fallback rendering bugs.
- GIF Frame Animation and Loop Control — viu has context-dependent GIF behavior (loop on single file, single-frame on multiple); understanding frame timing and signal handling (Ctrl-C) is critical for animation features.
- ANSI 256-color vs Truecolor (16M) Terminal Capabilities — viu selects palette depth based on $COLORTERM; fallback rendering quality depends on this distinction—low-color terminals produce dithered output.
- Aspect Ratio Preservation in Image Scaling — README mentions aspect ratio handling with flags but details omitted; terminal character cells are non-square (2:1 height:width), requiring special scaling logic.
- Clap Derive Macros for CLI Parsing — viu uses clap 4.4 derive syntax (likely #[derive(Parser)] with #[arg] attributes); understanding this declarative style is essential for adding new CLI flags.
🔗Related repos
atanunq/viuer— The upstream core library viu depends on; contains all graphics protocol logic (iTerm, Kitty, Sixel) and image decoding—viu is the CLI wrapper.efi/richtext— Alternative terminal image renderer using ANSI sequences; similar problem space but different approach (text-based vs protocol-based)itsjef/swayimg— Wayland-native image viewer; solves image viewing in Wayland terminal environments where viu's protocol support may not apply.ImageMagick/ImageMagick— Industry standard image processing library; viu uses the Rustimagecrate (pure Rust alternative) but ImageMagick is the ecosystem standard for comparison.kovidgoyal/kitty— The Kitty terminal itself and official graphics protocol specification; critical context for understanding viu's native Kitty support implementation.
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add integration tests for GIF animation playback in src/app.rs
The repo mentions GIF support as a key feature (gifdemo.gif, giphy.gif in img/ and 'gif' in keywords), but there are no visible test files. Integration tests should verify GIF frame parsing, timing, and rendering across different terminal backends (iTerm, Kitty, half-blocks). This ensures the animation feature works reliably.
- [ ] Create tests/gif_integration_tests.rs with test GIF files
- [ ] Test frame extraction and timing from sample GIFs in img/
- [ ] Verify correct rendering output for each protocol (iTerm/Kitty/blocks)
- [ ] Add test cases for edge cases (single frame, corrupted GIFs, various dimensions)
Add macOS universal binary (arm64 + x86_64) support to GitHub Actions CI
The .github/workflows/rust.yml exists but the repo targets macOS users (iTerm support, mentions MacOS in README installation). A dedicated GitHub Actions workflow should build and release universal binaries for both Apple Silicon and Intel Macs, making installation easier for MacOS users.
- [ ] Review current .github/workflows/rust.yml to understand existing CI
- [ ] Add matrix strategy in rust.yml to build for macos-latest with both x86_64 and aarch64 targets
- [ ] Use cargo-cross or native macOS toolchain to produce universal binary
- [ ] Add release asset upload step to attach binaries to GitHub releases
Add unit tests for src/config.rs and src/main.rs argument parsing
The README documents multiple command-line options and features (aspect ratio, width, height, etc.) but no visible test files validate argument parsing. Tests should verify clap integration for all documented CLI flags and ensure config validation works correctly across edge cases.
- [ ] Create tests/cli_tests.rs for command-line argument parsing
- [ ] Test all documented options from README's 'Command line options' section
- [ ] Add tests for conflicting arguments and invalid input combinations
- [ ] Verify feature flag combinations (sixel, icy_sixel) are properly handled
🌿Good first issues
- Add integration tests in tests/ directory (currently missing) covering: single image display, GIF looping behavior, stdin input, and dimension scaling. Start with a simple test that verifies viu exits cleanly with valid image input.
- Document iTerm-specific behavior in src/main.rs clap help text: add a note to --frame-rate and --once flags stating they're ignored on iTerm. Update README usage section with a concrete example.
- Implement explicit terminal protocol override flag (e.g., --protocol=iterm|kitty|sixel|blocks) to allow users to force fallback rendering without relying on $TERM detection. This would help debugging and testing.
⭐Top contributors
Click to expand
Top contributors
- @atanunq — 82 commits
- @mmulet — 5 commits
- @DavidBuchanan314 — 3 commits
- @pepa65 — 2 commits
- @NOBLES5E — 2 commits
📝Recent commits
Click to expand
Recent commits
5733be5— Release 1.6.1 (atanunq)55820ea— Merge pull request #142 from atanunq/macos-aarch (atanunq)e0dda5a— Add macos aarch build (atanunq)5c7a823— Release 1.6.0 (atanunq)d6d92d1— Merge pull request #139 from atanunq/viuer-0.11 (atanunq)5394360— Bump dependencies and add icy_sixel feature (atanunq)8710d04— Merge pull request #138 from pepa65/master (atanunq)fe84ca7— Indirectly use cross (atanunq)5a87c97— Update CI (atanunq)2059cc7— Add --caption to readme (atanunq)
🔒Security observations
The codebase demonstrates good security posture for a terminal utility application. Dependencies are well-maintained and from reputable sources (clap, crossterm, viuer, image, ctrlc). No hardcoded credentials, injection vulnerabilities, or obvious misconfigurations were identified in the visible files. The primary recommendations are: (1) implement dependency auditing in CI/CD, (2) add responsible disclosure guidelines, (3) ensure robust input validation for file paths and image data, and (4) consider more restrictive dependency versioning. The application's minimal attack surface (CLI-only, local file processing) and focus on terminal graphics rendering presents low inherent risk.
- Low · Dependency Version Pinning —
Cargo.toml - dependencies section. Several dependencies use caret (^) version specifications which allow minor and patch version updates automatically. While generally safe for maintenance, this could introduce unexpected behavior changes. The clap dependency (4.4) with default features could pull in additional transitive dependencies. Fix: Consider using more restrictive version specifications (e.g., '=0.25' for image crate) or implementing dependency audit checks in CI/CD pipeline using 'cargo audit'. - Low · Unsafe Feature Flags —
Cargo.toml - features section. Optional features 'sixel' and 'icy_sixel' are enabled conditionally and pass through to the 'viuer' dependency. While this is a legitimate design pattern, custom feature flags should be carefully documented to prevent unintended security implications. Fix: Document security implications of optional features in README. Ensure users are aware of what additional dependencies are pulled when features are enabled. - Low · Missing SECURITY.md —
Repository root. No SECURITY.md file is present in the repository. This makes it difficult for security researchers to report vulnerabilities responsibly. Fix: Create a SECURITY.md file with instructions for responsible disclosure of security vulnerabilities. - Low · Input Handling Best Practices —
src/app.rs, src/main.rs (not fully visible). The application processes user-supplied file paths and image data. While the visible dependencies (viuer, image, crossterm) are well-maintained, there is potential for path traversal or malformed image file handling if input validation is insufficient. Fix: Review file path handling to ensure proper canonicalization and validation. Verify that image processing libraries handle malformed files gracefully without crashes or resource exhaustion.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.