How FastFetch Renders Logos in Terminals Using Different Protocols
FastFetch renders terminal logos through a three-stage pipeline involving option parsing, capability detection, and protocol-specific rendering via Kitty, iTerm2, Sixel, Chafa, or ASCII fallbacks.
FastFetch, maintained in the fastfetch-cli/fastfetch repository, displays distribution logos alongside system information by adapting to diverse terminal capabilities. The tool implements a sophisticated rendering engine that detects emulator support and selects appropriate graphics protocols dynamically. Understanding how FastFetch renders logos in terminals using different protocols reveals the mechanisms behind seamless image display in text-based environments.
The Three-Stage Logo Rendering Pipeline
The rendering process follows a strict pipeline defined in the source code, moving from user input to terminal output through distinct phases.
Stage 1: Option Parsing and Type Selection
When you invoke FastFetch with flags like --logo-type kitty, the function ffOptionsParseLogoCommandLine in src/options/logo.c (lines 29-69) processes the arguments. This parser maps string inputs to the FFLogoType enumeration and stores the selection in instance.config.logo.type. The parser also captures auxiliary parameters including image paths, padding values, and color settings.
Available logo types include built-in ASCII art, small variants, and image protocols: FF_LOGO_TYPE_IMAGE_KITTY, FF_LOGO_TYPE_IMAGE_ITERM, FF_LOGO_TYPE_IMAGE_SIXEL, FF_LOGO_TYPE_IMAGE_CHAFA, FF_LOGO_TYPE_IMAGE_RAW, and FF_LOGO_TYPE_IMAGE_KITTY_DIRECT.
Stage 2: Terminal Capability Detection
Before rendering images, FastFetch verifies that the terminal supports the requested protocol. The ffDetectTerminal function in src/detection/terminalshell/terminalshell.c (lines 560-590) examines the $TERM environment variable and the terminal's process name. For Kitty detection, FastFetch specifically checks ffStrbufIgnCaseEqualS(&terminal->processName, "kitty") and queries the terminal using the escape sequence \eP+q…\e\ to confirm graphics protocol support.
This detection mechanism ensures FastFetch only attempts to send binary image data to terminals capable of interpreting it, preventing garbled output on incompatible emulators.
Stage 3: Protocol-Specific Output and Fallback
The ffLogoPrint function in src/logo/logo.c orchestrates the final output. When options->type indicates an image protocol, FastFetch prepares an FFLogoRequestData structure containing target dimensions and cache paths, then invokes printImageIfExists from src/logo/image/image.c.
For unsupported protocols or detection failures, FastFetch gracefully falls back to ffLogoPrintChars, which renders built-in ASCII logos line-by-line.
Supported Graphics Protocols
FastFetch implements distinct rendering strategies for each major terminal graphics protocol, generating specific escape sequences and handling image data accordingly.
Kitty Graphics Protocol (FF_LOGO_TYPE_IMAGE_KITTY): The printImageKitty function in src/logo/image/image.c (lines 512-518) emits the escape sequence \e_Gf=100,a=T,...\e\\ containing base64-encoded PNG data. For direct mode (FF_LOGO_TYPE_IMAGE_KITTY_DIRECT), FastFetch sends raw PNG bytes without base64 encoding. The FF_LOGO_TYPE_IMAGE_KITTY_ICAT variant invokes the external kitten icat utility and pipes its output.
iTerm2 Inline Images (FF_LOGO_TYPE_IMAGE_ITERM): The printImageIterm function in src/logo/image/image.c (lines 9-15) generates the escape sequence \e]1337;File=…\a, embedding base64-encoded image data within the proprietary iTerm2 protocol used on macOS.
Sixel Graphics (FF_LOGO_TYPE_IMAGE_SIXEL): The printImageSixel function in src/logo/image/image.c (lines 35-41) outputs the SIXEL bitmap format using the control sequence ESC P … ESC \\, compatible with XTerm, mintty, and other classical terminal emulators.
Chafa Unicode Blocks (FF_LOGO_TYPE_IMAGE_CHAFA): When compiled with FF_HAVE_CHAFA, FastFetch uses the Chafa library to convert images into colored Unicode block characters, outputting standard ANSI color codes rather than binary graphics protocols.
Raw Image Protocol (FF_LOGO_TYPE_IMAGE_RAW): The ffLogoPrintCharsRaw function sends the escape sequence \e[9999999C… followed by raw pixel data for terminals supporting the generic image-raw specification.
Built-in ASCII (FF_LOGO_TYPE_BUILTIN / FF_LOGO_TYPE_SMALL): Renders static ASCII art stored in the binary, accessed via ffLogoPrintChars when image protocols are unavailable or explicitly disabled.
Image Processing and Caching
When rendering custom image files, FastFetch leverages ImageMagick through the printImageIfExistsSlowPath function. This routine loads the source image, rescales it to fit the terminal's character cell dimensions, and rasterizes the result. To optimize repeated executions, FastFetch caches processed image data in protocol-specific cache files (e.g., kittyc or kittyu for Kitty graphics) and stores them in the user's cache directory. Subsequent invocations retrieve the processed data directly, avoiding redundant ImageMagick operations unless the source file modification time changes.
Command-Line Usage Examples
Control FastFetch's logo rendering behavior through specific command-line flags:
# Auto-detect and display built-in ASCII logo (default behavior):
fastfetch
# Force Kitty graphics protocol with a custom PNG image:
fastfetch --logo-type kitty --logo /path/to/logo.png
# Use iTerm2's inline image protocol on macOS:
fastfetch --logo-type iterm --logo ~/Pictures/arch.png
# Render with Sixel graphics in XTerm or compatible terminals:
fastfetch --logo-type sixel --logo ~/.config/fastfetch/logo.fflogo
# Display small variant of a built-in distribution logo:
fastfetch --logo-type small --logo arch
# Disable logo output entirely:
fastfetch --logo none
Summary
- FastFetch implements a three-stage pipeline for logo rendering: option parsing (
src/options/logo.c), terminal detection (src/detection/terminalshell/terminalshell.c), and protocol output (src/logo/image/image.c). - The tool supports six distinct rendering methods: Kitty (standard, direct, and icat variants), iTerm2, Sixel, Chafa, Raw, and ASCII fallback.
- Image processing occurs through ImageMagick with intelligent caching in protocol-specific formats (e.g.,
kittycfiles). - Graceful degradation ensures terminals without graphics support receive readable ASCII art instead of binary escape sequences.
Frequently Asked Questions
What graphics protocols does FastFetch support for terminal logos?
FastFetch supports Kitty graphics protocol (including direct and icat modes), iTerm2 inline images, Sixel, Chafa (Unicode block rendering), and a Raw image protocol. For terminals lacking graphics capabilities, it falls back to built-in ASCII art. Each protocol maps to a specific FFLogoType constant and generates distinct escape sequences defined in src/logo/image/image.c.
How does FastFetch detect which logo protocol to use?
FastFetch detects capabilities through the ffDetectTerminal function in src/detection/terminalshell/terminalshell.c, which examines the $TERM variable and terminal process names. For Kitty, it specifically checks the process name and queries the terminal with the escape sequence \eP+q…\e\. Detection results determine whether FastFetch attempts image rendering or falls back to ASCII.
Can I force FastFetch to use a specific logo type regardless of terminal detection?
Yes. Use the --logo-type flag with values like kitty, iterm, sixel, chafa, raw, builtin, or small. The ffOptionsParseLogoCommandLine function in src/options/logo.c overrides auto-detection and sets the corresponding FFLogoType in the configuration, forcing the specified rendering method even if the terminal reports different capabilities.
What happens if my terminal does not support the requested image protocol?
FastFetch implements graceful degradation. If ffLogoPrint determines the terminal cannot handle the requested protocol (e.g., missing Kitty support when --logo-type kitty is forced), it either attempts alternative protocols (such as falling back from Kitty to Chafa) or invokes ffLogoPrintChars to display the built-in ASCII logo, ensuring readable output without terminal corruption.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →