Skip to content

fastfetch: add new package#29564

Closed
AlbrechtL wants to merge 1 commit into
openwrt:masterfrom
AlbrechtL:add-fastfetch-support
Closed

fastfetch: add new package#29564
AlbrechtL wants to merge 1 commit into
openwrt:masterfrom
AlbrechtL:add-fastfetch-support

Conversation

@AlbrechtL
Copy link
Copy Markdown
Contributor

Fastfetch is a neofetch-like tool for fetching system information and displaying it in a visually appealing way.

📦 Package Details

Maintainer: @AlbrechtL
(You can find this by checking the history of the package Makefile.)

Description:

Fastfetch is a neofetch-like tool for fetching system information and displaying it in a visually appealing way.

Example

root@OpenWrt:~# fastfetch 
 _______                        root@OpenWrt
|       |.-----.-----.-----.    ------------
|   -   ||  _  |  -__|     |    OS: OpenWrt SNAPSHOT mips
|_______||   __|_____|__|__|    Host: Zyxel GS1900-8 A1 Switch
         |__|                   Kernel: Linux 6.18.26
 ________        __             Uptime: 1 hour, 2 mins
|  |  |  |.----.|  |_           Packages: 102 (apk)
|  |  |  ||   _||   _|          Shell: ash 1.37.0
|________||__|  |____|          Terminal: dropbear
                                CPU: gs1900-8-a1 @ 0.50 GHz
                                Memory: 53.67 MiB / 116.73 MiB (46%)
                                Swap: Disabled
                                Disk (/): 2.08 MiB / 7.94 MiB (26%) - overlay
                                Disk (/overlay): 2.08 MiB / 7.94 MiB (26%) - jffs2
                                Local IP (switch.1): 192.168.1.1/24
                                Locale: C

🧪 Run Testing Details

  • OpenWrt Version:
    OpenWrt SNAPSHOT, r34251+1-e4b3d5c799
  • OpenWrt Target/Subtarget:
    realtek/rtl838x
  • OpenWrt Device:
    zyxel_gs1900-8-a1

✅ Formalities

  • I have reviewed the CONTRIBUTING.md file for detailed contributing guidelines.

If your PR contains a patch:

  • It can be applied using git am
  • It has been refreshed to avoid offsets, fuzzes, etc., using
    make package/<your-package>/refresh V=s
  • [] It is structured in a way that it is potentially upstreamable
    (e.g., subject line, commit description, etc.)
    We must try to upstream patches to reduce maintenance burden.

Fastfetch is a neofetch-like tool for fetching system information and displaying it in a visually appealing way.

Signed-off-by: Albrecht Lohofener <albrecht@albrechtloh.de>
@AlbrechtL
Copy link
Copy Markdown
Contributor Author

I just realized that there is already an open PR for this tool here: #27949

@GeorgeSapkin
Copy link
Copy Markdown
Member

I'm not sure I understand the utility of these tools on mostly-embedded hardware.

@BKPepe
Copy link
Copy Markdown
Member

BKPepe commented May 26, 2026

I am on this one with @GeorgeSapkin. Similar PR for fancy tool to vizualize system details is this one: #29292 (review)

I understand that three users are interested in adding neofetch/fastfetch/afetch, but all of these are just "super cool" gadgets that display system information. Do we really need to have all three of these programs here in the repository? We are not in a position where we can prioritize quantity over quality.

I would be more interested in knowing why we should add this package. We can get this system information via the CLI, it's displayed in LuCI, and either way, if a user wants to install this package, they have to do it through LuCI or the CLI.

And since there is no LuCI interface for any of these packages, we are left only with the CLI.

In general, for all pull requests that add these kinds of "super cool" gadgets, I would like to know how much space they take up on the router. Let's keep in mind that adding a single package here means the OpenWrt buildbots will compile it for all platforms. This not only increases build time but also consumes resources for building the package—not just within OpenWrt, but for downstream distributions as well.

I definitely don't want to discourage you from adding packages or contributing to OpenWrt, but we need to look at the bigger picture and consider whether this package is truly useful. Keep in mind that OpenWrt supports devices with as little as 16 MB flash and 128 MB RAM, and this is Rust.

@stangri
Copy link
Copy Markdown
Member

stangri commented May 26, 2026

@BKPepe @GeorgeSapkin food for thought: I've built this for x86_64, the APK size is about 500kb, the installed binary size on device is ~ 1.3Mb.

Honestly, for the output it provides, this is a shell script Claude generated which does the same and takes ~6kb:

#!/bin/sh
# Lightweight fastfetch-style system info for OpenWrt.

