ink-picture
v1.3.3
Published
Better image component for Ink CLI/TUIs
Maintainers
Readme
ink-picture
Better image component for Ink CLI/TUI applications.
Display images in your terminal with automatic protocol detection and graceful fallbacks. Supports Sixel, Kitty image protocol, iTerm2 inline images, ASCII art, and more!
Who's using ink-picture?
- Instagram CLI: CLI and terminal client for Instagram
Feel free to open a PR to showcase your project here!
Installation
npm install ink-pictureBasic Usage
import React from "react";
import { Box, render } from "ink";
import Image, { TerminalInfoProvider } from "ink-picture";
function App() {
return (
<TerminalInfoProvider>
<Box flexDirection="column">
<Image
src="https://example.com/image.jpg"
width={40}
height={20}
alt="Example image"
/>
</Box>
</TerminalInfoProvider>
);
}
render(<App />);[!IMPORTANT] Always wrap your app with
TerminalInfoProvider.
API
<Image>
Main component with automatic protocol detection and fallback.
Props
src(string) - Image URL or file path. Supports all formats handled by Sharp (JPEG, PNG, WebP, AVIF, GIF, SVG, TIFF)width?(number) - Width in terminal cellsheight?(number) - Height in terminal cellsalt?(string) - Alternative text for loading/error statesprotocol?(string) - Force specific protocol:"auto" | "ascii" | "braille" | "halfBlock" | "sixel" | "iterm2" | "kitty"
Protocols
The component automatically selects the best available protocol with the following priority:
- Kitty (
kitty) - True color images in terminals that support the Kitty terminal graphics protocol. - iTerm2 (
iterm2) - True color images in terminals that implements the iTerm2 inline images protocol. - Sixel (
sixel) - True color bitmap graphics in Sixel-compatible terminals. - Half-block (
halfBlock) - Color rendering with Unicode half-blocks (▄). Requires color + Unicode support. - Braille (
braille) - High-resolution monochrome using Braille patterns. Requires Unicode support. - ASCII (
ascii) - Character-based art. Works in all terminals (fallback).
<TerminalInfoProvider>
Required wrapper component that automatically detects terminal capabilities.
Image rendering components depend on terminal information to select the best protocol and size images correctly. All Image components must be wrapped in TerminalInfoProvider.
For best performance, wrap your entire component tree so that terminal info detection is done only once per session.
<TerminalInfoProvider>{/* Your app components */}</TerminalInfoProvider>Under the hood, TerminalInfoProvider wraps a React context which uses a combination of ANSI control sequence queries, environment variables, and heuristics to determine:
- Terminal cell size in pixels
- Unicode and color support
- Supported terminal image protocols
During this detection phase, it will write some escape sequences to stdout and listen for system responses from stdin. This takes sub-second time and should not be visually noticeable.
It should not interfere with user input, but just in case, it is recommended to wrap your entire component tree in TerminalInfoProvider so that detection is finished on startup in order to minimize the chance of any interference.
Individual Components
For advanced usage, import specific renderers:
import {
AsciiImage,
BrailleImage,
HalfBlockImage,
SixelImage,
Iterm2Image,
} from "ink-picture";Hooks
useTerminalInfo()- Complete terminal informationuseTerminalDimensions()- Terminal size in pixels and cellsuseTerminalCapabilities()- Supported features (Unicode, color, graphics)
Important Notes & Caveats
High quality renderers
The Kitty, Sixel, and iTerm2 renderers provide the highest image quality but may not work perfectly in all environments. This is because they rely on hacky side effects to display and clear images.
[!WARNING] These components bypasses React/Ink's normal rendering pipeline and writes directly to the terminal.
You may experience:
- Rendering flicker during updates
- Images may be wiped from the terminal after app termination
These issues are difficult/infeasible to fix and I will not be addressing them in the near future. If you know a solution, please open an issue or PR.
General Considerations
- Images are fetched and processed asynchronously
- Large images are automatically resized to fit terminal constraints
- Terminal capability detection happens once per session
Examples
Static Gallery
<TerminalInfoProvider>
<Box flexDirection="row" gap={2}>
<Image src="./photo1.jpg" width={20} height={15} />
<Image src="./photo2.jpg" width={20} height={15} />
<Image src="./photo3.jpg" width={20} height={15} />
</Box>
</TerminalInfoProvider>Force Specific Protocol
<Image src="./diagram.png" protocol="braille" alt="Technical diagram" />Responsive Sizing
{
/* Image will fit within container bounds */
}
<Box width={50} height={30}>
<Image src="./large-image.jpg" />
</Box>;Choosing the right protocol
Devs using this library are highly encouraged to provide a configuration option to select the image protocol that works best for their users.
If you use ink-picture in your project, feel free to link to this section in your documentation.
Please read if you use a project that uses ink-picture.
ink-picture should work out-of-the-box in most modern terminal emulators. Yet, not all terminals support all image protocols.
Use the table below as a reference to check which protocol to use for your terminal. You might also want to install a better terminal emulator for best experience.
✅ = Fully supported
⚠️ = Partially supported (works but may have issues/caveats)
❌ = Not supported
| Terminal Emulator | Sixel | kitty graphics | iTerm2 inline images | | ----------------------------------------------- | ----- | -------------- | -------------------- | | GNOME Terminal | ❌ | ❌ | ❌ | | Ghostty | ❌ | ✅ | ❌ | | iTerm2 | ✅ | ❌ | ✅ | | Kitty | ❌ | ✅ | ❌ | | Konsole | ⚠️ | ✅ | ⚠️ | | Rio | ✅ | ❌ | ✅ | | VS Code integrated terminal (xterm.js)* | ✅ | ❌ | ✅ | | Warp | ❌ | ⚠️ | ❌ | | Wayst | ❌ | ⚠️ | ❌ | | WezTerm | ✅ | ✅ | ✅ | | Windows Terminal | ✅ | ❌ | ❌ | | XTerm | ✅ | ❌ | ❌ |
Please refer to Are We Sixel Yet? for a comprehensive (but slightly out-of-date) list of terminals that support Sixel graphics.
* For VS Code, make sure you have the settings terminal.integrated.enableImages and terminal.integrated.gpuAcceleration enabled, then restart the integrated terminal. If you are on Windows, you might need to follow the on-screen instructions to configure conPTY.
If you know your terminal supports any of the above protocols but is not listed here, please open an issue or PR to update the table.
Generally, it is recommended to use the kitty protocol if it is fully supported, as it provides near-perfect performance, without any flickers or artifacts.
Otherwise, the performance of sixel and iterm2 protocols are practically the same, so use whichever your terminal supports.
If not provided with a explicit protocol, ink-picture will automatically select the best available protocol based on detected terminal capabilities.
See the protocols section for more details.
Contributing
Contributions are welcome! To contribute:
- Open or comment on an issue describing what you want to change
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Install dependencies:
npm install - Make your changes
- Run tests:
npm test - Open a pull request
License
MIT License, see LICENSE. )
