Expand the theme editor with multi-select, snapping, context menus, draft recovery and export validation; add theme backups and trust prompts. Add in-app diagnostics and rotating log bundle viewing, hardware-accelerated theme video playback on macOS, and refresh the settings, setup wizard and theme gallery layouts.
14 KiB
EZPPLauncher Theme API 2.0
API 2.0 is a declarative theme format. Instead of shipping a JavaScript bundle that
mounts its own UI, a theme describes its background, effects, audio, fonts and
freeform layers in theme.json. The launcher renders it, and the built-in advanced
editor can create and edit these themes without writing code.
API 1.0 themes continue to work unchanged. Pick the API that fits the theme:
| API 1.0 | API 2.0 | |
|---|---|---|
| Rendering | Svelte bundle (entry) |
Launcher-rendered |
| Files | theme.json, bundle.js, style.css, assets/ |
theme.json, assets/ |
| Created with | create-ezpplauncher-theme |
Launcher editor or create-ezpplauncher-theme |
| Scripts / arbitrary DOM | Yes | No (data only, optional CSS) |
| Cross-platform | Depends on the bundle | Yes |
Package layout
A packaged .ezpplauncher-theme file is a zip with this structure:
theme.json
assets/
background.webm
layer.png
music.mp3
font.woff2
preview.png # optional thumbnail
An installed theme lives in:
# Windows
C:\Users\<user>\.ezpplauncher\themes\<folder>\
# macOS / Linux
~/.ezpplauncher/themes/<folder>/
theme.json
{
"name": "Midnight",
"version": "1.0.0",
"apiVersion": "2.0",
"author": "Your Name",
"description": "A dark gradient with drifting stars.",
"preview": "preview.png",
"background": {
"type": "gradient",
"from": "#181825",
"to": "#3b1d4f",
"angle": 135,
"opacity": 1
},
"overlay": {
"color": "#000000",
"opacity": 0.2,
"vignette": 0.35
},
"effects": {
"type": "stars",
"density": 40,
"speed": 1,
"color": "#ffd6f2"
},
"typography": {
"body": "Sora Variable",
"heading": "Bebas Neue"
},
"fonts": [
{
"family": "My Display Font",
"src": "display.woff2",
"weight": "400",
"style": "normal"
}
],
"elements": [
{
"id": "tagline",
"type": "text",
"text": "MIDNIGHT",
"x": 640,
"y": 84,
"width": 300,
"height": 72,
"fontFamily": "Bebas Neue",
"fontSize": 46,
"fontWeight": 400,
"color": "#ffffff",
"align": "right",
"verticalAlign": "center",
"letterSpacing": 2
}
],
"audio": {
"src": "music.mp3",
"loop": true
},
"accentColor": "#ff006e",
"css": ""
}
Metadata
| Field | Type | Required | Notes |
|---|---|---|---|
name |
string | yes | Display name; also used for the install folder |
version |
string | yes | Semver, used for update checks |
apiVersion |
string | yes | Must start with 2 (use "2.0") |
author |
string | yes | Shown in the theme manager |
description |
string | no | Shown on the theme card |
nsfw |
bool | no | Marks the theme as adult content (18+ badge) |
preview |
string | no | Card thumbnail; the editor generates preview.png |
accentColor |
string | no | Hex color used for focus rings and active UI states |
css |
string | no | Extra CSS injected while the theme is active |
Background
background.type selects the layer:
{ "type": "color", "color": "#181825", "opacity": 1 }
{ "type": "gradient", "from": "#181825", "to": "#3b1d4f", "angle": 135, "opacity": 1 }
{ "type": "image", "src": "background.png", "fit": "cover", "opacity": 1, "blur": 0 }
{
"type": "video",
"src": "background.webm",
"fit": "cover",
"opacity": 1,
"blur": 0,
"muted": true
}
srcis relative to the theme'sassets/folder.fitiscover(default) orcontain.opacityis clamped to0–1,blurto0–40pixels.- Background videos autoplay and loop. They are muted by default; set
mutedtofalseto play their audio. - Prefer WebM for video backgrounds and video layers. It is supported by the launcher and keeps theme packages much smaller than MP4. MP4, MOV and M4V also work.
Overlay
{ "color": "#000000", "opacity": 0.2, "vignette": 0.35 }
opacity controls the flat dim layer and vignette darkens the edges. Both are
clamped to 0–1.
Effects
{ "type": "stars", "density": 40, "speed": 1, "color": "#ffd6f2" }
Supported types: none, stars, snow, petals, bubbles.
densityis clamped to0–120particles.speedis clamped to0.2–3.- Effects are disabled when the user turns on Reduce animations.
Audio
{ "src": "music.mp3", "loop": true }
src is relative to assets/. Music uses the launcher's volume control and is
silent in the theme editor preview.
Typography
typography.body changes the font used by the launcher UI. typography.heading
changes headings such as the launcher title.
"typography": {
"body": "Montserrat Variable",
"heading": "Playfair Display Variable"
}
These families ship with the launcher through @fontsource and can be used
without adding any files:
| Family | Style |
|---|---|
Sora Variable |
Sans |
Montserrat Variable |
Sans |
Bebas Neue |
Display |
Playfair Display Variable |
Serif |
Space Mono |
Mono |
JetBrains Mono Variable |
Mono |
Custom fonts can be packaged with the theme. The launcher generates the
@font-face rules from fonts:
"fonts": [
{ "family": "My Display Font", "src": "display.woff2", "weight": "400", "style": "normal" }
]
srcis relative toassets/.- Supported formats: WOFF2 (recommended), WOFF, TTF and OTF.
weightdefaults to400;styledefaults tonormal.- Use the
familyvalue intypographyand in text layers.
The editor's Fonts tab browses the full Fontsource catalog (2,000+ families)
and downloads the selected family, weight, style and subset as a WOFF2 into the
theme's assets/ folder. It adds the matching fonts entry automatically, so
saved and exported themes stay self-contained.
Freeform layers
elements are rendered above the launcher UI, but only on the Home screen.
The launcher canvas is a fixed 1000 × 650 coordinate space. Elements can extend
the home screen with text, images, videos and shapes, and they are
pointer-transparent in the running launcher so they never block buttons.
The order of the elements array controls stacking: the last element is drawn on
top. Themes can contain up to 100 layers.
Every layer supports:
| Field | Type | Notes |
|---|---|---|
id |
string | Unique within the theme |
name |
string? | Optional editor label; does not affect rendering |
type |
string | text, image, video or shape |
x, y |
number | Position in the 1000 × 650 stage |
width |
number | 24–1000 |
height |
number | 24–650 |
rotation |
number | Degrees, -360–360 |
opacity |
number | 0–1 |
hidden |
boolean | Keep the layer in the file but do not render it |
locked |
boolean | Prevent moving/resizing the layer in the editor |
Text
{
"id": "greeting",
"type": "text",
"text": "Welcome back!",
"x": 360,
"y": 220,
"width": 420,
"height": 90,
"fontFamily": "Bebas Neue",
"fontSize": 42,
"fontWeight": 600,
"color": "#ffffff",
"align": "center",
"verticalAlign": "center",
"lineHeight": 1.2,
"letterSpacing": 0
}
align is left, center or right; verticalAlign is top, center or
bottom. Font size is clamped to 6–240.
Image and video
{
"id": "logo",
"type": "image",
"src": "logo.png",
"x": 700,
"y": 420,
"width": 220,
"height": 140,
"fit": "contain",
"radius": 18,
"opacity": 1
}
{
"id": "ambient",
"type": "video",
"src": "ambient.webm",
"x": 0,
"y": 0,
"width": 1000,
"height": 650,
"fit": "cover",
"opacity": 0.35
}
Video layers autoplay and loop. They are muted by default; set muted to false to
play their audio. WebM is recommended for size. Use an opacity below 1 if the video
should blend into the launcher UI.
Shape
{
"id": "glow",
"type": "shape",
"shape": "ellipse",
"x": 680,
"y": 60,
"width": 260,
"height": 260,
"fill": "#ff006e",
"opacity": 0.18,
"borderWidth": 0,
"borderColor": "#ffffff"
}
shape is rectangle, ellipse or line. radius rounds rectangle corners.
borderWidth is clamped to 0–40.
Custom CSS
The css field is appended while the theme is active. Theme authors can use it for
small tweaks, but it is not required. Example:
:root {
--radius: 1rem;
}
Using the advanced editor
- Open Themes in the launcher.
- Select Create theme, or the pencil button on an installed API 2.0 theme.
- The editor opens in its own resizable window, not a modal. The center is a full launcher home canvas at 1000 × 650.
- Use the left toolbar to add text, image, video and shape layers. Drag layers on the canvas, resize with the corner handles, or edit exact values in the right inspector. Shift/Cmd-click a layer or drag a marquee over empty canvas to select several layers. Multi-selections can be dragged together and aligned or distributed from the right panel. Layers snap to canvas edges, the canvas center, and other layers while dragging; hold Alt to disable snapping. Right-click a layer for quick duplicate, ordering, hide/lock and delete actions, or right-click empty canvas to add a new layer.
- The layer list supports double-click rename, hide/show, lock/unlock and drag-to-reorder. Hidden layers remain in the package, while locked layers cannot be moved or resized on the canvas.
- Use the Theme tab for metadata, background, effects, typography and custom
CSS. Open the Fonts tab to search and download from every Fontsource
family, or import WOFF2, WOFF, TTF and OTF files. Downloaded fonts are copied
into the theme's
assets/folder when you save. - Select Save theme to write
theme.jsonand copy new assets into~/.ezpplauncher/themes. A freshassets/preview.pngthumbnail is rendered from the theme and the launcher applies the saved theme immediately. Unsaved edits are autosaved as a local draft and offered for recovery after a crash. - Select Export to create a shareable
.ezpplauncher-themepackage. A theme check runs first and reports missing assets, oversized media, missing fonts and unused imports. Export saves and refreshes the preview, then reports the final package size.
Keyboard shortcuts:
Cmd/Ctrl+Zundoes the last change.Cmd/Ctrl+Shift+ZorCtrl+Yredoes it.Cmd/Ctrl+Ssaves.Cmd/Ctrl+Dduplicates the selected layer or multi-selection.Cmd/Ctrl+Aselects every visible layer.- Shift/Cmd-click toggles a layer in the current selection.
- Arrow keys nudge the selected layer(s) by 1 px; hold Shift for 10 px.
Deleteremoves the selected layer(s).- Hold Alt while dragging to skip snapping.
Escclears the selection or closes an open editor dialog.
Creating API 2.0 themes with the CLI
The create-ezpplauncher-theme CLI includes a declarative (API 2.0) template:
npx git+https://git.ez-pp.farm/EZPPFarm/create-ezpplauncher-theme.git my-theme
Choose declarative (API 2.0), edit theme.json, add files to assets/, then run:
npm run build
This produces dist/my_theme.ezpplauncher-theme. The template also includes
preview.html for a standalone browser preview:
npx serve .
Compatibility and limits
- API 2.0 packages must include
theme.json;entryandstyleare not used. - Asset paths are resolved inside
assets/; path traversal is rejected by the import commands. - Exports include only
assets/files referenced bytheme.json(background, audio, fonts, layers and preview). Orphaned files left in the folder are omitted, which keeps packages small. API 1.0 themes are exported whole because their bundles can load files dynamically. - The editor writes
preview.pngwhenever you save or export. The generated thumbnail renders the background, effects, launcher UI, theme fonts and freeform layers; custom CSS is not applied to the thumbnail. - The theme editor only writes inside
~/.ezpplauncher/themes. - API 1.0 themes are still loaded through their existing
mountThemebundle API. - API 2.0 themes cannot run JavaScript. Use custom CSS for small visual tweaks, or use API 1.0 when a theme needs a fully custom UI.
- Freeform layers are decorative, home-screen-only and pointer-transparent; they cannot add interactive controls.