if [ -t 1 ] && [ "${TERM:-dumb}" != dumb ]; then
	C_BLUE=$(printf '\033[1;34m')
	C_GREEN=$(printf '\033[32m')
	C_YELLOW=$(printf '\033[93m')
	C_RED=$(printf '\033[91m')
	C_RST=$(printf '\033[0m')
else
	C_BLUE= C_GREEN= C_YELLOW= C_RED= C_RST=
fi

pct_color() {
	if [ "$1" -gt 80 ]; then printf '%s' "$C_RED"
	elif [ "$1" -gt 50 ]; then printf '%s' "$C_YELLOW"
	else printf '%s' "$C_GREEN"
	fi
}

logo() {
	cat <<'EOF'
 _______
|       |.-----.-----.-----.
|   -   ||  _  |  -__|     |
|_______||   __|_____|__|__|
         |__|
 ________        __
|  |  |  |.----.|  |_
|  |  |  ||   _||   _|
|________||__|  |____|
EOF
}

human_kib() {
	awk -v k="$1" 'BEGIN{
		if (k >= 1048576) printf "%.2f GiB", k/1048576
		else printf "%.2f MiB", k/1024
	}'
}

get_user_host() { printf '%s@%s' "$(id -un)" "$(uname -n)"; }

get_os() {
	if [ -r /etc/os-release ]; then
		. /etc/os-release
		printf '%s %s %s' "${NAME:-Linux}" "${VERSION:-}" "$(uname -m)"
	else
		printf '%s %s' "$(uname -s)" "$(uname -m)"
	fi
}

get_host() {
	model= rev=
	if [ -r /tmp/sysinfo/model ]; then
		model=$(cat /tmp/sysinfo/model)
	elif [ -r /sys/devices/virtual/dmi/id/product_name ]; then
		model=$(cat /sys/devices/virtual/dmi/id/product_name 2>/dev/null)
		rev=$(cat /sys/devices/virtual/dmi/id/product_version 2>/dev/null)
	else
		model=$(uname -n)
	fi
	case "$rev" in ''|'Not Specified'|'To be filled by O.E.M.') rev= ;; esac
	if [ -n "$rev" ]; then printf '%s (%s)' "$model" "$rev"
	else printf '%s' "$model"; fi
}

get_kernel() { printf '%s %s' "$(uname -s)" "$(uname -r)"; }

get_uptime() {
	up=$(awk '{print int($1)}' /proc/uptime)
	d=$((up/86400)); h=$(((up%86400)/3600)); m=$(((up%3600)/60))
	out=
	[ $d -gt 0 ] && { s=; [ $d -ne 1 ] && s=s; out="$d day$s"; }
	[ $h -gt 0 ] && { s=; [ $h -ne 1 ] && s=s; out="${out:+$out, }$h hour$s"; }
	[ $m -gt 0 ] && { s=; [ $m -ne 1 ] && s=s; out="${out:+$out, }$m min$s"; }
	printf '%s' "${out:-less than a minute}"
}

get_packages() {
	if command -v apk >/dev/null 2>&1; then
		printf '%d (apk)' "$(apk list --installed 2>/dev/null | wc -l)"
	elif command -v opkg >/dev/null 2>&1; then
		printf '%d (opkg)' "$(opkg list-installed 2>/dev/null | wc -l)"
	elif command -v dpkg-query >/dev/null 2>&1; then
		printf '%d (dpkg)' "$(dpkg-query -f '.\n' -W 2>/dev/null | wc -l)"
	fi
}

get_shell() {
	sh=${SHELL##*/}
	case "$sh" in
		bash) printf 'bash %s' "$(bash -c 'echo "$BASH_VERSION"' 2>/dev/null | cut -d'(' -f1)" ;;
		*) printf '%s' "${sh:-unknown}" ;;
	esac
}

get_terminal() {
	t=$(tty 2>/dev/null)
	[ -n "$t" ] && [ "$t" != 'not a tty' ] && printf '%s' "$t" || printf '%s' "${TERM:-unknown}"
}

