Skip to content

Instantly share code, notes, and snippets.

@jimmckeeth
Created March 15, 2026 22:26
Show Gist options
  • Select an option

  • Save jimmckeeth/6314cf5c50e225b8954641f8b9df379e to your computer and use it in GitHub Desktop.

Select an option

Save jimmckeeth/6314cf5c50e225b8954641f8b9df379e to your computer and use it in GitHub Desktop.
Hides all non-whitelisted Noto fonts on Ubuntu Linux

clean_noto.sh

The Ubuntu family Noto font cleaner

The Problem

Ubuntu-based Linux distros treat all of the Noto fonts as dependencies. This is good because it provides an exhaustive international langauge support, but it means there is a huge list of fonts that may not be relivant to your selected language. I'd tried uninstalling them, which was a lot of trouble to uninstall the right ones, and then they came back with a future update.

The Solution

This script uses a customizable whitelist of fonts to keep, creating a user fontconfig file 99-hide-noto.conf that uses rejectfont to reject the other fonts. This should be consistent between updates, and leaves the font files installed for maximum compatibility.

Usage

Edit the clean_noto.sh and then run it. If you change your mind or want to tweak the results, just edit or delete ~/.config/fontconfig/conf.d/99-hide-noto.conf

It automatically refreshses your font cache with the command fc-cache -f after the file is generated.

To see the list of Noto fonts installed you can use the following:

fc-list : family | grep -i "Noto" 

Note that fc-list respects your fontconfig files, so check ~/.config/fontconfig/conf.d/ for any other font config files.

Example 99-hide-noto.conf

<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
  <selectfont>
    <rejectfont>
      <pattern><patelt name="family"><string>Noto Kufi Arabic</string></patelt></pattern>
      <pattern><patelt name="family"><string>Noto Looped Lao</string></patelt></pattern>
      <pattern><patelt name="family"><string>Noto Looped Thai</string></patelt></pattern>
      <!-- ... -->
      <pattern><patelt name="family"><string>Noto Serif Tibetan</string></patelt></pattern>
      <pattern><patelt name="family"><string>Noto Serif Yezidi</string></patelt></pattern>
      <pattern><patelt name="family"><string>Noto Traditional Nushu</string></patelt></pattern>
    </rejectfont>
  </selectfont>
</fontconfig>
#!/bin/bash
echo "================="
echo "Noto Font Cleaner"
echo "================="
echo "Hides all Noto fonts except the white listed ones. Edit script to customize."
echo
# --- CONFIGURATION: Add fonts you want to KEEP here ---
# Use the exact family name as seen in fc-list : family | grep -i "Noto"
# The link comment is just for reference.
WHITELIST=(
"Noto Color Emoji" # https://fonts.google.com/noto/specimen/Noto+Color+Emoji
"Noto Emoji" # https://fonts.google.com/noto/specimen/Noto+Emoji
"Noto Music" # https://fonts.google.com/noto/specimen/Noto+Music
"Noto Sans Display" # https://fonts.google.com/noto/specimen/Noto+Sans+Display
"Noto Sans Deseret" # https://fonts.google.com/noto/specimen/Noto+Sans+Deseret
"Noto Sans Gothic" # https://fonts.google.com/noto/specimen/Noto+Sans+Gothic
"Noto Sans Math" # https://fonts.google.com/noto/specimen/Noto+Sans+Math
"Noto Sans Mono" # https://fonts.google.com/noto/specimen/Noto+Sans+Mono
"Noto Sans Symbols 2" # https://fonts.google.com/noto/specimen/Noto+Sans+Symbols+2
"Noto Sans Symbols" # https://fonts.google.com/noto/specimen/Noto+Sans+Symbols
"Noto Sans" # https://fonts.google.com/noto/specimen/Noto+Sans
"Noto Serif Display" # https://fonts.google.com/noto/specimen/Noto+Serif+Display
"Noto Serif" # https://fonts.google.com/noto/specimen/Noto+Serif
)
CONF_FILE="$HOME/.config/fontconfig/conf.d/99-hide-noto.conf"
mkdir -p "$(dirname "$CONF_FILE")"
echo "Regenerating $CONF_FILE"
# Remove old config file first
[ -f "$CONF_FILE" ] && rm "$CONF_FILE"
# Collect all installed Noto font families
mapfile -t NOTO_FONTS < <(fc-list : family | grep -i "Noto" | cut -d',' -f1 | sort -u)
NOTO_COUNT=${#NOTO_FONTS[@]}
MATCH_LIST=()
MISSING_LIST=()
HIDE_LIST=()
for font in "${NOTO_FONTS[@]}"; do
keep=false
for allowed in "${WHITELIST[@]}"; do
if [[ "$font" == "$allowed" ]]; then
keep=true
break/.config/fontconfig/conf.d/99-hide-noto.conf
fi
done
if [ "$keep" = true ]; then
MATCH_LIST+=("$font")
else
HIDE_LIST+=("$font")
fi
done
for allowed in "${WHITELIST[@]}"; do
found=false
for font in "${NOTO_FONTS[@]}"; do
if [[ "$font" == "$allowed" ]]; then
found=true
break
fi
done
[ "$found" = false ] && MISSING_LIST+=("$allowed")
done
MATCH_COUNT=${#MATCH_LIST[@]}
MISSING_COUNT=${#MISSING_LIST[@]}
HIDE_COUNT=${#HIDE_LIST[@]}
echo "Total Noto fonts installed: $NOTO_COUNT"
echo "Matching whitelist (kept): $MATCH_COUNT"
for f in "${MATCH_LIST[@]}"; do echo " + $f"; done
echo "Whitelisted but not installed: $MISSING_COUNT"
for f in "${MISSING_LIST[@]}"; do echo " ? $f"; done
echo "Total to hide: $HIDE_COUNT"
echo
TMP_FILE="$CONF_FILE.tmp"
# Start the XML file
echo '<?xml version="1.0"?>' > "$TMP_FILE"
echo '<!DOCTYPE fontconfig SYSTEM "fonts.dtd">' >> "$TMP_FILE"
echo '<fontconfig>' >> "$TMP_FILE"
echo ' <selectfont>' >> "$TMP_FILE"
echo ' <rejectfont>' >> "$TMP_FILE"
for font in "${HIDE_LIST[@]}"; do
echo " <pattern><patelt name=\"family\"><string>$font</string></patelt></pattern>" >> "$TMP_FILE"
done
# Close the XML tags
echo ' </rejectfont>' >> "$TMP_FILE"
echo ' </selectfont>' >> "$TMP_FILE"
echo '</fontconfig>' >> "$TMP_FILE"
echo '' >> "$TMP_FILE"
sed -i '$ d' "$TMP_FILE" # Remove accidental extra lines if any
mv "$TMP_FILE" "$CONF_FILE"
# Refresh caches
echo "Regenerating font cache..."
fc-cache -f
echo "Done! The non-whitelist Noto fonts were HIDDEN."
echo "To revert, remove: $CONF_FILE"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment