Build panels
Example panels
Fourteen open source panels, MIT licensed, each written to teach one part of the SDK. What each one teaches, what it asks for, and how it looks in Deska.
The repository
deska-panels-examples holds the panels below, the starter/ folder from Build your first panel, and the preview and check tools. Each panel’s README walks through its code, explains every permission and host, and lists what it could not do.
git clone https://github.com/0xPasho/deska-panels-examples.git
cd deska-panels-examples
npm install
npm run preview -- panels/team-clocksTo try one in Deska, load its folder under panels/ with Load a folder, or install it from Discover. To build on one, copy its folder and change id, name and author in panel.json. The screenshots are Deska itself, with each panel installed from Discover.
Start here
Team Clocks
The place to start. Waits for deska.ready() and formats every time with init.locale, styles only with theme tokens, keeps its list in deska.storage, puts the first place’s time in setTitle, and stops its clock while visibility says hidden.
Permissions: none. Sites: none, it never goes online.
SDK Playground
Every call behind a small form, the line of code it ran, Deska’s answer, and what each error code means. Shows how to read refusals by err.code, keep layout across reloads, and answer an Extras control from every frame.
Permissions: notify, open-url, clipboard-write. Sites: none, it never goes online. Has a row in Extras.
Theme Inspector
Every theme token live, with its value and WCAG contrast in both modes, and a sample built only from tokens. Teaches deska.on('theme'), contrast from resolved colors, and the clipboard with each of its refusals.
Permissions: clipboard-write. Sites: none, it never goes online.
Reaching the network
Service Status
Fetches seven status pages with a timeout each, so one failing host marks only its own row. Polls every 2 minutes while seen and every 10 when hidden, notifies only on a real change (remembered in storage so a reload never repeats it), and sums it up in Extras.
Permissions: notify, open-url. Sites: status.claude.com, status.openai.com, www.githubstatus.com, status.cursor.com, www.vercel-status.com, www.cloudflarestatus.com, status.npmjs.org. Has a row in Extras.
HN Front Page
Network errors done right: timeouts, partial results and offline, each with a way to retry. Loads 30 stories six at a time into rows that fill as answers arrive, and opens links with deska.openUrl from the click, taking declined quietly.
Permissions: open-url. Sites: hacker-news.firebaseio.com.
Repo Pulse
Living inside GitHub’s anonymous limit of 60 requests an hour: ETags kept in storage, a budget spread over the hour, backoff that survives reloads, and avatars from a second declared host. Notifies once per new release. Uses no token, on purpose.
Permissions: notify, open-url. Sites: api.github.com, avatars.githubusercontent.com.
Weather Now
Units from init.locale, a search form under form-action 'none', debounced requests with AbortController, a forecast cached in storage for offline starts, and inline SVG icons in place of remote ones.
Permissions: open-url. Sites: api.open-meteo.com, geocoding-api.open-meteo.com.
On This Day
A panel in the person’s language: a small dictionary for its own words, a Wikipedia host per language (the policy takes exact hosts, never wildcards), lazy images from declared hosts, and attribution under each view.
Permissions: open-url. Sites: en.wikipedia.org, es.wikipedia.org, fr.wikipedia.org, de.wikipedia.org, pt.wikipedia.org, it.wikipedia.org, upload.wikimedia.org, thumb.wikimedia.org.
Storage and the clipboard
Prompt Shelf
clipboard.write from a click or Enter, with a message for each refusal. A versioned collection in one storage key that keeps the person’s edit when storage_full refuses it, and full keyboard handling inside the sandbox.
Permissions: clipboard-write. Sites: none, it never goes online.
Habit Streaks
Storage as a small database: one versioned document, migrations on load, compaction that keeps a year of history around 15 KB, a fallback when storage_full, and safe writes when several copies share the same keys.
Permissions: none. Sites: none, it never goes online.
Extras and media
Ship Countdown
The Extras row in depth: its own extras.html, an until that Deska keeps counting, the progress ring, stop and start controls, and two pages sharing one storage without overwriting each other.
Permissions: notify. Sites: none, it never goes online. Has a row in Extras.
Net Radio
Streams audio from declared hosts with <audio>, plays and pauses from the Extras row, switches to a compact layout when place is extras, and handles a play refused until the person presses something. One per project, with scope: global.
Permissions: open-url. Sites: api.somafm.com, ice1.somafm.com, ice2.somafm.com, ice3.somafm.com, ice4.somafm.com, ice5.somafm.com, ice6.somafm.com. Has a row in Extras.
Noise Machine
Sound with no network and no files, generated with Web Audio. A sleep timer through until, one speaker across many frames agreed through storage, and a level meter that stops drawing while hidden.
Permissions: none. Sites: none, it never goes online. Has a row in Extras.
Window View
Video from one declared host, paused while the panel is hidden or the person is away to save power, a scene that skips to the next when it will not load, and credits for every licensed clip.
Permissions: open-url. Sites: upload.wikimedia.org.
Contributing an example
Fixes and new examples are welcome on GitHub. A new example should teach something the others do not, pass npm run check, use only theme tokens for color, and look right in both themes. Open an issue first if you are not sure it fits.