get_cpu() {
	model=$(awk -F: '/^model name/{sub(/^ +/,"",$2); print $2; exit}' /proc/cpuinfo)
	[ -z "$model" ] && model=$(awk -F: '/^(Hardware|Model|Processor)/{sub(/^ +/,"",$2); print $2; exit}' /proc/cpuinfo)
	[ -z "$model" ] && [ -r /sys/firmware/devicetree/base/model ] && model=$(tr -d '\0' < /sys/firmware/devicetree/base/model)
	[ -z "$model" ] && model=$(uname -p 2>/dev/null) && [ "$model" = unknown ] && model=$(uname -m)
	cores=$(grep -c '^processor' /proc/cpuinfo)
	if [ -r /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq ]; then
		freq=$(awk '{printf "%.2f", $1/1000000}' /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq)
	else
		freq=$(awk -F: '/cpu MHz/{printf "%.2f", $2/1000; exit}' /proc/cpuinfo)
	fi
	if [ -n "$freq" ]; then printf '%s (%d) @ %s GHz' "$model" "$cores" "$freq"
	else printf '%s (%d)' "$model" "$cores"; fi
}

get_memory() {
	awk -v cg="$C_GREEN" -v cy="$C_YELLOW" -v cr="$C_RED" -v ce="$C_RST" '
		/^MemTotal:/ {t=$2}
		/^MemAvailable:/ {a=$2}
		END {
			u=t-a; p=(u*100)/t
			if (t >= 1048576) th=sprintf("%.2f GiB", t/1048576); else th=sprintf("%.2f MiB", t/1024)
			if (u >= 1048576) uh=sprintf("%.2f GiB", u/1048576); else uh=sprintf("%.2f MiB", u/1024)
			c = (p > 80 ? cr : (p > 50 ? cy : cg))
			printf "%s / %s (%s%d%%%s)", uh, th, c, p, ce
		}' /proc/meminfo
}

get_swap() {
	total=$(awk '/^SwapTotal:/{print $2}' /proc/meminfo)
	if [ -z "$total" ] || [ "$total" -eq 0 ]; then
		printf 'Disabled'
		return
	fi
	free=$(awk '/^SwapFree:/{print $2}' /proc/meminfo)
	used=$((total-free))
	pct=$((used*100/total))
	printf '%s / %s (%s%d%%%s)' "$(human_kib "$used")" "$(human_kib "$total")" "$(pct_color "$pct")" "$pct" "$C_RST"
}

get_disks() {
	df -P -T 2>/dev/null | awk -v cg="$C_GREEN" -v cy="$C_YELLOW" -v cr="$C_RED" -v ce="$C_RST" '
		NR>1 && $2 !~ /^(tmpfs|devtmpfs|squashfs|overlay|proc|sysfs|cgroup|rootfs|none|efivarfs|debugfs|tracefs|fusectl|configfs|pstore|bpf|securityfs|hugetlbfs|mqueue|autofs|binfmt_misc)$/ && $7 ~ /^\// {
			u=$4; t=$3
			if (u >= 1048576) uh=sprintf("%.2f GiB", u/1048576); else uh=sprintf("%.2f MiB", u/1024)
			if (t >= 1048576) th=sprintf("%.2f GiB", t/1048576); else th=sprintf("%.2f MiB", t/1024)
			p=$6; gsub(/%/,"",p); p=p+0
			c = (p > 80 ? cr : (p > 50 ? cy : cg))
			printf "Disk (%s)\t%s / %s (%s%s%s) - %s\n", $7, uh, th, c, $6, ce, $2
		}'
}

get_local_ips() {
	command -v ip >/dev/null 2>&1 || return
	ip -o -4 addr show scope global 2>/dev/null | awk '{printf "Local IP (%s)\t%s\n", $2, $4}'
}

get_locale() { printf '%s' "${LANG:-${LC_ALL:-C}}"; }

