Contains a JSON schema that describes a cursor theme, its variants, cursors, sprites, animations and more, and GitHub Actions to validate, export a JSON following this schema from a Figma file, and a builder that takes a JSON and SVG assets and builds a cursor theme from it.
The schema can be used to create a valid cursor theme JSON file. Modern editors can use it to provide autocompletion and validation. All that is needed is to reference the schema in the JSON file like this:
{
"$schema": "https://phisch.github.io/cursor-theme-builder/schemas/CursorTheme.json",
"name": "My Cursor Theme",
"variants": [ ... ]
}Each cursor theme definition can contain multiple root and child variants. A variant is built into a functioning base cursor theme. A child variant defines its parent variant as the inheritance source. This way, a child variant can override the parent variant's properties.
This would allow to create a base cursor theme, that has a variant, which adds animations on top.
Each sprite allows you to define "flips". A flip is a css selector that selects elements from the sprites SVG and flips all of them horizontally.
Each selected element is flipped around its bounding box's center, except for the special svg selector, which flips the whole SVG around its center.
This project uses SVG.js to animate cursor sprites. The JSON schema provides a shallow abstraction that allows to select elements from the SVG and call SVG.js functions on them.
Warning
The TypeScript types for SVG.js are not perfect, and have proven to be a bit buggy. I don't intend in fixing this, which means that the animations are a bit limited, or some instructions might not work as expected.
There is also a sub-schema for animations, which is available at https://phisch.github.io/cursor-theme-builder/schemas/Animations.json.
You can use the web interface to create animations. It supports auto-completion and validation, and updates the animated cursor in real-time. Drag and drop a SVG file on top of the animated cursor to replace the loaded one.
Every variant is built into both two cursor formats:
cursors/: XCursor files, rendered at 1x, 2x, 3x and 4x of each sprite's size. Used by X11 and most Wayland clients.cursors_scalable/: SVG cursors as introduced by KDE Plasma 6.2 and GNOME 51. Each cursor gets a directory with its SVG frames and ametadata.jsonwith hotspot and size. The largest sprite of a cursor is used as the scalable cursor.
Aliases are a way to define multiple names for a cursor. Due to cursor themes history, many applications expect a cursor to have a specific name. Aliases allow you to define multiple names for a cursor, so it can be used in more applications.
Thre are 3 GitHub Actions in this repository, each of them has its own documentation: