Skip to content

Build panels

Build panels

A community panel is a folder of web files that Deska runs in a sandbox on your desk. What one is, how it reaches Deska, the rules it lives under, and where each part is documented.

What a panel is

A community panel is a small web page that lives on a Deska desk next to terminals, editors and tasks. You write it as a folder: a panel.json that says what the panel is and what it may do, an HTML page, and whatever scripts, styles, images and fonts that page loads. There is no build step, no server and no framework to adopt. Deska serves the folder to the panel itself.

Deska runs the page in a sandboxed frame with an origin of its own, so it cannot read your files, your other panels, your agents or your account. The page reaches Deska only through window.deska, the SDK Deska serves at /__deska/sdk.js inside every panel. Through it a panel keeps its own data, follows the theme, knows when it is on screen, and, when the person allows it, sends notices, opens links and copies text.

A panel shows up in two places:

  • On the desk, as a panel on the canvas, in a dock or in a window of its own. Every package has this.
  • In Extras, the popover on the canvas that holds Focus and Music, as a row with a state line and a round control. Optional; see Extras.
NoteCommunity panels run in the desktop app, from Deska 1.26.0. The phone app and app.deska.dev do not open them.

The smallest panel

Two files make a panel that loads, follows the theme and greets you by its name:

panel.jsonjson
{
  "schema": 1,
  "id": "hello-desk",
  "name": "Hello Desk",
  "version": "0.1.0",
  "description": "Says hello in Deska's colors.",
  "author": "Your name",
  "sdk": 1,
  "contributes": { "panel": { "entry": "index.html" } }
}
index.htmlhtml
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <script src="/__deska/sdk.js"></script>
  <style>
    body { margin: 0; padding: 16px; background: var(--deska-bg); color: var(--deska-text); font: 13px var(--deska-font-ui); }
  </style>
</head>
<body>
  <p id="hello">Waiting for Deska</p>
  <script type="module">
    const init = await deska.ready()
    document.getElementById('hello').textContent = `Hello from ${init.panel.name}`
  </script>
</body>
</html>

Put them in a folder, open the Panel Library (Cmd/CtrlShiftE), go to Community, then Build a panel, choose Load a folder and pick it. The panel lands on your desk and reloads each time you save. Build your first panel takes the same idea further in about fifteen minutes.

From a folder to people’s desks

  1. Build. Write the folder, preview it next to your editor with the examples repository’s preview tool, and load it in Deska with Load a folder. Deska checks it with the same rules it will meet when published. See Testing and debugging.
  2. Apply. Publishing is open to invited authors. Tell us what you are building at deska.dev/panels/apply.
  3. Publish. Once your account is approved, press Publish on the loaded folder’s page in Deska. deska.dev checks the package again and lists it. See Publishing.
  4. Install. People find it in Discover and on deska.dev/panels, read what it may do and which sites it reaches, and install it. Their installs follow their account to every computer they sign in to.
  5. Update. Raise version and publish again. Installs offer the update, and ask again first if the new version wants a permission or a site they had not allowed.

The rules in short

Each rule below has a reason and a way around it on The sandbox; the exact limits are on Error codes and limits.

RuleWhat to do instead
Only the sites in network, over httpsDeclare every host the panel fetches from or loads images, fonts and media from. The API must allow any origin (CORS).
No localStorage, indexedDB or cookiesKeep data in deska.storage: 256 KB per package, shared by every copy on the computer. Keep images and other files in deska.files: 32 MB a file, 256 MB per package.
No downloadsSave a file with deska.files.save: the person picks where.
No frames of its own, workers or remote scriptsShip your libraries inside the package. Play media from declared hosts with <audio> and <video>, or show another site’s page through Deska with deska.embed.
Forms never navigate, no popups or alert()Handle submit with preventDefault(), open links with deska.openUrl.
Focus moves only when the person actsCall openUrl, clipboard.write and files.save straight from a click; ask for attention with deska.notify.
No secretsThere is no safe place for a token. Use public APIs.
It can reload at any timeKeep what matters in storage and rebuild from what deska.ready() answers.

Where everything is

Start from an example

deska-panels-examples on GitHub holds fourteen MIT licensed panels, a starter folder and the preview tool. Read one, copy it, or load any folder under panels/ with Load a folder. Begin with Team Clocks, then keep SDK Playground open while you build: it runs every call and shows every error code. The full list, with screenshots, is on Example panels.

People who only want to install panels will find what they need on Community panels.