build_info() {
	uh=$(get_user_host)
	user=${uh%@*}; host=${uh#*@}
	printf '%s%s%s@%s%s%s\n' "$C_BLUE" "$user" "$C_RST" "$C_BLUE" "$host" "$C_RST"
	printf '%s\n' "$uh" | sed 's/./-/g'
	printf '%sOS%s\t%s\n' "$C_BLUE" "$C_RST" "$(get_os)"
	printf '%sHost%s\t%s\n' "$C_BLUE" "$C_RST" "$(get_host)"
	printf '%sKernel%s\t%s\n' "$C_BLUE" "$C_RST" "$(get_kernel)"
	printf '%sUptime%s\t%s\n' "$C_BLUE" "$C_RST" "$(get_uptime)"
	p=$(get_packages); [ -n "$p" ] && printf '%sPackages%s\t%s\n' "$C_BLUE" "$C_RST" "$p"
	printf '%sShell%s\t%s\n' "$C_BLUE" "$C_RST" "$(get_shell)"
	printf '%sTerminal%s\t%s\n' "$C_BLUE" "$C_RST" "$(get_terminal)"
	printf '%sCPU%s\t%s\n' "$C_BLUE" "$C_RST" "$(get_cpu)"
	printf '%sMemory%s\t%s\n' "$C_BLUE" "$C_RST" "$(get_memory)"
	printf '%sSwap%s\t%s\n' "$C_BLUE" "$C_RST" "$(get_swap)"
	get_disks | awk -v c="$C_BLUE" -v e="$C_RST" -F'\t' '{printf "%s%s%s\t%s\n", c, $1, e, $2}'
	get_local_ips | awk -v c="$C_BLUE" -v e="$C_RST" -F'\t' '{printf "%s%s%s\t%s\n", c, $1, e, $2}'
	printf '%sLocale%s\t%s\n' "$C_BLUE" "$C_RST" "$(get_locale)"
}

fastfetch() {
	LOGO=$(logo)
	INFO=$(build_info)

	logo_w=$(printf '%s\n' "$LOGO" | awk '{ if (length>m) m=length } END{print m+0}')
	pad=4
	gap=$(printf '%*s' "$pad" '')

	n_logo=$(printf '%s\n' "$LOGO" | wc -l)
	n_info=$(printf '%s\n' "$INFO" | wc -l)
	n=$n_logo; [ "$n_info" -gt "$n" ] && n=$n_info

	i=1
	while [ "$i" -le "$n" ]; do
		l=$(printf '%s\n' "$LOGO" | sed -n "${i}p")
		r=$(printf '%s\n' "$INFO" | sed -n "${i}p")
		case "$r" in
			*"	"*)
				label=${r%%	*}
				value=${r#*	}
				r="${label}: ${value}"
				;;
		esac
		printf "%s%-${logo_w}s%s%s%s\n" "$C_BLUE" "$l" "$C_RST" "$gap" "$r"
		i=$((i+1))
	done
}

fastfetch "$@"

throw it into /etc/profile.d/ and/or create a Makefile which installs it into /usr/bin/.

Even if it's missing any non-x86_64 bits and grows to double the size, it's still peanuts compared to compiled binary.

@betonmischer86
Copy link
Copy Markdown

betonmischer86 commented May 26, 2026

@BKPepe I'd like to chime in as the author of the pervious fastfetch PR (#27949). I understand the reasoning behind keeping out the software that is impractical to waste the limited resources of a small home router on. But, looking at the broad range of capabilities that OpenWrt offers and the kind of packages already existing in the repo, I think that ship has sailed long ago. For many users, OpenWrt has become another lean server Linux, even if still specialized to a large extent. In that case, why not let in optional software which is found in other distros? As for the extra load on the build system, that is yet another consequence of the project outgrowing its original purpose. Along with the apparent lack of resources to deal with PRs and bug reports, sadly.

@BKPepe
Copy link
Copy Markdown
Member

BKPepe commented May 27, 2026

I think you missed the core point of my question: why is this package actually useful on a router?

If we look at how these tools are handled in other distributions, it tells a clear story:

  • Fastfetch / Neofetch: mostly unmaintained or outdated in the majority of distributions.
  • Afetch: available in very few distros

This clearly shows that the lack of maintainers isn't just an OpenWrt problem—it’s a widespread issue for these specific packages.

Regarding your point about PRs and issues: anyone has the opportunity to contribute to OpenWrt and help others, including by doing code reviews. It’s easy to point fingers and complain about the project's shortcomings just because you want to get a specific package merged. But we are all volunteers here. If you want to lend a hand and help us review or maintain things, we’d more than welcome it.

TL;DR: As we can see from the great example by @stangri, a simple shell script is a much better and more efficient solution for anyone who just wants a "super cool" gimmick in their CLI. It completely bypasses the need for constant maintenance, compilation, and wasting precious storage space on the router.

@betonmischer86
Copy link
Copy Markdown

I think you missed the core point of my question: why is this package actually useful on a router?

On a simple home router which is only configured via LuCi, not useful at all. On more of a regular server, which OpenWrt is capable of being, fastfetch-like tools can be genuinely helpful despite their reputation of being cosmetic. I visit my OpenWrt box over SSH quite often and it's nice to see stats like uptime and IP addresses on login. Sure, a script can do the same, but neofetch/fastfetch is also highly customizable and available on different platforms. I use it everywhere there is a shell available to get the same output presented in the same familiar way.

It’s easy to point fingers and complain about the project's shortcomings just because you want to get a specific package merged.

I'm sorry my words came across as finger-pointing. I only wanted to contrast the "basic router as the primary target platform" argument with the actual scale and scalability of OpenWrt, which is the reason behind the shortage of both maintainer time and build infrastructure resources.

@CarterLi
Copy link
Copy Markdown

Honestly, for the output it provides, this is a shell script Claude generated which does the same and takes ~6kb:

It's unfair bro... You used /bin/sh uname cat cut grep awk ip in your script. They all should be counted in the total size, otherwise your script won't work.

@GeorgeSapkin
Copy link
Copy Markdown
Member

GeorgeSapkin commented May 27, 2026

It's unfair bro... You used /bin/sh uname cat cut grep awk ip in your script. They all should be counted in the total size, otherwise your script won't work.

root@OpenWrt:~# ls -lh /usr/bin/awk /usr/bin/cut /bin/cat /bin/grep /bin/sh /bin/uname /sbin/ip
lrwxrwxrwx    1 root     root           7 May 25 10:41 /bin/cat -> busybox
lrwxrwxrwx    1 root     root           7 May 25 10:41 /bin/grep -> busybox
lrwxrwxrwx    1 root     root           7 May 25 10:41 /bin/sh -> busybox
lrwxrwxrwx    1 root     root           7 May 25 10:41 /bin/uname -> busybox
lrwxrwxrwx    1 root     root          14 May 25 10:41 /sbin/ip -> ../bin/busybox
lrwxrwxrwx    1 root     root          17 May 25 10:41 /usr/bin/awk -> ../../bin/busybox
lrwxrwxrwx    1 root     root          17 May 25 10:41 /usr/bin/cut -> ../../bin/busybox

@CarterLi
Copy link
Copy Markdown

  • Fastfetch / Neofetch: mostly unmaintained or outdated in the majority of distributions.
    This clearly shows that the lack of maintainers isn't just an OpenWrt problem—it’s a widespread issue for these specific packages.

You are ABSOLUTELY correct! I'm suggesting removing bash from openwrt's packages list as it has MUCH MORE red entries. It MUST cost MUCH trouble to MOST distros! (except rolling distros, I guess)

@CarterLi
Copy link
Copy Markdown

It's unfair bro... You used /bin/sh uname cat cut grep awk ip in your script. They all should be counted in the total size, otherwise your script won't work.

root@OpenWrt:~# ls -lh /usr/bin/awk /usr/bin/cut /bin/cat /bin/grep /bin/sh /bin/uname /sbin/ip
lrwxrwxrwx    1 root     root           7 May 25 10:41 /bin/cat -> busybox
lrwxrwxrwx    1 root     root           7 May 25 10:41 /bin/grep -> busybox
lrwxrwxrwx    1 root     root           7 May 25 10:41 /bin/sh -> busybox
lrwxrwxrwx    1 root     root           7 May 25 10:41 /bin/uname -> busybox
lrwxrwxrwx    1 root     root          14 May 25 10:41 /sbin/ip -> ../bin/busybox
lrwxrwxrwx    1 root     root          17 May 25 10:41 /usr/bin/awk -> ../../bin/busybox
lrwxrwxrwx    1 root     root          17 May 25 10:41 /usr/bin/cut -> ../../bin/busybox

So let's count busybox in?

@GeorgeSapkin
Copy link
Copy Markdown
Member

So let's count busybox in?

Brilliant! Let's replace Busybox - the default shell - with this:

root@OpenWrt:/tmp# ls -lh /usr/bin/fastfetch /bin/busybox 
-rwxr-xr-x    1 root     root      396.0K May 25 10:41 /bin/busybox
-rwxr-xr-x    1 root     root        1.2M May 26 18:34 /usr/bin/fastfetch

@CarterLi
Copy link
Copy Markdown

CarterLi commented May 27, 2026

Brilliant! Busybox must not have any dependency (except libc) like fastfetch

ldd $(which busybox)


Maybe it is time for fastfetch to lose weight by removing these hundreds of brilliant distro logos

@GeorgeSapkin
Copy link
Copy Markdown
Member

GeorgeSapkin commented May 27, 2026

Brilliant! Busybox must not have any dependency (except libc) like fastfetch

root@OpenWrt:/tmp# ldd `which busybox`
	/lib/ld-musl-x86_64.so.1 (0x7febbe5ee000)
	libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x7febbe5c8000)
	libc.so => /lib/ld-musl-x86_64.so.1 (0x7febbe5ee000)
