Design guidelines
What makes a widget feel native to DeskDash: components first, tokens always, quiet motion, and restraint in density and decoration.
A widget feels native when a user cannot tell where DeskDash ends and your work begins: it follows their theme, it behaves like the widgets around it, and it stays quiet until looked at. Most of that comes from the platform for free, if you take what it offers. These are the habits that keep you on that path; each links to the guide that shows the how.
Components first
Build chrome from the dd-* components: the
panel, the text roles, the buttons, chips, and meters. They carry the house
look, react to themes, and auto-wire shared settings. Custom markup is for
what is genuinely yours (the visualization, the art, the layout); the
frame around it should be stock. And inside your own code, the second time
you build the same shape, unify it rather than copying it.
Tokens, always
Every color, size, font, radius and duration comes from a
--dd-* token. One literal hex value is all it
takes to break theming; a user who switches to a light theme, or lets the
automatic theme follow their wallpaper, will find your widget the one thing
on the desktop that did not come along. The single carve-out is symbol art
whose color is its identity (a cherry is red in every theme); keep that
palette private to the art and tokenize everything around it.
Structure in HTML
Someone opening your index.html should see what the widget is: its
regions, its parts, its shape. Keep the skeleton in markup, update values
in place, and build DOM in JavaScript only where structure genuinely
varies. It is a code-quality rule, but also a design one: widgets built
this way tend to have a clear, calm hierarchy, because the hierarchy had
to be written down.
Motion that stays out of the way
The desktop is a background, and nothing on it should move uninvited. DeskDash's own motion is opt-in and one-shot: entrance animations play once, controls transition their hover and press states subtly, and all of it respects the OS reduced-motion preference without you doing anything. Follow the same rules in your own motion: animate opacity and transform only, time it with the motion tokens, and reserve continuous animation for things that genuinely represent live data (a spectrum, a sweep second hand), never for decoration.
Respect the click-through desktop
At rest, the desktop is the user's. Capture input only where your widget is genuinely interactive, mark exactly what should feel solid, and let everything else pass through. A glanceable widget often needs no capture at all: ghost hover gives you presence (a highlight as the cursor passes) at zero cost to the desktop underneath. Widgets that grab more than they use are the fastest way to make a desktop feel broken.
Icons
Use the built-in glyphs for UI verbs (play, close, settings, refresh); they
tint with the text color and follow the theme. Ship your own SVG for
identity art, one file per icon, tinted when it should behave like text and
full-color when the color is the point. Stateful, animated, or multi-part
art is widget code, built with dd.ui.create and bound to your data, not a
pile of swapped image files.
Density and restraint
A widget is furniture, not an app. It should answer its one question at a glance and otherwise stay quiet:
- Prefer one clear readout over four small ones. If everything is emphasized, nothing is.
- Use the house empty state (
.dd-empty) and status line (.dd-status) instead of inventing chrome for "nothing here" and "last updated". - An idle state should look calm, not busy. Blank space on a desktop is a feature.
- Test the widget over a bright wallpaper, a dark one, and a photo. The surface tokens handle this; hardcoded backgrounds do not.
Settings that respect the theme
Every setting is a question the user has to answer, so add them deliberately. Use the shared presets (panel style and accent color) rather than inventing your own variants of the same ideas, and do not add settings for things the theme already decides; a widget with its own font picker or corner-radius slider is fighting the system it lives in. The best settings change what the widget shows, not how DeskDash looks.
Publishing to the marketplace
Get a publisher handle, upload the widget zip, build the listing with screenshots, and get through review and later updates.
Performance and quality
Polling intervals, animation discipline, effect hygiene, behavior at extreme sizes, and a self-check list before you publish.