xfetch has a plugin system that allows extending functionality through standalone executables. Plugins communicate with the core via a JSON protocol over stdin/stdout.
Plugins are standalone executables named xfetch-plugin-<name> (or xfetch-plugin-<name>.exe on Windows). They are spawned as child processes by the xfetch core.
xfetch core ---> stdin (JSON request) ---> plugin process
xfetch core <--- stdout (JSON response) <--- plugin process
xfetch core <--- stderr (error messages) <--- plugin process
There are two types of plugins:
| Kind | Identifier | Purpose |
|---|---|---|
| Logo Animation | logo_animation | Animates ASCII logos with color effects |
| Info Provider | info_provider | Returns system or external information lines |
Protocol Version: 1
Request:
{
"version": 1,
"kind": "info_provider",
"args": {
"username": "xscriptor",
"max_lines": 3
}
}
The args field contains plugin-specific arguments from the configuration. If no arguments are configured, args is null.
Response:
{
"lines": [
"\uf09b X (@xscriptor)",
"\uf005 114 stars",
"\uf441 33 repos"
]
}
Request:
{
"version": 1,
"kind": "logo_animation",
"lines": [
" __ __",
" \\ \\/ /",
" \\ /"
],
"frames": [
["frame 1 line 1", "frame 1 line 2"],
["frame 2 line 1", "frame 2 line 2"]
],
"args": {
"fps": 12,
"duration_ms": 1200,
"loop": false,
"style": "sweep"
}
}
The lines field contains the current ASCII logo. The frames field contains optional pre-loaded frame sets. The args field contains animation parameters.
Response:
{
"frames": [
{
"delay_ms": 83,
"lines": ["\u001b[31mcolored line\u001b[0m", "\u001b[32mnext line\u001b[0m"]
}
]
}
Each frame has a delay_ms (how long to display the frame) and lines (the frame content, potentially with ANSI escape codes for colors).
Plugins must write error messages to stderr and exit with a non-zero status code on failure.
When executing a plugin, xfetch searches for the binary in this order:
$PATH for xfetch-plugin-<name>~/.config/xfetch/plugins/ (Linux/macOS) or %APPDATA%/xfetch/plugins/ (Windows)./plugins/<name>/target/release/# Install from a local directory
xfetch plugin install ./my-plugin
# Install from the official plugin repository
xfetch plugin install animate-logo
# Install from a custom git repository
xfetch plugin install my-plugin --repo https://github.com/user/plugins.git
./<name>/, ./plugins/<name>/, or ./plugins/plugins/<name>/https://github.com/xfetch-cli/plugins.git by default)cargo build --release in the plugin directory~/.config/xfetch/plugins/xfetch-plugin-<name># List installed plugins
xfetch plugin list
# Remove a plugin
xfetch plugin remove animate-logo
Animates ASCII logos with various color effects.
logo_animationxfetch-plugin-animate-logoConfiguration:
{
"logo_animation": {
"plugin": "animate-logo",
"fps": 12,
"duration_ms": 1200,
"loop": false,
"style": "sweep"
}
}
Animation styles:
| Style | Description |
|---|---|
sweep | Colors sweep left-to-right across characters (6-color ANSI palette) |
wave | Sine-wave color pattern across the logo |
rainbow | Full RGB gradient shifting over time (24-bit color) |
sparkle | Random characters light up in bright colors |
breathing | All characters fade in and out in warm amber tones |
frame | Cycles through pre-loaded ASCII frame sets |
none | No coloring, displays logo as-is |
Displays Docker container statistics.
info_providerxfetch-plugin-dockerdocker command in PATH)Configuration:
{
"info_plugins": [{ "plugin": "docker" }],
"modules": ["plugin:docker"]
}
Output:
| State | Example |
|---|---|
| Daemon running | Containers: 15 total, 3 running, 1 paused, 11 stopped |
| Daemon not running | Docker: daemon not running |
| CLI not found | Docker: not found |
Fetches GitHub user statistics.
info_providerxfetch-plugin-github-statscurl CLI in PATHConfiguration:
{
"info_plugins": [{
"plugin": "github-stats",
"args": {
"username": "xscriptor",
"token": "ghp_your_token_here",
"max_lines": 3
}
}],
"modules": ["plugin:github-stats"]
}
Arguments:
| Field | Required | Description |
|---|---|---|
username | Yes (or GITHUB_USER env) | GitHub username |
token | No | Personal access token (5,000 req/hr vs 60 req/hr unauthenticated) |
max_lines | No | Truncate output to first N lines (1-7) |
Output lines: Name + username, Stars, Repos, PRs, Issues, Followers, Following
Displays currently playing music from MPD and/or Spotify.
info_providerxfetch-plugin-music-playermpc (MPD), playerctl (Spotify)Configuration:
{
"info_plugins": [{ "plugin": "music-player" }],
"modules": ["plugin:music-player"]
}
Detection: Checks both MPD (via mpc status) and Spotify (via playerctl -p spotify metadata). If both are active, information from both is shown.
Displays current weather conditions.
info_providerxfetch-plugin-weathercurl CLI in PATHConfiguration:
{
"info_plugins": [{
"plugin": "weather",
"args": {
"location": "London",
"format": "%C|%t|%w|%h|%p"
}
}],
"modules": ["plugin:weather"]
}
Arguments:
| Field | Required | Description |
|---|---|---|
location | No | City name, coordinates, or airport code. Auto-detects by IP if omitted. |
format | No | wttr.in format string. Default: `%C |
Output: Condition (text), temperature, humidity, wind, precipitation. Uses weather condition icons based on the Nerd Font weather icon set.
Displays current time, date, and timezone information.
info_providerxfetch-plugin-timezoneConfiguration:
{
"info_plugins": [{ "plugin": "timezone" }],
"modules": ["plugin:timezone"]
}
Arguments:
| Field | Required | Description |
|---|---|---|
format | No | date format string. Default: %Z %z (timezone name + UTC offset). |
Timezone detection: /etc/timezone > /etc/localtime symlink > timedatectl
Output: Current datetime (e.g., "Thursday, 23 July 2026 14:30"), timezone name, and UTC offset.
Displays user account information.
info_providerxfetch-plugin-user-infoid, getent, groups CLI toolsConfiguration:
{
"info_plugins": [{
"plugin": "user-info",
"args": { "show_groups": true }
}],
"modules": ["plugin:user-info"]
}
Arguments:
| Field | Required | Description |
|---|---|---|
show_groups | No | Show group memberships (max 10). Default: false. |
Output: Username, full name (from GECOS), UID, GID, home directory, shell, and optionally groups.
Detects monitor resolution and refresh rate.
info_providerxfetch-plugin-display-resolutionConfiguration:
{
"info_plugins": [{ "plugin": "display-resolution" }],
"modules": ["plugin:display-resolution"]
}
Platform detection:
| Platform | Method |
|---|---|
| Linux (X11) | xrandr --current (fallback: xdpyinfo) |
| Linux (Wayland) | wlr-randr |
| macOS | system_profiler SPDisplaysDataType |
| Windows | PowerShell GetDeviceCaps |
Output: Monitor name, resolution, and refresh rate. Multiple monitors are supported.
Detects current desktop theme settings.
info_providerxfetch-plugin-theme-detectiongsettings (GTK)Configuration:
{
"info_plugins": [{ "plugin": "theme-detection" }],
"modules": ["plugin:theme-detection"]
}
Detection:
| Environment | Source |
|---|---|
| GTK (GNOME, Budgie, Cinnamon) | gsettings get org.gnome.desktop.interface |
| KDE Plasma | ~/.config/plasmarc and ~/.config/kdeglobals |
Output: GTK theme, icon theme, cursor theme, font, color scheme (dark/light), and KDE Plasma theme if applicable.
xfetch-plugin-<name> (Linux/macOS)
xfetch-plugin-<name>.exe (Windows)
[package]
name = "xfetch-plugin-my-plugin"
version = "0.1.0"
edition = "2024"
[dependencies]
serde = { version = "1", features = ["derive"] }
serde_json = "1"
xfetch-plugin-api = { git = "https://github.com/xfetch-cli/api", package = "xfetch-plugin-api" }
use xfetch_plugin_api::{
read_info_plugin_args_or_default,
write_info_lines,
};
#[derive(Debug, Default, serde::Deserialize)]
struct PluginArgs {}
fn main() {
let _args = match read_info_plugin_args_or_default::<PluginArgs>() {
Ok(value) => value,
Err(err) => {
eprintln!("{}", err);
std::process::exit(1);
}
};
if let Err(err) = write_info_lines(vec!["Hello from plugin".to_string()]) {
eprintln!("{}", err);
std::process::exit(1);
}
}
# Test an info plugin
echo '{"version":1,"kind":"info_provider","args":null}' \
| ./target/release/xfetch-plugin-my-plugin
# Test a logo animation plugin
echo '{"version":1,"kind":"logo_animation","lines":["hello"],"args":{"fps":12}}' \
| ./target/release/xfetch-plugin-my-plugin
The xfetch-plugin-api crate (source at github.com/xfetch-cli/api) provides all the types and helpers needed for plugin development:
AnimationFrame, EmptyArgs, InfoPluginRequest, InfoPluginResponse, LogoAnimationArgs, LogoAnimationRequest, LogoAnimationResponse, PluginKindread_logo_animation_request(), read_info_plugin_request(), read_info_plugin_args_or_default(), write_logo_animation_frames(), write_info_lines()read_json_from_stdin(), write_json_to_stdout()PluginApiError enum with variants for Io, Serialize, Deserialize, InvalidProtocolVersion, InvalidPluginKind, InvalidArgs, EmptyAnimationFramesxfetch-plugin-api crate for protocol types