YouTube Music Desktop App bundled with custom plugins (and built-in ad blocker / downloader)
YouTube Music Desktop App
The YouTube Music Desktop App is an enhanced desktop application designed to offer a richer experience of YouTube Music with features such as custom plugins, built-in ad blocking, and offline downloading capabilities. It provides native download support for offline listening, extensive plugin functionality allowing users to modify the interface or add new features, and cross-platform availability via package managers like Winget on Windows, Homebrew on macOS, and AUR on Linux. The app supports customizable themes for a personalized look and feel, making it ideal for music enthusiasts seeking an enhanced, distraction-free experience with extended functionalities.
Key Features:
Built-in Ad Blocker: Eliminates distractions by blocking ads within the YouTube Music interface.
Offline Download Support: Enables users to download their favorite songs and playlists for offline listening.
Custom Plugins: Offers extensive plugin functionality that allows users to modify the interface or add new features, enhancing the app's capabilities according to personal preferences.
Cross-Platform Compatibility: Available on multiple platforms including Windows, macOS, and Linux, with support via package managers like Winget, Homebrew, and AUR for easy installation.
Customizable Themes: Provides options for users to personalize the app’s look and feel through various themes.
Audience & Benefits:
Ideal for music enthusiasts and tech-savvy individuals who desire an enhanced listening experience. The app provides a distraction-free environment with extended functionalities, allowing users to tailor their experience through plugins and custom themes. This makes it perfect for those looking to customize their YouTube Music experience beyond the standard offering.
This description adheres to the guidelines by focusing on professional tone, clear benefits, avoiding hype words, mentioning installation via Winget without discussing download possibilities, and staying within character limits.
README
:pear: Pear Desktop
Native look & feel extension
> [!IMPORTANT]
> ⚠️ Disclaimer
>
> No Affiliation
>
> This project, and its contributors, are not affiliated with, authorized by, endorsed by, or in any way officially connected with Google LLC, YouTube, or any of their subsidiaries or affiliates. This is an independent, non-profit, and unofficial extension developed by a team of volunteers with the goal of providing a desktop experience.
>
> Trademarks
>
> The names "Google" and "YouTube Music", as well as related names, marks, emblems, and images, are registered trademarks of their respective owners. Any use of these trademarks is for identification and reference purposes only and does not imply any association with the trademark holder. We have no intention of infringing upon these trademarks or causing harm to the trademark holders.
>
> Limitation of Liability
>
> This application (extension) is provided "AS IS", and you use it at your own risk. In no event shall the developers or contributors be liable for any claim, damages, or other liability, including any legal consequences, arising from, out of, or in connection with the software or the use or other dealings in the software. The responsibility for any and all outcomes of using this software rests entirely with the user.
Alternately you can use Winget, Windows 11s
official CLI package manager to install the pear-devs.pear-desktop 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 pear-devs.pear-desktop
How to install without a network connection? (in Windows)
Download the *.nsis.7z file for your device architecture in release page.
x64 for 64-bit Windows
ia32 for 32-bit Windows
arm64 for ARM64 Windows
Download installer in release page. (*-Setup.exe)
Place them in the same directory.
Run the installer.
Themes
You can load CSS files to change the look of the application (Options > Visual Tweaks > Themes).
git clone https://github.com/pear-devs/pear-desktop
cd pear-desktop
pnpm install --frozen-lockfile
pnpm dev
Build your own plugins
Using plugins, you can:
manipulate the app - the BrowserWindow from electron is passed to the plugin handler
change the front by manipulating the HTML/CSS
Creating a plugin
Create a folder in src/plugins/YOUR-PLUGIN-NAME:
index.ts: the main file of the plugin
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
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, context) {
// 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
injecting custom CSS: create a style.css file in the same folder then:
// 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, pear-desktop will show a restart dialog
config: {
enabled: false,
}, // your custom config
stylesheets: [style], // your custom style
renderer() {} // define renderer hook
});
If you want to change the HTML:
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() {
console.log('hello from renderer');
} // define renderer hook
});
communicating between the front and back: can be done using the ipcMain module from electron. See index.ts file and
example in sponsorblock plugin.