root@OpenWrt:/tmp# ldd `which fastfetch`
	/lib/ld-musl-x86_64.so.1 (0x7f4832621000)
	libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x7f48325fb000)
	libc.so => /lib/ld-musl-x86_64.so.1 (0x7f4832621000)

@CarterLi

This comment was marked as low quality.

@efahl
Copy link
Copy Markdown
Contributor

efahl commented May 27, 2026

Although there's no way I'm installing a 1.3MB binary on even my x86 devices, I can indeed see the utility in this. I too ssh into a dozen+ machines every day, and on almost all of them I've got an Xfetch variant called in their .profile/.bashrc/.cshrc, just so I can get my bearings on login.

On my OpenWrt boxes, I usually just hack together something in /etc/profile.d/login.sh or something, so I typically see something like below. From now on though, I'm going to be using stanfetch.

$ ssh rtr01
BusyBox v1.37.0 (2026-05-15 18:58:27 UTC) built-in shell (ash)

  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 -----------------------------------------------------
 OpenWrt 25.12.4, r32933-4ccb782af7 Dave's Guitar
 -----------------------------------------------------

    _             _                  ____ _____       _  _
   / \   _ __ ___| |__   ___ _ __   / ___|___  |_   _| || |
  / _ \ | '__/ __| '_ \ / _ \ '__| | |      / /\ \ / / || |_
 / ___ \| | | (__| | | |  __/ |    | |___  / /  \ V /|__   _|
/_/   \_\_|  \___|_| |_|\___|_|     \____|/_/    \_/    |_|


 11:51:24 up 9 days,  2:54,  load average: 0.00, 0.01, 0.00
ASU server: https://sysupgrade.brain.lan

@AlbrechtL
Copy link
Copy Markdown
Contributor Author

Thanks everyone for the feedback and discussion.

I’d like to refocus on the main question: what are the actual requirements for getting a package like fastfetch into the official OpenWrt package repository?

fastfetch currently has more than 22k GitHub stars, which is a strong indication that there is real user interest in the project. While tools like this are obviously not essential on a router or Ethernet switch, OpenWrt has always also attracted enthusiasts and hackers who enjoy customizing and showcasing their systems. Tools such as fastfetch are commonly used in blogs, forums, screenshots, and YouTube videos, and they contribute to the broader community experience around Linux systems.

Regarding maintenance: based on the discussion so far, there are already at least two people willing to maintain an OpenWrt package for fastfetch. In addition, the upstream project itself is actively maintained. Because of that, I would be surprised if long-term maintenance availability is considered a blocker in this case.

Package size could be a more reasonable concern. However, I tested fastfetch successfully on a 16 MB flash / 128 MB RAM device without issues. Also, this would be an optional package — nobody is forced to install it. If footprint is the main concern preventing approval, we could also discuss optimizations such as removing unused distro logos or other nonessential assets to reduce the package size further.

I also understand the concern about increased build and CI time as more packages are added. That said, this is a general challenge that applies to all new packages, and I am not aware of this being used as a reason to reject otherwise maintained and functional additions in the past.

@CarterLi, thanks for joining the discussion as the fastfetch maintainer.

@GeorgeSapkin, @BKPepe, I also appreciate your perspective, especially given your experience working with OpenWrt packages on a regular basis.

@betonmischer86
Copy link
Copy Markdown

betonmischer86 commented May 29, 2026

@AlbrechtL In case the repo maintainers allow fastfetch in, I don't mind closing my original PR (#27949) in favor of yours and you becoming the package maintainer. Just a few suggestions about the makefile.

I'm pretty sure you don't need these.

PKG_BUILD_PARALLEL:=1
CMAKE_INSTALL:=1

My makefile included all of the build time dependencies available on OpenWrt.

PKG_BUILD_DEPENDS:=dbus drm elfutils glib-networking imagemagick pulseaudio sqlite3 zlib

Yours disabled some of them explicitly. I also included the shell completions in the install section, which are only a few dozen extra KB, because I didn't see a reason to try trimming the package that ends up "bloated" anyways. Maybe except for the OS logos as suggested before if that would lead to any meaningful savings.

@AlbrechtL
Copy link
Copy Markdown
Contributor Author

@betonmischer86 We can also do it the other way around ;-). You put more work in your PR than I did.

