.deskin format reference

A .deskin file is a ZIP archive containing a skin.json manifest and, optionally, image assets. Audeeport loads .deskin files (and plain .zip files) from ~/.audeeport/skins/.

Package structure

my-skin.deskin              ← ZIP archive, .deskin extension
├── skin.json               ← required, manifest
├── preview.png             ← recommended, preview shown in the gallery
├── index.html              ← required for web skins only (see below)
└── assets/                 ← optional, custom images
    ├── np_bg.png
    ├── btn_play.png
    ├── btn_pause.png
    ├── no_art.png
    └── ...

The assets/ folder can contain subdirectories. Reference each asset by relative path from the package root (for example assets/btn_play.png).

skin.json reference

{
  "meta": {
    "id": "unique-skin-id",
    "name": "My Cool Skin",
    "author": "YourName",
    "version": "1.0",
    "description": "A description of this skin",
    "website": "https://example.com",
    "isDark": true,
    "previewImage": "preview.png"
  },

  "colors": {
    "background": "#0D0D0F",
    "surface": "#161618",
    "surfaceVariant": "#1E1F22",
    "surfaceContainer": "#222326",
    "surfaceBright": "#2A2B2F",
    "onBackground": "#E4E4E6",
    "onSurface": "#E4E4E6",
    "onSurfaceVariant": "#9A9A9E",
    "onSurfaceMuted": "#6A6A6E",
    "outline": "#32333A",
    "accent": "#D4A574",
    "accentVariant": "#E8C49A",
    "onAccent": "#1A1A1A",
    "nowPlayingBackground": "#080808",
    "miniPlayerBackground": "#1A1A1E",
    "bottomBarBackground": "#121214"
  },

  "typography": {
    "headlineWeight": 600,
    "bodyWeight": 400,
    "scaleFactor": 1.0
  },

  "shapes": {
    "artRadiusSmall": 6,
    "artRadiusMedium": 8,
    "artRadiusLarge": 12,
    "cardRadius": 12,
    "buttonRadius": 22,
    "seekbarHeight": 3
  },

  "assets": {
    "nowPlayingBackground": "assets/np_bg.png",
    "libraryBackground": "assets/library_bg.png",
    "bottomBarBackground": "assets/bar_bg.png",
    "miniPlayerBackground": "assets/mini_bg.png",

    "buttonPlay": "assets/btn_play.png",
    "buttonPause": "assets/btn_pause.png",
    "buttonStop": "assets/btn_stop.png",
    "buttonNext": "assets/btn_next.png",
    "buttonPrevious": "assets/btn_prev.png",
    "buttonShuffle": "assets/btn_shuffle.png",
    "buttonRepeat": "assets/btn_repeat.png",

    "seekbarTrack": "assets/seek_track.png",
    "seekbarFill": "assets/seek_fill.png",
    "seekbarThumb": "assets/seek_thumb.png",

    "eqSliderTrack": "assets/eq_track.png",
    "eqSliderThumb": "assets/eq_thumb.png",

    "albumArtPlaceholder": "assets/no_art.png",
    "appLogo": "assets/logo.png",

    "iconLibrary": "assets/ic_library.png",
    "iconEq": "assets/ic_eq.png",
    "iconBitacora": "assets/ic_journal.png",
    "iconEchoes": "assets/ic_echoes.png"
  },

  "layout": {
    "nowPlayingArtSize": 0.78,
    "nowPlayingArtShadow": true,
    "nowPlayingShowAlbumName": true,
    "nowPlayingControlsSize": 1.0,

    "albumGridMinSize": 160,
    "albumGridSpacingH": 16,
    "albumGridSpacingV": 20,

    "trackRowShowArt": true,
    "trackRowArtSize": 44,
    "trackRowDividers": true,

    "bottomBarShowLabels": true,

    "miniPlayerHeight": 56,
    "miniPlayerShowProgress": true
  }
}

Everything except meta.id, meta.name, and meta.author is optional. Missing values fall back to the Midnight (default) skin.

meta (required)

FieldTypeRequiredNotes
idstringyesMust be unique across installed skins.
namestringyesShown in the gallery.
authorstringyes
versionstringnoDefaults to 1.0.
descriptionstringnoOne- to two-sentence summary.
websiteURLnoLink from the gallery.
isDarkbooleannotrue for dark skins, false for light. Defaults to true. Affects system UI integration.
previewImagestringnoRelative path to a preview image (for example preview.png).

colors

Overrides Audeeport’s theme palette. Every key is optional, and any you omit falls back to the default skin. Available keys: background, surface, surfaceVariant, surfaceContainer, surfaceBright, onBackground, onSurface, onSurfaceVariant, onSurfaceMuted, outline, accent, accentVariant, onAccent, nowPlayingBackground, miniPlayerBackground, bottomBarBackground.

Colors use hex format: #RRGGBB (opaque) or #AARRGGBB (with alpha).

typography

FieldTypeNotes
headlineWeightintFont weight for headings (for example 600).
bodyWeightintFont weight for body text (for example 400).
scaleFactorfloatMultiplies the base text scale (1.0 is default).

shapes

Overrides corner radii and the seek bar thickness. Keys: artRadiusSmall, artRadiusMedium, artRadiusLarge, cardRadius, buttonRadius, seekbarHeight (all integers, in dp).

assets

Optional images applied to native UI elements. Keys: nowPlayingBackground, libraryBackground, bottomBarBackground, miniPlayerBackground, buttonPlay, buttonPause, buttonStop, buttonNext, buttonPrevious, buttonShuffle, buttonRepeat, seekbarTrack, seekbarFill, seekbarThumb, eqSliderTrack, eqSliderThumb, albumArtPlaceholder, appLogo, iconLibrary, iconEq, iconBitacora, iconEchoes.

layout

Fine-tunes sizing and toggles for the Now Playing screen, album grid, track rows, bottom bar, and mini player. Keys: nowPlayingArtSize, nowPlayingArtShadow, nowPlayingShowAlbumName, nowPlayingControlsSize, albumGridMinSize, albumGridSpacingH, albumGridSpacingV, trackRowShowArt, trackRowArtSize, trackRowDividers, bottomBarShowLabels, miniPlayerHeight, miniPlayerShowProgress.

Asset guidelines

AssetRecommended sizeFormat
previewImage400x300PNG
nowPlayingBackground / libraryBackground1080x1920 or tileablePNG/JPG
buttonPlay / buttonPause / buttonNext / buttonPrevious64x64PNG (transparent bg)
seekbarTrack / seekbarFill800x8PNG
seekbarThumb24x24PNG (transparent bg)
eqSliderTrack8x200PNG
eqSliderThumb24x24PNG (transparent bg)
albumArtPlaceholder400x400PNG
Bottom bar icons24x24PNG (transparent bg)

Monochrome icons with transparency work best, since they adapt to the accent color.

Web skins

A web skin is a .deskin package with an index.html at its root (plus any CSS, JS, and image assets it needs). Audeeport detects the index.html and loads it in a JavaFX WebView in its own focused window when the user switches to that skin. The skin draws the entire player interface.

The JavaScript bridge

When the page loads, Audeeport injects a window.Audeeport object and fires an audeeport-ready event. Listen for it before you assume the bridge is present:

document.addEventListener('audeeport-ready', () => {
  // window.Audeeport is now available.
})

Inbound: audeeport-state events

State updates arrive as an audeeport-state CustomEvent. The latest state is also always available as window.Audeeport.state, and you can assign a function to Audeeport.onStateChange to receive the same payload.

document.addEventListener('audeeport-state', (e) => {
  const {
    title,           // current track title
    artist,          // current track artist
    album,           // current track album
    albumArt,        // data: URL for the cover, or null
    isPlaying,       // boolean
    progressMs,      // playback position in milliseconds
    durationMs,      // track duration in milliseconds
    progress,        // position as a 0.0 to 1.0 fraction
    volume,          // 0.0 to 1.0
    shuffle,         // boolean
    repeat,          // 'off' | 'all' | 'one'
    queue,           // array of { id, title, artist, durationMs, albumArt }
    currentTrackId   // id of the playing queue row
  } = e.detail

  // Update your UI here.
})

Inbound: audeeport-palette events

When the user’s color theme changes, Audeeport fires an audeeport-palette CustomEvent and updates window.Audeeport.palette. Use it so a single web skin adapts to Midnight, Arctic, and the rest without shipping multiple copies.

document.addEventListener('audeeport-palette', (e) => {
  const { skinId, accent, accentVariant, onAccent, background, surface,
          surfaceVariant, surfaceContainer, surfaceBright, onSurface,
          onSurfaceVariant, onSurfaceMuted, outline, isDark } = e.detail
})

Outbound: Audeeport.* methods

Audeeport.play()
Audeeport.pause()
Audeeport.togglePlayPause()
Audeeport.stop()
Audeeport.next()
Audeeport.previous()
Audeeport.seek(fraction)      // 0.0 to 1.0, not seconds
Audeeport.setVolume(fraction) // 0.0 to 1.0
Audeeport.toggleShuffle()
Audeeport.cycleRepeat()
Audeeport.playAtIndex(index)  // play a queue row by index
Audeeport.dismiss()           // close the skin and return to the desktop window
Audeeport.dragWindow(dx, dy)  // move the chromeless skin window

There is also a helper, Audeeport.formatTime(ms), which returns a m:ss string.

Notes for web-skin authors

Minimal example: color-only skin

{
  "meta": {
    "id": "neon-pink",
    "name": "Neon Pink",
    "author": "Community",
    "isDark": true
  },
  "colors": {
    "background": "#0A0A0A",
    "surface": "#141414",
    "surfaceVariant": "#1E1E1E",
    "accent": "#FF1493",
    "onBackground": "#FFFFFF",
    "onSurface": "#FFFFFF",
    "onSurfaceVariant": "#AAAAAA",
    "onAccent": "#000000"
  }
}

ZIP this single file (no assets/ folder needed for a color-only skin) and rename it to neon-pink.deskin.

Install path

~/.audeeport/skins/ on macOS and Linux. %USERPROFILE%\.audeeport\skins\ on Windows.

Drop the .deskin file into the folder and refresh the gallery. No restart required.

Tips

Where to go next