Home

Awesome

<div align="center">

YouTube Music

GitHub release GitHub license eslint code style Build status GitHub All Releases AUR Known Vulnerabilities

</div>

Screenshot

<div align="center"> <a href="https://github.com/th-ch/youtube-music/releases/latest"> <img src="web/youtube-music.svg" width="400" height="100" alt="YouTube Music SVG"> </a> </div>

Read this in other languages: 🇰🇷, 🇮🇸, 🇨🇱 🇪🇸, 🇷🇺

Electron wrapper around YouTube Music featuring:

Demo Image

Player Screen (album color theme & ambient light)
Screenshot1

Content

Features:

Available plugins:

Translation

You can help with translation on Hosted Weblate.

<a href="https://hosted.weblate.org/engage/youtube-music/"> <img src="https://hosted.weblate.org/widget/youtube-music/i18n/multi-auto.svg" alt="translation status" /> <img src="https://hosted.weblate.org/widget/youtube-music/i18n/287x66-black.png" alt="translation status 2" /> </a>

Download

You can check out the latest release to quickly find the latest version.

Arch Linux

Install the youtube-music-bin package from the AUR. For AUR installation instructions, take a look at this wiki page.

macOS

You can install the app using Homebrew (see the cask definition):

brew install th-ch/youtube-music/youtube-music

If you install the app manually and get an error "is damaged and can’t be opened." when launching the app, run the following in the Terminal:

/usr/bin/xattr -cr /Applications/YouTube\ Music.app

Windows

You can use the Scoop package manager to install the youtube-music package from the extras bucket.

scoop bucket add extras
scoop install extras/youtube-music

Alternately you can use Winget, Windows 11s official CLI package manager to install the th-ch.YouTubeMusic package.

Note: Microsoft Defender SmartScreen might block the installation since it is from an "unknown publisher". This is also true for the manual installation when trying to run the executable(.exe) after a manual download here on github (same file).

winget install th-ch.YouTubeMusic

How to install without a network connection? (in Windows)

Themes

You can load CSS files to change the look of the application (Options > Visual Tweaks > Themes).

Some predefined themes are available in https://github.com/kerichdev/themes-for-ytmdesktop-player.

Dev

git clone https://github.com/th-ch/youtube-music
cd youtube-music
pnpm install --frozen-lockfile
pnpm dev

Build your own plugins

Using plugins, you can:

Creating a plugin

Create a folder in src/plugins/YOUR-PLUGIN-NAME:

import style from './style.css?inline'; // import style as inline

import { createPlugin } from '@/utils';

export default createPlugin({
  name: 'Plugin Label',
  restartNeeded: true, // if value is true, ytmusic show restart dialog
  config: {
    enabled: false,
  }, // your custom config
  stylesheets: [style], // your custom style,
  menu: async ({ getConfig, setConfig }) => {
    // All *Config methods are wrapped Promise<T>
    const config = await getConfig();
    return [
      {
        label: 'menu',
        submenu: [1, 2, 3].map((value) => ({
          label: `value ${value}`,
          type: 'radio',
          checked: config.value === value,
          click() {
            setConfig({ value });
          },
        })),
      },
    ];
  },
  backend: {
    start({ window, ipc }) {
      window.maximize();

      // you can communicate with renderer plugin
      ipc.handle('some-event', () => {
        return 'hello';
      });
    },
    // it fired when config changed
    onConfigChange(newConfig) { /* ... */ },
    // it fired when plugin disabled
    stop(context) { /* ... */ },
  },
  renderer: {
    async start(context) {
      console.log(await context.ipc.invoke('some-event'));
    },
    // Only renderer available hook
    onPlayerApiReady(api: YoutubePlayer, context: RendererContext) {
      // set plugin config easily
      context.setConfig({ myConfig: api.getVolume() });
    },
    onConfigChange(newConfig) { /* ... */ },
    stop(_context) { /* ... */ },
  },
  preload: {
    async start({ getConfig }) {
      const config = await getConfig();
    },
    onConfigChange(newConfig) {},
    stop(_context) {},
  },
});

Common use cases

// index.ts
import style from './style.css?inline'; // import style as inline

import { createPlugin } from '@/utils';

export default createPlugin({
  name: 'Plugin Label',
  restartNeeded: true, // if value is true, ytmusic will show a restart dialog
  config: {
    enabled: false,
  }, // your custom config
  stylesheets: [style], // your custom style
  renderer() {} // define renderer hook
});
import { createPlugin } from '@/utils';

export default createPlugin({
  name: 'Plugin Label',
  restartNeeded: true, // if value is true, ytmusic will show the restart dialog
  config: {
    enabled: false,
  }, // your custom config
  renderer() {
    // Remove the login button
    document.querySelector(".sign-in-link.ytmusic-nav-bar").remove();
  } // define renderer hook
});

Build

  1. Clone the repo
  2. Follow this guide to install pnpm
  3. Run pnpm install --frozen-lockfile to install dependencies
  4. Run pnpm build:OS

Builds the app for macOS, Linux, and Windows, using electron-builder.

Production Preview

pnpm start

Tests

pnpm test

Uses Playwright to test the app.

License

MIT © th-ch

FAQ

Why apps menu isn't showing up?

If Hide Menu option is on - you can show the menu with the <kbd>alt</kbd> key (or <kbd>`</kbd> [backtick] if using the in-app-menu plugin)