The icon
The icon is Jordy's to make; the creator avatar is yours.
A droplet in the Store carries two pieces of artwork: its icon and its creator avatar. You make the avatar. You do not make the icon.
The droplet icon
Jordy designs every Store droplet's icon himself, in Icon Composer and in Droppy's current icon style. Droppy draws a droplet's icon at seven sizes, on light and dark chrome, behind glass, and in every icon appearance macOS offers: default, dark, clear and tinted. Icons made together, by one hand, adapt properly in all of them and make the Store read as one set rather than a collection of styles.
So the icon is not part of your work:
droppykit newwrites a placeholder Icon Composer document,<Name>.icon, so the harness and Droppy Playground have something to draw. Leave it as it is.droppykit submitleaves the icon document out of the merge request, and the Store's pipeline refuses a merge request that adds or changes one.- Have an idea for it? The merge request has an Icon concept section: a sentence about what it could show, a reference sketch, or an SF Symbol to start from. It is optional, and Jordy reads it.
- Jordy adds the icon to your droplet's folder before it publishes; the publish job refuses a droplet without it. An update keeps the icon the Store already has.
droplet.json still names the document ("icon": "WorldClock.icon"). That is the file name the icon is saved under, so leave it as droppykit new wrote it. The images inside your droplet's own interface, its glyphs and its settings tiles, are yours to make; this is only about the droplet's icon.
The rest of this section is how the icon works, for reading rather than doing.
A .icon is a directory:
WorldClock.icon/
icon.json the document: groups, layers, fills, specializations
Assets/
dial.png every image icon.json names by `image-name`Droppy requires that the document is well formed and self-contained.
What is checked. When an icon document is in your package, droppykit validate checks it the way Droppy will: a .icon directory with a readable icon.json, at least one layer, and every image it names in Assets/. The placeholder passes. When there is none, validate says so and passes too: a submission needs no icon.
What Droppy draws. droppykit build compiles the document with actool, the same compiler Xcode runs on an app's icon, and puts the result in the bundle beside it. That compiled icon is the real macOS one, with the squircle, the material, the specular edge and the shadow, and it is what the Store and the widget picker draw. The harness and older Droppy versions render the document themselves, which is a flat preview of the layers. While you build, that preview shows the placeholder; the published droplet carries Jordy's icon.
Icon and widget style
macOS 26 lets a user draw every app icon Default, Clear or Tinted, each light or dark, in a tint of their choosing (System Settings ▸ Appearance ▸ Icon & widget style), and the Dock follows it live. A Droppy that embeds DroppyKit 1.21.0 draws droplet icons the same way: the system's own icon renderer composites your compiled icon in the user's style, with the real Liquid Glass, and redraws it the moment the setting changes. Your icon needs no change and there is nothing to opt into; it reads the Assets.car droppykit build has written into every bundle since 1.6.2. A bundle built before that carries only the document and stays Default in every style: rebuild it.
What you do control is how your icon looks in the five styles that are not Default. Icon Composer gives every fill a dark and a tinted specialization, and tinted drives both Clear and Tinted:
- Give each layer a
tintedfill, plain white at a chosen strength, so the mono styles have a designed light-to-dim hierarchy instead of whatever the system derives from your colours. - Give the background or the hero a
darkfill where Default would vanish on a dark tile. - Preview all six in Icon Composer before you submit. After
droppykit build, the harness's Overview page draws the built bundle's icon in all six through the same renderer Droppy uses, and Droppy Playground does the same for every droplet you drop in.
A droplet's own views can follow the same choice:
struct MyWidget: View {
@Environment(\.droppyIconStyle) private var pinned
var body: some View {
let style = pinned ?? DroppyIconStyleObserver.shared.style
// style.variant is .default, .clear or .tinted;
// style.appearance is .light or .dark; style.tint is the colour.
...
}
}DroppySystemIconRenderer draws any bundle's icon in any style, and icon(inBundleAt:style:pixelSize:) draws an installed droplet's. Reading the style needs minAPI 1.21.0. On macOS 14 and 15 it is always Default, light or dark with the interface.
The creator avatar
The small round mark beside your droplet's name in the Store and on getdroppy.app/droplets. It says who made the thing at a glance, and it is what separates the Store's Community shelf from its By Droppy shelf visually rather than only by label.
- A square PNG, at least 256×256.
- No rounding of your own. Every surface clips it to a circle; a pre-rounded image is clipped twice and the two radii disagree by a pixel or two all the way around, which reads as a muddy edge rather than a circle.
- It has to read at 20pt. A wordmark will not. A monogram, a face, or a single symbol will.
- It is yours. The blue disc
droppykit newwrites is a placeholder, and the Store's checks refuse it byte for byte.
Transparency is fine. Name it in creator.avatar and place it in Assets/.
"creator": {
"name": "Jane Doe",
"kind": "community",
"url": "https://jane.example",
"avatar": "Creator.png"
}Screenshots are not asked for
The one image you have to make is the creator avatar; the icon is Jordy's. Nothing in the SDK, droppykit validate, the Store repository or review asks for a screenshot, and a droplet that ships none looks complete everywhere: the Store shows its icon, its summary and its real widget, and the page simply has no screenshot strip.
The screenshots key exists for a droplet whose author wants one, and it stays optional. If you use it, name PNGs that sit in Assets/; if you do not, leave the key out entirely.