Material Bibata Cursor
August 30, 2026 · View on GitHub
Material Bibata Cursor
28 Bibata cursor themes, colored using Material Design 3's tonal system — a dark body paired with a vibrant accent outline, tuned independently per theme.
Pick whichever variant fits your setup, or add your own color — see Adding a color below.

Themes
Ice Blue, Sky Blue, Deep Blue, Soft Blue, Mint, Seafoam, Teal, Peach,
Apricot, Sunset, Blush, Salmon, Pink Pastel, Pink Rose, Lilac, Violet,
Sage, Lime, Moss, Sand, Beige, Brown, Cloud, Grey, Slate, Noir,
Midnight, Charcoal. Exact hex values are in themes.json.
There's also Classic — the original stock Bibata-Modern-Classic
colors (#000000 body, #ffffff outline), included as-is for anyone
who wants the vanilla look rather than an M3 variant. It's not one of
the 28 (it doesn't follow the Container/Primary design this project is
actually about), just a convenient extra in the same pack.
Each theme's actual range of cursor shapes:

Light versions
Every one of the 28 also has a -Light counterpart (e.g. Ice-Blue-Light)
— same hue, tone-swapped: a pale/light body instead of a dark one, and a
darker, saturated outline instead of a light one. This mirrors how
Material Design 3 actually defines light vs dark surfaces (it's not a
simple color inversion — light and dark mode swap which tone from the
same palette plays which role). All 28 light variants meet the same
≥4.5 contrast bar as the dark set.

Each light theme's range of cursor shapes:

Windows cursors
Windows .cur cursor files are generated separately using scripts/build_windows.py:
python3 scripts/build_windows.py # all themes
python3 scripts/build_windows.py --only-dark # dark themes only
python3 scripts/build_windows.py --only-light # light themes only
Each theme gets a folder under out_win/ containing .cur files at sizes 16, 24, 32, 48, 64, and 128px.
To install on Windows, copy each theme folder into %LOCALAPPDATA%\Icons\ (per-user) or C:\Windows\Cursors\ (all users, requires admin), then select the cursor in Settings → Personalization → Colors.
Package Windows cursors into a distributable .zip:
bash scripts/package_release.sh <version> --win
bash scripts/package_release.sh <version> --win --only-dark
bash scripts/package_release.sh <version> --win --only-light
Each archive contains an INSTALL.txt with Windows-specific instructions.
For finer control (e.g. skipping specific themes):
bash scripts/package_release.sh <version> --win --exclude Noir
Install
Needs fish, git, python3, jq, plus whatever bibata_cursor
itself needs to build (librsvg, xorg-xcursorgen — see
rtgiskard/bibata_cursor).
git clone https://github.com/SakibShahariar/material-bibata-cursor
cd material-bibata-cursor
fish scripts/compile_bibata_material.fish
That installs all 57 (28 dark, 28 light, plus Classic) to ~/.icons.
From there, pick one through GNOME Settings, GNOME Tweaks, or however
your desktop/WM selects a cursor theme — the exact menu depends on
your setup.
Don't want to run fish directly? There's a justfile:
just build # all 57 (28 dark, 28 light, Classic)
just build-dark # just the 28 dark themes + Classic
just build-light # just the 28 light themes
just build-one Coral # just one, faster for testing a color
just package <version> # bundle for a release, e.g. just package v1.0.0
just package-win <version> # Windows .cur .zip archives
just list
just show Ice-Blue
just check-deps
For finer control (e.g. skipping specific themes, or combining
--only-light/--only-dark with --exclude), call the fish script
directly: fish scripts/compile_bibata_material.fish --only-light --exclude Noir-Light,Charcoal-Light.
Adding a color
Add an entry to themes.json:
"Coral": {
"body": "#4e2418",
"primary": "#ff7f50",
"watch": "#2e130a"
}
Then fish scripts/compile_bibata_material.fish Coral (or
just build-one Coral) to build just that one instead of recompiling
everything.
A few guidelines for picking colors that hold up visually:
- Body: dark, desaturated, roughly 10-25% lightness. This is the neutral fill, not a darker copy of your accent.
- Primary: the vibrant one. This carries the actual color.
- Watch: near-black, just needs to sit behind the outline.
Preview it with gsettings set org.gnome.desktop.interface cursor-theme Bibata-Material-Coral, or hyprctl setcursor Bibata-Material-Coral 24
on Hyprland.
Why body and primary are separate colors
Most themed-cursor setups just take an accent color and darken it for the body. That works fine against some wallpapers and falls apart against others — low contrast, hard to spot the cursor at all.
This project picks body and primary independently instead, following Material Design 3's Container/Primary roles:
| M3 Role | Cursor part | What it does |
|---|---|---|
| Container | Body | Dark, desaturated fill. Stays legible regardless of how bright or saturated the accent is. |
| Primary | Outline | The actual accent color — vibrant, high-chroma. |
For Ice Blue:
Body (Container) : #1a333d
Primary (Outline) : #a8cbe2
Watch : #0a1f26
This keeps contrast consistent across all 28 themes, regardless of how saturated or pastel the accent color is.
Files
themes.json # all theme colors, edit this to add/change one
scripts/
├── compile_bibata_material.fish # builds themes.json -> ~/.icons
├── metadata_generator.py # writes index.theme so GNOME picks it up
└── package_release.sh # bundles compiled themes for release
Build flow: clone bibata_cursor, patch its render config with each
theme's colors, then compile and install to ~/.icons. index.theme
gets written right after each theme installs, so a broken metadata
file gets caught immediately instead of at the end of a 28-theme run.
Cursors are also compiled at more sizes than upstream's default (19 sizes instead of 11) — specifically every exact size a 24px cursor hits across Plasma/GNOME's fractional display scaling steps (0.5x through 3x). Without an exact match, some apps scale the nearest available bitmap instead, which can look blurry on fractional scaling. This roughly doubles build time (~30s vs ~17s per theme) but doesn't change anything about how you use the themes.
Packaging for redistribution
If you want to share compiled themes somewhere as a single download (a GitHub Release, GNOME-Look.org, wherever) instead of having people clone and build the repo themselves, package what you've built:
bash scripts/package_release.sh <version>
bash scripts/package_release.sh <version> --win # Windows .cur archives
Writes two separate archives (dark/light) by default:
dist/bibata-material-dark-<version>.tar.gz— the 28 dark themes + Classicdist/bibata-material-light-<version>.tar.gz— the 28-Lightthemes
With --win, outputs Windows .zip archives instead:
dist/bibata-material-dark-<version>-win.zip— dark themes as.curfilesdist/bibata-material-light-<version>-win.zip— light themes as.curfiles
Each archive contains its own plain-language INSTALL.txt. Use --only-dark, --only-light, or --exclude to filter themes. This step is entirely optional — it's only for packaging downloadable copies, not part of building or using the themes yourself.
To leave specific themes out (e.g. Classic, since it's not one of
the 28 M3 themes — this only affects the dark archive):
bash scripts/package_release.sh <version> --exclude Classic
Comma-separate multiple names to exclude more than one:
--exclude Classic,Noir.
Matugen Setup
To make these themes work with matugen put scripts/cursor_matugen.sh, scripts/themes.json and scripts/color_match.py in your ~/.config/matugen/post-hook-scripts/ folder. Then inside your ~/.config/matugen/config.toml file add
[templates.cursor]
input_path = "~/.config/matugen/templates/cursors.json"
output_path = "~/.config/colors.json"
post_hook = "~/.config/matugen/post-hook-scripts/cursor_matugen.sh"
then inside the ~/.config/matugen/templates/ folder create cursors.json with this
{
"colors": {
"color13": "{{colors.primary.default.hex}}"
}
}
Then running matugen command will do the job
License
Scripts and themes.json in this repo are MIT — see LICENSE.
The compiled cursor themes are a different story: they're derivative of Bibata_Cursor, which is GPLv3-or-later. If you redistribute compiled themes, that's under GPLv3, not this repo's MIT license. Not legal advice — check the GPLv3 text if you need to know exactly what that means for your situation.