@CarterLi
Copy link
Copy Markdown

CarterLi commented May 30, 2026

@betonmischer86 @AlbrechtL CMake options -DMODULE_DISABLE_<MODULE_NAME>=ON are implemented in dev branch to disable module on compile time. Since a router likely have no WM/DE, displays or GPUs, these modules can be removed for smaller binary size.

You can use fastfetch -c all --show-errors to check what modules should be disabled (the red ones), and use cmake -L . to list all available options.

Note: these options rely on LTO for dead code elimination (-DCMAKE_BUILD_TYPE=Release should enable LTO)

Most ENABLE_<FEATURE> flags should be disabled too. For example, ENABLE_PULSE is used for sound device detection. If Sound module has been disabled via -DDISABLE_MODULE_SOUND=ON, importing pulseaudio is then meaningless. Please check https://github.com/fastfetch-cli/fastfetch/wiki/Dependencies#linux-and-freebsd for features should be disabled. -DENABLE_WCWIDTH=OFF

In addition, unneeded ASCII logos can now be removed without modifying fastfetch's code. Just run rm -rf src/ascii/[a-z] && git checkout src/logo/ascii/o/openwrt.txt to remove all of them except openwrt. Also implemented in dev branch.

Please test if these options work for you and how much binary size can be reduced. Thanks.


Other tips:

-DPACKAGES_DISABLED_* can be used to disable detection of unneeded package managers. Only opkg and apk should be left as enabled IMO. Note these option won't reduce binary size.

-DIS_MUSL=ON should be set for musl build

@AlbrechtL
Copy link
Copy Markdown
Contributor Author

@betonmischer86 Do you want to add @CarterLi recommendations in your PR #27949?

@AlbrechtL
Copy link
Copy Markdown
Contributor Author

@CarterLi I followed your recommendations and I have a local binary size of 588 kB on a mips32 CPU now (only on my local machine, I didn't update this PR).

root@OpenWrt:~# ls -l /usr/bin/
[...]
-rwxr-xr-x    1 root     root        588021 May 30  2026 fastfetch
[..]

root@OpenWrt:~# fastfetch 
 _______                        root@OpenWrt
|       |.-----.-----.-----.    ------------
|   -   ||  _  |  -__|     |    OS: OpenWrt SNAPSHOT mips
|_______||   __|_____|__|__|    Host: Zyxel GS1900-8 A1 Switch
         |__|                   Kernel: Linux 6.18.26
 ________        __             Uptime: 8 hours, 50 mins
|  |  |  |.----.|  |_           Shell: ash 1.37.0
|  |  |  ||   _||   _|          Terminal: dropbear
|________||__|  |____|          CPU: gs1900-8-a1 @ 0.50 GHz
                                Memory: 45.82 MiB / 116.73 MiB (39%)
                                Swap: Disabled
                                Disk (/): 784.00 KiB / 7.94 MiB (10%) - overlay
                                Disk (/overlay): 784.00 KiB / 7.94 MiB (10%) - jffs2
                                Locale: C

@BKPepe, @GeorgeSapkin Which binary size would acceptable for you?

@betonmischer86
Copy link
Copy Markdown

betonmischer86 commented Jun 1, 2026

@CarterLi Thank you for your directions and the effort to make fastfetch leaner. I revised the build dependencies and cmake options according to what is available on OpenWrt. Do you mind checking if any of the -DENABLE_*=OFF options are redundant now that the whole modules can be cut out?

-DPACKAGES_DISABLED_* can be used to disable detection of unneeded package managers. Only opkg and apk should be left as enabled IMO. Note these option won't reduce binary size.

Isn't it possible for the user to have Nix or Homebrew installed, though?

@AlbrechtL To keep the discussion in one place, I uploaded the updated Makefile as a gist for now rather than updating my PR. Also, numbered releases are prioritized over tags and git commits. We should probably wait until the next release of fastfetch is out.

https://gist.github.com/betonmischer86/0f3472f8df409e22a265a92fb286c16f

@betonmischer86
Copy link
Copy Markdown

@CarterLi I also find the current OpenWrt logo ugly and not matching the design on the official website and OpenWrt One boards. Is there any chance someone is willing to create a new one?

@efahl
Copy link
Copy Markdown
Contributor

efahl commented Jun 1, 2026

I also find the current OpenWrt logo ugly

Yeah, me, too. If you simply indent 3 spaces on the Wrt it looks a lot better and retains the narrow column use.

image

Comment thread utils/fastfetch/Makefile
Comment on lines +11 to +17
PKG_MAINTAINER:=Albrecht Lohofener <albrecht@albrechtloh.de>
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE
PKG_CPE_ID:=cpe:/a:fastfetch-cli:fastfetch
PKG_BUILD_PARALLEL:=1

CMAKE_INSTALL:=1
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
PKG_MAINTAINER:=Albrecht Lohofener <albrecht@albrechtloh.de>
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE
PKG_CPE_ID:=cpe:/a:fastfetch-cli:fastfetch
PKG_BUILD_PARALLEL:=1
CMAKE_INSTALL:=1
PKG_MAINTAINER:=Albrecht Lohofener <albrecht@albrechtloh.de>
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE
PKG_CPE_ID:=cpe:/a:fastfetch-cli:fastfetch
  • parallel build is enabled by default for cmake
  • there's nothing worthy to be installed to staging_dir

Comment thread utils/fastfetch/Makefile
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/fastfetch $(1)/usr/bin/
endef

$(eval $(call BuildPackage,fastfetch)) No newline at end of file
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing new line at the end of the file

@1715173329
Copy link
Copy Markdown
Member

People are always paying for those "beautiful" (but useless) things xD
so +1 from me.

@CarterLi
Copy link
Copy Markdown

CarterLi commented Jun 3, 2026

A new version has been cut.

https://gist.github.com/betonmischer86/0f3472f8df409e22a265a92fb286c16f

Some suggestions:

-DCMAKE_BUILD_TYPE=MinSizeRel # Build with -Os

PKG_BUILD_DEPENDS:=elfutils # Others are not useful for routers

-DMODULE_DISABLE_CODEC=ON \ # A new module introduced in the newest release; not useful for routers

	-DENABLE_LIBZFS=OFF \   
	-DENABLE_WCWIDTH=OFF # Other ENABLE_XYZ options will be disabled if cmake can't find their 3rd-party headers. Please check `cmake -L .` to ensure they are correctly disabled

@betonmischer86
Copy link
Copy Markdown

@CarterLi thank you. I updated the makefile draft. Not sure how the OpenWrt buildbots handle this, but, when building the whole OpenWrt image, fastfetch will still pick up the libraries already compiled for the target. So, I kept the -DENABLE_*=OFF lines to prevent that.

The binary is now 769K on aarch64. @AlbrechtL @GeorgeSapkin Let us know if the package now meets the criteria for inclusion and I'll update my old PR (#27949).

@betonmischer86
Copy link
Copy Markdown

BTW, an updated OpenWrt logo got merged.

@CarterLi
Copy link
Copy Markdown

CarterLi commented Jun 5, 2026

@betonmischer86 Unneeded packages managers should be disabled with -DPACKAGE_DISABLE_*=OFF -DPACKAGES_REMOVE_DISABLED=ON

You may use @GeorgeSapkin's brilliant awk command to disable everything except APK and OPKG, so that when fastfetch adds support for other package managers they will be automatically disabled for openwrt:

cmake . -L 2>/dev/null | awk -F'[:=]' '$1 ~ /^PACKAGES_DISABLE_/ && $1 !~ /_(APK|OPKG)$/ {printf "-D%s=OFF ", $1} END { print "" }'

Similar approach works for -DMODULE_DISABLE_* and -DENABLE_*

@AlbrechtL
Copy link
Copy Markdown
Contributor Author

I'm closing this PR to let PR #27949 go first. But I'm fine if we are sill using the place here for discussion.

@AlbrechtL AlbrechtL closed this Jun 5, 2026
@betonmischer86
Copy link
Copy Markdown

betonmischer86 commented Jun 6, 2026

You may use @GeorgeSapkin's brilliant awk command to disable everything except APK and OPKG, so that when fastfetch adds support for other package managers they will be automatically disabled for openwrt:

cmake . -L 2>/dev/null | awk -F'[:=]' '$1 ~ /^PACKAGES_DISABLE_/ && $1 !~ /_(APK|OPKG)$/ {printf "-D%s=OFF ", $1} END { print "" }'

@CarterLi I tried integrating this line into the package Makefile. For now, just to print out the package manager related cmake options.

define Build/Configure
	$(call Build/Configure/Default)
	cmake $(PKG_BUILD_DIR) -L 2>/dev/null | \
		awk -F'[:=]' '$$$$1 ~ /^PACKAGES_DISABLE_/ && \
		$$$$1 !~ /_(APK|OPKG)/ {printf "-D%s=ON ", $$$$1} END { print "" }'
endef

Problem is, the Build/Configure/Default script has to run first and call cmake. Then we can read the variables from cache to create a string of -DPACKAGE_DISABLE_*=ON options. Now, to use those options, we'd have to call Build/Configure/Default again, which doesn't seem efficient or elegant, unless I'm missing something.

@CarterLi
Copy link
Copy Markdown

CarterLi commented Jun 6, 2026

Yeah. You need cmake to parse CMakeList.txt.
Or, you can grab the package names from https://github.com/fastfetch-cli/fastfetch/blob/dev/src/modules/packages/option.h. However I can't guarantee the file won't be moved or its format won't be changed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants