A fork of Übersicht, rebuilt

Your desktop,
under version control.

Gailan runs widgets on your macOS desktop. They are TypeScript files in a folder: save one and it is on screen before you have switched windows.

macOS 13.5+GPL-3.0No account
01

A folder of files, on your wallpaper

There is no widget store and no editor to learn. Gailan watches a directory, compiles what it finds, and draws it behind your windows. Delete the file and the widget is gone.

01

Widgets are TypeScript

A widget is a module exporting a command, a refresh interval and a render. Types are stripped when it bundles, so annotate as much or as little as suits you.

02

esbuild, not Babel

Save a file and it rebuilds in single-digit milliseconds, then pushes over a socket. No dev server to start, no watcher to configure.

03

Glass drawn by macOS

A widget marks a rectangle and the system frosts your wallpaper behind it. Real Liquid Glass on macOS 26, a vibrancy material before that.

04

Shortcuts and AppleScript

Refresh a widget, reload one, hide it, choose its screens. From the Shortcuts app with a widget picker, from a script, or from Siri.

05

Locked to your machine

The server binds to localhost, checks the origin, and takes a per-launch token handed over on stdin. Nothing else on your network can reach it.

06

Übersicht widgets still run

The classic object-literal API is intact, and importing uebersicht still resolves. Rename the file to .js and it works.

02

Three exports and you are done

A command to run, how often to run it, and what to draw with the output. Everything else is optional.

widgets/clock/index.tsxtsx
import { styled } from "gailan"

export const command = "date '+%H:%M'"
export const refreshFrequency = 10000

const Time = styled("div")`
  font-variant-numeric: tabular-nums;
`

// the desktop is frosted behind this one
export const render = ({ output }) => (
  <Time data-gailan-desktop-glass={12}>
    {output.trim()}
  </Time>
)

What you get for free

Emotion's css and styled are exported from the gailan module, and generated class names carry the component they came from, so the inspector reads css-1a2b3c-Time rather than a hash on its own.

Widgets see the system appearance through prefers-color-scheme and an attribute on the document, so light and dark are a media query rather than a setting to read.

When a widget fails, the error appears where the widget was, with the line from your source and the column marked. The stack is mapped back through the bundle, so it points at the file you wrote.

03

Glass the system draws

A page cannot see what is behind its own window, which is why CSS has never been able to frost a wallpaper. So the widget marks a rectangle and the app asks macOS to put its material there.

One attribute

Add data-gailan-desktop-glass to an element with the radius you want. Give it an id and the same pane of glass follows it as the widget re-renders.

On macOS 26 this is Liquid Glass, with a style and a tint in Preferences. Before that it is the closest vibrancy material. Keep your own background thin or it covers the glass it asked for.

Frost
On by default
Style
Regular / Clear
Tint
Any colour, or none
Drawn by
NSGlassEffectView
04

Specifications

Requires
macOS 13.5 or later, Apple silicon or Intel
Widget languages
.tsx .jsx .ts .js
Bundler
esbuild 0.25, shipped inside the app
Runtime
Node 24 LTS, bundled; nothing to install
Styling
Emotion 11, css and styled
Automation
App Intents and AppleScript
Updates
Sparkle, signed with EdDSA
Licence
GPL-3.0-or-later
05

Widgets, by pull request

GailanHub is one repository of widgets. Every one is a folder with a manifest, a readme saying what it runs, and a screenshot. Adding yours means opening a pull request; CI compiles it before anyone looks.