cli Documentation

Command-line tool to customize Spotify client. Supports Windows, macOS, and Linux.

RAW Doc

1. Project Overview & Quickstart (spicetify/cli)

File: README.md

[](https://spicetify.app/)


Command-line tool to customize the official Spotify client.
Supports Windows, MacOS and Linux.

Features

  • Change colors across the User Interface
  • Inject CSS for advanced customization
  • Inject Extensions to extend functionalities, manipulate UI and control player
  • Inject Custom Apps
  • Make yourself in control of the Spotify client

Code Signing Policy

Free code signing provided by SignPath.io, certificate by SignPath Foundation.


File: CustomApps/lyrics-plus/README.md

Spicetify Custom App

Lyrics Plus

Show current track lyrics. Current lyrics providers:

  • Internal Spotify lyrics service.
  • Netease: From Chinese developers and users. Provides karaoke and synced lyrics.
  • Musixmatch: A company from Italy. Provided synced lyrics.
  • Genius: Provides unsynced lyrics but with description/insight from artists themselves (Disabled and cannot be used as a provider on 1.2.31 and higher).

Different lyrics modes: Karaoke, Synced, Unsynced and Genius. At the moment, only Netease provides karaoke-able lyrics. Mode is automatically falled back, from Karaoke, Synced, Unsynced to Genius when lyrics are not available in that mode.

Right click or Double click at any mode tab to "lock in", so lyric mode won't auto switch. It should show a dot next to mode name when mode is locked. Right click or double click again to unlock

Lyrics in Unsynced and Genius modes can be search and jump to. Hit Ctrl + Shift + F to open search box at bottom left of screen. Hit Enter/Shift+Enter to loop over results.

Choose between different option of displaying Japanese lyrics. (Furigana, Romaji, Hiragana, Katakana)

Customise colors, change providers' priorities in config menu. Config menu locates in Profile Menu (top right button with your user name).

To install, run:

bash
spicetify config custom_apps lyrics-plus
spicetify apply

Credits

2. Official Technical Reference & Guides (spicetify/docs)

File: README.md

Spicetify Docs

This repository holds the documentation for Spicetify, which can be found here.

Contributing

If you feel like you can contribute, please do so by opening an issue or pull request. We are always open to expand our documentation and add new features.


File: docs/development/api-wrapper/functions/add-to-queue.md


title: addToQueue

Adds a track or array of tracks to the bottom of the prioritized queue.

:::tip

This works similarly to Spicetify.Platform.PlayerAPI.addToQueue but works silently, meaning no notification will be shown.

If you want default Spotify behavior, use Spicetify.Platform.PlayerAPI.addToQueue instead.

:::

ts
function addToQueue(uri: ContextTrack[]): Promise<void>;

Parameters

Name Type Description
uri ContextTrack[] Array of tracks to add to queue.

Example

ts
// Add current track to queue
const currentTrack = Spicetify.Player.data.item;

await Spicetify.addToQueue([currentTrack]);

// Add a track to queue
const trackUri = "spotify:track:4iV5W9uYEdYUVa79Axb7Rh";

await Spicetify.addToQueue([ { uri: trackUri } ]);

---

## File: docs/development/api-wrapper/functions/color-extractor.md

---
title: colorExtractor
---

Extracts colors from a playlist, track, album, artist, show, etc.

```ts
function colorExtractor(uri: string): Promise<{
    DARK_VIBRANT: string;
    DESATURATED: string;
    LIGHT_VIBRANT: string;
    PROMINENT: string;
    VIBRANT: string;
    VIBRANT_NON_ALARMING: string;
}>;

Parameters

Parameter Type Description
uri string URI of anything that has artwork (playlist, track, album, artist, show, etc.)

Returns

Name Type Description
DARK_VIBRANT string Dark vibrant color in hex format.
DESATURATED string Desaturated color in hex format.
LIGHT_VIBRANT string Light vibrant color in hex format.
PROMINENT string Prominent color in hex format.
VIBRANT string Vibrant color in hex format.
VIBRANT_NON_ALARMING string Vibrant non alarming color in hex format.

Example

ts
// Get color from current track
const currentTrack = Spicetify.Player.data.item;
const colors = await Spicetify.colorExtractor(currentTrack.uri);

File: docs/development/api-wrapper/functions/get-audio-data.md


title: getAudioData

Fetch track analyzed audio data.

Under the hood, it uses the wg://audio-attributes/v1/audio-analysis/ endpoint, which is identical to Spotify Web API's Get Track's Audio Analysis. The only difference is that it doesn't require authentication.

:::caution

Beware, not all tracks have audio data.

:::

ts
function getAudioData(uri?: string): Promise<any>;

Parameters

Parameter Type Description
uri string | undefined URI of the track. If not provided, it will use the current track.

Returns

An object containing the audio data. See the Spotify Web API reference for more details.

Example

ts
// Get audio data from current track
const audioData = await Spicetify.getAudioData();

// Get audio data from a specific track
const audioData = await Spicetify.getAudioData("spotify:track:1qDrWA6lyx8cLECdZE7TV7");

File: docs/development/api-wrapper/functions/get-font-style.md


title: getFontStyle

Spicetify provides a function that returns the CSS style for a given font variant used in the Spotify app.

:::tip

This function is used to provide backwards compatibility for older Spicetify extensions and custom apps that use main-type- classes.

Instead of using this function to get Spotify stylings, you can simply add the main-type-<variant> class to your element.

:::

ts
function getFontStyle(font: Variant): string;

Parameters

Parameter Type Description
font Variant Font variant

Returns

string - CSS style for the given font variant.

Example

ts
const style = getFontStyle("forte");

// Returns "viola" if given an invalid variant
// Equivalent to `getFontStyle("viola");`
const style = getFontStyle("invalid-variant");

File: docs/development/api-wrapper/functions/remove-from-queue.md


title: removeFromQueue

:::tip

This works similarly to Spicetify.Platform.PlayerAPI.removeFromQueue.

:::

:::caution

If a uid is not provided, all tracks with the same uri will be removed.

:::

ts
function removeFromQueue(uri: ContextTrack[]): Promise<void>;

Parameters

Name Type Description
uri ContextTrack[] Array of tracks to remove from queue.

Example

ts
// Remove current track from queue
const currentTrack = Spicetify.Player.data.item;

await Spicetify.removeFromQueue([currentTrack]);

// Remove a track from queue
const trackUri = "spotify:track:4iV5W9uYEdYUVa79Axb7Rh";

await Spicetify.removeFromQueue([ { uri: trackUri } ]);

File: docs/development/api-wrapper/functions/show-notification.md


title: showNotification

Show a toast notification inside Spotify.

ts
function showNotification(text: string, isError?: boolean, msTimeout?: number): void;
Parameter Type Description
text string Message to display. Can use inline HTML for styling.
isError boolean If true, toast will be red. Defaults to false.
msTimeout number Time in milliseconds to display the toast. Defaults to Spotify's value.

Example

ts
// Display a notification
Spicetify.showNotification("My Menu Item clicked!");

// Display a notification with a custom timeout
Spicetify.showNotification("My Menu Item clicked!", false, 1000);

// Display an error notification
Spicetify.showNotification("Something wrong happened", true);

// Display a bolded error notification
Spicetify.showNotification("**Something wrong happened**", true);

File: docs/development/api-wrapper/classes/context-menu.md


title: ContextMenu

Create custom menu item and prepend to right click context menu.

Useful for adding custom actions to context menu (when a user right-clicks on a track, album, artist, etc.)

Classes

Item

Single context menu item.

ts
new Spicetify.ContextMenu.Item(
  name: string,
  onClick: OnClickCallback,
  shouldAdd?: ShouldAddCallback,
  icon?: SVGIcon | string,
  disabled?: boolean,
)

Parameters

Parameter Type Description
name string Name of the menu item.
onClick OnClickCallback Callback function when the menu item is clicked.
shouldAdd ShouldAddCallback Callback function to determine if the menu item should be added.
icon SVGIcon | string Icon of the menu item.
disabled boolean Whether the menu item is disabled.

Properties

:::tip

All of the listed properties are dynamic and can be changed at any time. Look into the example below for more information.

:::

Name Type Description
iconList readonly SVGIcon[] List of icons.
name string Name of the menu item.
icon SVGIcon | string Icon at the end of the menu item.
disabled boolean Whether the menu item is disabled.
shouldAdd ShouldAddCallback Callback function to determine if the menu item should be added.
onClick OnClickCallback Callback function when the menu item is clicked.

Methods

`register`

Register the menu item to context menu.

ts
register(): void

`deregister`

Remove the menu item from context menu.

ts
deregister(): void

Example

ts
// This function will determine if the selected item is a track
function ifItemIsTrack(uri) {
  let uriObj = Spicetify.URI.fromString(uri[0]);
  switch (uriObj.type) {
    case Type.TRACK:
      return true;
  }
  return false;
}

// Create a new menu item that only appears when a track is selected
const menuItem = new Spicetify.ContextMenu.Item(
  "My Menu Item",
  () => {
    Spicetify.showNotification("My Menu Item clicked!");
  },
  ifItemIsTrack,
  Spicetify.SVGIcons["play"],
  false,
);

// Register the menu item
menuItem.register();

// Deregister the menu item
menuItem.deregister();

// Change the menu item's name
menuItem.name = "My New Menu Item";

// Change the menu item's icon
menuItem.icon = "pause"

Create a sub menu to contain Items.

Items in subItems array shouldn't be registered.

ts
new Spicetify.ContextMenu.SubMenu(
  name: string,
  subItems: Iterable,
  shouldAdd?: ShouldAddCallback,
  disabled?: boolean,
)

Parameters

Parameter Type Description
name string Name of the menu item.
subItems Iterable Array of Items to be added to the sub menu.
shouldAdd ShouldAddCallback Callback function to determine if the menu item should be added.
disabled boolean Whether the menu item is disabled.

Properties

:::tip

All of the listed properties are dynamic and can be changed at any time. Look into the example below for more information.

:::

Name Type Description
name string Name of the menu item.
disabled boolean Whether the menu item is disabled.
shouldAdd ShouldAddCallback Callback function to determine if the menu item should be added.

Methods

`addItem`

Add an Item to the sub menu.

ts
addItem(item: Item): void
Parameter Type Description
item Item Item to be added to the sub menu.

`removeItem`

Remove an Item from the sub menu.

ts
removeItem(item: Item): void
Parameter Type Description
item Item Item to be removed from the sub menu.

`register`

Register the sub menu to context menu.

ts
register(): void

`deregister`

Remove the sub menu from context menu.

ts
deregister(): void

Example

ts
// Create a new menu item
const menuItem = new Spicetify.ContextMenu.Item(
  "My Menu Item",
  () => {
    Spicetify.showNotification("My Menu Item clicked!");
  },
  () => true,
  Spicetify.SVGIcons["play"],
  false,
);

// Create a new sub menu
const subMenu = new Spicetify.ContextMenu.SubMenu(
  "My Sub Menu",
  [menuItem],
  () => true,
  false,
);

// Register the sub menu
subMenu.register();

// Deregister the sub menu
subMenu.deregister();

// Change the sub menu's name
subMenu.name = "My New Sub Menu";

// Add a new menu item to the sub menu
subMenu.addItem(new Spicetify.ContextMenu.Item(
  "My New Menu Item",
  () => {
    Spicetify.showNotification("My New Menu Item clicked!");
  },
  () => true,
  Spicetify.SVGIcons["play"],
  false,
));

File: docs/development/api-wrapper/classes/menu.md


title: Menu

Create and prepend custom menu items in the profile menu.

Classes

Item

Single menu item.

ts
new Spicetify.Menu.Item(
  name: string,
  isEnabled: boolean,
  onClick: (self: Item) => void,
  icon?: SVGIcon | string,
)

Parameters

Parameter Type Description
name string Name of the menu item.
isEnabled boolean Whether the menu item is enabled.
onClick (self: Item) => void Callback function when the menu item is clicked.
icon SVGIcon | string Icon of the menu item.

Properties

:::tip

All of the listed properties are dynamic and can be changed at any time. Look into the example below for more information.

:::

Name Type Description
name string Name of the menu item.
isEnabled boolean Whether the menu item is enabled.
icon SVGIcon | string Icon of the menu item.

Methods

setName

Set the label of the menu item.

ts
setName(name: string): void
Parameter Type Description
name string Name of the menu item.

setState

Set the state of the menu item. The item will have a tick icon next to it if its state is enabled.

ts
setState(isEnabled: boolean): void
Parameter Type Description
isEnabled boolean Whether the menu item is enabled.

setIcon

Set the icon at the end of the menu item.

ts
setIcon(icon: SVGIcon | string): void
Parameter Type Description
icon SVGIcon | string Icon of the menu item.

register

Register the menu item to the profile menu.

ts
register(): void

deregister

Remove the menu item from the profile menu.

ts
deregister(): void

Example

ts
const item = new Spicetify.Menu.Item("My Item", true, () => {
  console.log("My Item is clicked");
});

item.register();

// item.name = "My Item (Updated)";
item.setName("My Item (Updated)");

// item.isEnabled = false;
item.setState(false);

// item.icon = "heart";
item.setIcon("heart");

Create a sub menu to contain Item toggles.

Items in subItems array shouldn't be registered.

ts
new Spicetify.Menu.SubMenu(
  name: string,
  subItems: Item[],
)

Parameters

Parameter Type Description
name string Name of the menu item.
subItems Item[] Array of sub menu items.

Properties

:::tip

All of the listed properties are dynamic and can be changed at any time. Look into the example below for more information.

:::

Name Type Description
name string Name of the menu item.

Methods

setName

Set the label of the menu item.

ts
setName(name: string): void
Parameter Type Description
name string Name of the menu item.

addItem

Add a sub menu item.

ts
addItem(item: Item): void
Parameter Type Description
item Item Sub menu item.

removeItem

Remove a sub menu item.

ts
removeItem(item: Item): void
Parameter Type Description
item Item Sub menu item.

register

Register the menu item to profile menu.

ts
register(): void

deregister

Remove the menu item from profile menu.

ts
deregister(): void

Example

ts
const item1 = new Spicetify.Menu.Item("My Item 1", true, () => {
  console.log("My Item 1 is clicked");
});

const item2 = new Spicetify.Menu.Item("My Item 2", true, () => {
  console.log("My Item 2 is clicked");
});

const subMenu = new Spicetify.Menu.SubMenu("My Sub Menu", [item1, item2]);

subMenu.register();

// subMenu.name = "My Sub Menu (Updated)";
subMenu.setName("My Sub Menu (Updated)");

// subMenu.addItem(item3);
subMenu.addItem(
  new Spicetify.Menu.Item("My Item 3", true, () => {
    console.log("My Item 3 is clicked");
  })
);

File: docs/development/api-wrapper/classes/playbar.md


title: Playbar

Create buttons in the player.

ts
namespace Playbar {
    class Button {
        constructor(label: string, icon: SVGIcon | string, onClick: (self: Button) => void, disabled?: boolean, active?: boolean, registerOnCreate?: boolean);
        label: string;
        icon: string;
        onClick: (self: Button) => void;
        disabled: boolean;
        active: boolean;
        element: HTMLButtonElement;
        tippy: any;
        register: () => void;
        deregister: () => void;
    }

    class Widget {
        constructor(label: string, icon: SVGIcon | string, onClick?: (self: Widget) => void, disabled?: boolean, active?: boolean, registerOnCreate?: boolean);
        label: string;
        icon: string;
        onClick: (self: Widget) => void;
        disabled: boolean;
        active: boolean;
        element: HTMLButtonElement;
        tippy: any;
        register: () => void;
        deregister: () => void;
    }
};

`Button`

Create buttons next to the player extra control buttons (e.g. queue, lyrics, Now Playing View, etc.).

This is useful for creating buttons whose actions have an impact on or relate to the player, and are generally dynamic/stateful, such as a button that toggles the player's loop mode.

Parameters

Parameter Type Description
label string Label of the button.
icon SVGIcon | string Icon of the button.
onClick (self: Button) => void Callback function when the button is clicked.
disabled boolean | undefined Whether the button is disabled.
active boolean | undefined Whether the button is active.
registerOnCreate boolean | undefined Whether the button should be registered to the player on creation.

Properties

:::tip

All of the listed properties are dynamic and can be changed at any time. Look into the example below for more information.

:::

Name Type Description
label string Label of the button.
icon string Icon of the button.
disabled boolean Whether the button is disabled.
active boolean Whether the button is active.
onClick (self: Button) => void Callback function when the button is clicked.
element HTMLButtonElement HTML element of the button.
tippy any Tippy instance of the button. For more information, see Tippy.js.

Methods

`register`

Register the button to the player.

ts
register(): void;

`deregister`

Deregister the button from the player.

ts
deregister(): void;

Example

:::caution

Tippy, onclick or any other click events will not work if disabled is set to true. You will need to manually enable the button inside your extension.

This is due to the limitations of Tippy itself and how HTML elements work.

:::

ts
// By default, the button will be registered to the player on creation.
// You can disable this by setting registerOnCreate to false.
// Each button comes with a preconfigured Tippy instance that aims to mimic the original Spotify tooltip.
const button = new Spicetify.Playbar.Button(
    "My Button",
    "play",
    (self) => {
        // Do something when the button is clicked.
    },
    false, // Whether the button is disabled.
    false, // Whether the button is active.
);

// You can also register the button to the player later.
button.register();

// Remove the button from the player when it is no longer needed.
button.deregister();
// If you don't want to remove the button entirely, you can also disable it.
button.disabled = true;

// Change button properties.
// Changing label will also change the tooltip content.
button.label = "Hello world!";
button.icon = "play";

// You can also set properties of the HTML element.
button.element.style.color = "red";
button.element.oncontextmenu = () => {
    Spicetify.showNotification("You right-clicked me!");
};
button.element.addEventListener("click", () => {
    // Do something else.
    Spicetify.showNotification("You clicked me!");
});

// You can also change properties of the Tippy instance. For more information, see https://atomiks.github.io/tippyjs/v6/tippy-instance/.
button.tippy.setContent("Hello world!");

// Or if you want to use HTML.
button.tippy.setProps({
    content: "**Hello world!**",
    allowHTML: true,
});

`Widget`

Create widgets in the player, next to track information similar to the Heart button.

This is useful for creating buttons whose actions have an impact on the state of the player and the track being played, such as a button that adds the current track to a playlist.

Parameters

Parameter Type Description
label string Label of the widget.
icon SVGIcon | string Icon of the widget.
onClick (self: Widget) => void Callback function when the widget is clicked.
disabled boolean | undefined Whether the widget is disabled.
active boolean | undefined Whether the widget is active.
registerOnCreate boolean | undefined Whether the widget should be registered to the player on creation.

Properties

:::tip

All of the listed properties are dynamic and can be changed at any time. Look into the example below for more information.

:::

Name Type Description
label string Label of the widget.
icon string Icon of the widget.
disabled boolean Whether the widget is disabled.
active boolean Whether the widget is active.
onClick (self: Widget) => void Callback function when the widget is clicked.
element HTMLButtonElement HTML element of the widget.
tippy any Tippy instance of the widget. For more information, see Tippy.js.

Methods

`register`

Register the widget to the player.

ts
register(): void;

`deregister`

Deregister the widget from the player.

ts
deregister(): void;

Example

:::caution

Tippy, onclick or any other click events will not work if disabled is set to true. You will need to manually enable the widget inside your extension.

This is due to the limitations of Tippy itself and how HTML elements work.

:::

ts
// By default, the widget will be registered to the player on creation.
// You can disable this by setting registerOnCreate to false.
// Each widget comes with a preconfigured Tippy instance that aims to mimic the original Spotify tooltip.
const widget = new Spicetify.Playbar.Widget(
    "My Widget",
    "play",
    (self) => {
        // Do something when the widget is clicked.
    },
    false, // Whether the widget is disabled.
    false, // Whether the widget is active.
);

// You can also register the widget to the player later.
widget.register();

// Remove the widget from the player when it is no longer needed.
widget.deregister();

// Change widget properties.
// Changing label will also change the tooltip content.
widget.label = "Hello world!";
widget.icon = "play";

// You can also set properties of the HTML element.
widget.element.style.color = "red";
widget.element.oncontextmenu = () => {
    Spicetify.showNotification("You right-clicked me!");
};
widget.element.addEventListener("click", () => {
    // Do something else.
    Spicetify.showNotification("You clicked me!");
});

// You can also change properties of the Tippy instance. For more information, see https://atomiks.github.io/tippyjs/v6/tippy-instance/.
widget.tippy.setContent("Hello world!");

// Or if you want to use HTML.
widget.tippy.setProps({
    content: "**Hello world!**",
    allowHTML: true,
});