fork of fetch by areofyl
  • C 98.8%
  • Shell 0.7%
  • Makefile 0.5%
Find a file
2026-08-01 03:28:43 +02:00
docs add shading modes docs 2026-07-29 21:11:06 -07:00
.gitignore Add Ubuntu/Debian packaging via Launchpad PPA 2026-07-24 00:20:48 +03:00
demo.gif update demo gif 2026-07-26 16:53:06 -07:00
fetch.c Merge upstream updates and retain custom changes 2026-08-01 03:14:58 +02:00
LICENSE Update LICENSE 2026-04-13 16:29:13 -07:00
Makefile clean up duplicate version define in makefile 2026-07-29 08:47:01 -07:00
PKGBUILD Fix pkgver in PKGBUILD to work without tags 2026-08-01 03:22:02 +02:00
README.md Update README: keep only Arch PKGBUILD instructions, remove other package managers 2026-08-01 03:19:44 +02:00
summary.md Add summary.md to track project changes 2026-08-01 03:28:43 +02:00
VERSION changed in accordance with feedback 2026-07-28 11:24:27 +02:00

fetch (Alex's Fork)

Why we forked this: This is a fork of areofyl/fetch. We forked it to add custom image and 3D model support that isn't present in the upstream repository, as well as remove Nix and adapt the repository exclusively for Arch Linux via a PKGBUILD.

Our Additions:

  • --convert <file>: Uses chafa to convert an image into an ASCII logo that fetch can render in 3D.
  • --3d-model <file.obj>: Directly loads and renders a 3D .obj model instead of an ASCII logo.
  • Custom distro color fallback ("custom").

A donut.c-inspired fetch tool that spins your distro logo in 3D with live-updating system info.

demo

Takes any ASCII/Unicode distro logo, turns each character into a point cloud based on its visual density, and renders it as a rotating 3D relief with Blinn-Phong shading. System info is gathered natively no external dependencies required. Works on Linux and macOS.

Based on gentoo.c.

Build & run

make
./fetch

Press any key to stop the keypress passes through to the shell, so it works as a startup fetch. Ctrl-C works too.

Install

sudo make install

PREFIX=~/.local make install if you don't want it system-wide.

Package Manager

You can install fetch-git directly using the provided PKGBUILD:

makepkg -si

Logos

Custom logos: docs/custom-logos.md

By default it auto-detects your distro and grabs the logo from fastfetch (if installed) with its original per-character colors preserved. Works with any of fastfetch's 500+ distro logos!

You can also specify one directly:

./fetch -l arch
./fetch -l NixOS
./fetch -l asahi

Or drop a custom logo in ~/.config/fetch/logo.txt:

# distro: gentoo
         -/oyddmdhs+:.
     -odNMMMMMMMMNNmhy+-`
...

Without fastfetch, the built-in Gentoo logo is used.

System info

All system info is gathered natively no fastfetch or neofetch needed:

  • OS - /etc/os-release
  • Host - /proc/device-tree/model or /sys/class/dmi/id/product_name
  • Kernel - uname()
  • Uptime - /proc/uptime
  • Packages - emerge, pacman, dpkg, rpm, xbps, apk
  • Shell - parent process detection (not just $SHELL)
  • Display - per-connector DRM enumeration (multi-monitor)
  • WM - process scanning + DE-to-WM mapping
  • Theme/Icons/Font - ~/.config/gtk-3.0/settings.ini (Linux), defaults read (macOS)
  • CPU - /proc/cpuinfo, device-tree (Apple Silicon), or sysctl (macOS)
  • GPU - DRM + lspci for full names (Linux), system_profiler (macOS)
  • Memory/Swap - /proc/meminfo (Linux), vm_stat (macOS)
  • Disk - statvfs() + /proc/mounts (Linux), getmntinfo (macOS) supports multiple mount points via config
  • Battery - energy_now/energy_full (Linux), IOKit (macOS)
  • Packages - emerge, pacman, dpkg, rpm, xbps, apk, flatpak, brew
  • Local IP - getifaddrs()

Stats like memory, battery, and uptime update in real-time while the logo spins.

Config

Full reference: docs/configuration.md

Create ~/.config/fetch/config to customize:

# fields  list to show, in this order
# remove or comment out to hide
os
host
kernel
uptime
packages
shell
display
wm
theme
icons
font
terminal
cpu
gpu
memory
swap
disk
ip
battery
locale
colors

# extra disks (add more mount points)
# disk=/home
# disk=/data

# appearance
# label_color=magenta   (red, green, yellow, blue, magenta, cyan, white)
# separator=─           (character for the title separator)
# shading_mode=ascii    (ascii, or opt into blocks / sextants)
# shading=.,-~:;=!*#$@  (characters for 3D shading, supports UTF-8)
# box=0                 (adds a box around the system-data, 0 = off, 1 = on)

# logo colors (override distro defaults)
# logo_outer=magenta    (extruded side color)
# logo_inner=white      (front/back face color)

# 3d
# light=top-left        (top-left, top-right, top, left, right, front, bottom-left, bottom-right)
# spin=xy               (x, y, or xy)
# speed=1.0             (rotation speed)
# size=1.0              (logo scale, e.g. 2.0 for double size)
# depth=1.0             (3D extrusion depth, e.g. 3.0 for chunkier look)
# height=36             (override render height in rows)

Options

Flag Description
-l, --logo <name> Use a logo from fastfetch by name
--rotate-x Lock rotation to X axis only
--rotate-y Lock rotation to Y axis only
-s, --speed <float> Speed multiplier (default 1.0)
--size <float> Scale the logo (e.g. 2.0 for double size)
--depth <float> Scale the 3D depth (default 1.0)
--height <n> Override render height in rows
--box Draw a border box around the info block
--no-info Just the logo, no system info
--no-color Disable coloring
--frames <n> Stop after n frames
--infinite Run forever
--shading-mode <mode> ascii (default), or opt into sub-cell blocks with sextants (2x3) or blocks (2x2)
--shading-chars <str> Custom shading ramp, supports UTF-8
-h, --help Show help
-V, --version Show version

CLI flags override config file settings.

Shading modes

Full reference: docs/shading-modes.md

ASCII is the default. The sub-cell modes are opt-in, and trade the donut.c look for a silhouette that lands on a fraction of a cell instead of snapping to the character grid.

ascii (default) blocks sextants
ascii blocks sextants
brightness mapped onto .,-~:;=!*#$@, one character per cell coverage sampled 2×2, edges on quadrants coverage sampled 2×3, edges on block sextants

sextants needs a terminal that draws the Symbols for Legacy Computing block (kitty, Ghostty, foot and WezTerm do it themselves, so the font does not matter); blocks works anywhere with a UTF-8 locale.

Same logo, same frame, same terminal palette in all three.

Contributing

PRs are welcome! If you want to add a feature, fix a bug, or package fetch for your distro, go for it. I try to keep the codebase small and easy to understand, so smaller PRs are easier to merge than big ones.

If you want to chat about ideas before writing code, reach out on Reddit or open an issue.

How it works

For a deep dive with visuals and code, see the full blog post.

  1. Logo loading reads ASCII/Unicode art from ~/.config/fetch/logo.txt or grabs a distro logo via fastfetch. ANSI color codes are parsed and preserved per-character.

  2. Heightmap each character gets a weight based on visual density (@ is heavy, . is light, is full, is thin). The weight becomes a Z height, turning the flat logo into a 3D relief map. Logos with low height variance (uniform characters) get their depth auto-scaled so they don't look flat.

  3. Point cloud the heightmap is sampled into 3D points. Interior cells get multiple Z layers for a solid extrusion, edge cells get only front and back faces to keep outlines clean.

  4. Surface normals computed from the height gradient at each cell using finite differences, giving each point a direction for lighting.

  5. Rotation + projection every frame, all points are rotated around X/Y axes, then perspective-projected onto the terminal grid with a z-buffer to handle occlusion.

  6. Shading Blinn-Phong lighting (diffuse + specular) gives every visible point a brightness, which maps onto the .,-~:;=!*#$@ ramp, one character per cell. --shading-mode sextants or blocks instead samples coverage finer than the character cell 2×3 or 2×2 and each cell picks whichever glyph carries the right amount of ink: a shade block (░▒▓█) where the cell is filled, a partial block where the silhouette cuts through it. So an edge lands on a fraction of a cell instead of snapping to the character grid.

    Logos that ship their own colors keep them. The rest are two-toned by surface: front and back faces in logo_inner, extruded sides in logo_outer.

  7. Rendering the entire frame is written in a single write() syscall to avoid flicker. System info is displayed alongside the animation and fast-changing fields (uptime, memory, swap) update live every second.

Single file C, no dependencies beyond libm.