# Ceru Music ships the player and the plugin runtime, and leaves the music to you

> Ceru Music is an Electron and Vue 3 desktop music player that deliberately contains no music of its own. It provides a plugin host, playback, lyrics and cover art, virtual scrolling, and local playlist management, and the user supplies the data source by installing plugins. The licence in the package manifest is AGPL-3.0-only, alongside a separate EULA, and the project is releasing weekly.

**timeshiftsauce/CeruMusic** — Ceru Music 是基于 Electron 和 Vue 开发的跨平台桌面音乐播放器工具，借鉴洛雪音乐插件思想，提供插件运行框架与播放功能，不直接存储、提供任何音乐源文件。用户需通过自行选择、安装合规插件获取音乐相关数据，项目旨在为开发者提供桌面应用技术实践与学习案例，为用户提供合规的音乐播放工具框架。

- Repository: https://github.com/timeshiftsauce/CeruMusic
- Website: https://ceru.docs.shiqianjiang.cn
- Stars: 2,006 · Forks: 115
- Language: Vue
- License: NOASSERTION
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/timeshiftsauce-cerumusic

## A player with no music in it

The project's own framing is unusually careful, and it is worth reading closely before anything else. Ceru Music is a cross platform desktop music player application that supports obtaining public music information and playback through compliant plugins, and it only provides the plugin running framework and playback features, without directly storing or providing any music source files. Users are expected to obtain music related data by selecting and installing compliant plugins themselves, and the stated aim is to give developers a desktop application practice and learning case, and to give users a compliant music playback tool framework.

So the deliverable is the machinery: the window, the queue, the visualiser, the playlist, the plugin host, and the update mechanism. The content comes from outside, and the README says in more than one place that the plugin is the user's responsibility to obtain.

The design is explicitly modelled on the plugin approach of the LX Music project, and the main feature list is built around that boundary. It offers plugin loading and management to obtain public music information through compliant plugins, lyrics and album cover metadata through plugins, a virtual scrolling list to keep rendering fast with a lot of data, and local playlist management where only the structure of lists the user created is stored and never the music files themselves.

That boundary is what makes the project interesting to read and also what makes it conditional to use. Nothing arrives until a plugin does.

The package manifest records the name ceru-music at version 2.3.1, the author as the project team, and the homepage as ceru.docs.shiqianjiang.cn. The last push was on 2026-10-10.

## The plugin host is the part with the interesting design

The source tree shows where the effort went, and it is not in the player chrome.

In the Electron main process there is a plugin/ directory with a manager/ subdirectory holding CeruMusicPluginHost.ts, converter-event-driven.ts, a logger.ts and an index.ts. A host that loads third party code, plus a converter that translates between event driven models, plus a logger, is the shape of a plugin system that expects to be extended.

Next to it sits musicSdk/, with index.ts, service.ts and type.ts, and services/music/ with a service-base.ts and a net-ease-service.ts. The base class is the abstraction and the NetEase implementation is one concrete source, which tells you how a plugin provides the data: it implements a service interface rather than patching the application.

The renderer side has a components/Plugins area with a plugins.vue settings page and a PluginNoticeDialog.vue, and there is a whole website/ directory at the top level with pluginDev.html and script.js. That is a plugin development page shipped inside the repository, which is a strong signal that writing plugins is a first class activity rather than an afterthought.

The main process also carries an events/ directory with autoUpdate.ts, musicCache.ts, pluginNotice.ts, directorySettings.ts, songList.ts and ai.ts, a songList/ directory with ManageSongList.ts and PlayListSongs.ts, an ai-service.ts and a ConfigManager.ts. The renderer has its own services/music with the same service-base pattern, so the same base class appears on both sides of the process boundary, which is how a plugin contract stays consistent between main and renderer.

## Electron in the middle, Vue and Pinia in the front

The stack section of the README lists Electron for the cross platform desktop application, Vue 3 for the front end with a reactive user interface, TypeScript for maintainability and type safety, Pinia for state management, Vite as the fast front end build tool, and CeruPlugins as the music plugin runtime environment, with the note that it provides only the framework and contains no default plugins.

The directory layout follows the standard Electron split, with main/ for the main process, preload/ for the bridge, and renderer/ for the Vue application, plus a common/ directory shared between them that holds the types for playlists and song lists, the lyric utilities, and the common, nodejs and renderer helpers.

The renderer is a normal Vue 3 application. There are components for the AI float ball, the context menu, the home layout, a virtualised song list, and a Play/ directory with an audio visualiser, a full player view, a global audio component, playlist actions, a playlist drawer, the play view and a shader background. The store/ directory holds the Pinia stores for audio control, local user detail, search and settings, and utils/ contains the audio helpers including a media session integration, a downloader and a volume module, a colour extractor and a contrast colour helper, and playlist import and export.

The build is electron-vite, and the configuration is split into tsconfig.node.json and tsconfig.web.json with a separate typecheck for each, one for the Node side with tsc and one for the web side with vue-tsc.

## Four packaging targets and a build that checks its own dependencies

The scripts in the package manifest show a project that takes packaging seriously, and the build is not a single command.

```json
"build": "yarn run check:packaging && yarn run typecheck && cross-env NODE_OPTIONS=--max-old-space-size=4096 electron-vite build",
"build:mac:universal": "yarn run build && electron-builder --mac --universal --config --publish never",
"build:win": "yarn run build && electron-builder --win --x64 --config --publish never",
"dev": "electron-vite dev --watch",
```

The build runs a packaging check first, then the type checks, then the electron-vite build, with the Node heap raised to 4GB for the bundling step. The check script is scripts/check-production-deps.mjs, and there is a postinstall hook that runs scripts/prepare-native-modules.mjs, which is what makes a native module work in a packaged build rather than only in development.

The packaging targets are separate scripts. There is build:win for Windows on x64, build:mac, build:mac:intel for a dmg and a zip on x64, build:mac:arm64 for the same on arm64, build:mac:universal for a universal binary, build:linux, and build:unpack for a directory build. The publishing flag is set to never in these commands, so the artefacts are produced locally rather than pushed anywhere, and electron-builder is driven by electron-builder.yml at the top of the source tree.

There are also development conveniences worth noting. dev:debug adds a remote debugging port, and dev:second launches a second instance through scripts/launch-second-instance.mjs, which is a common need for a single instance application that needs a second window for a playlist or a track.

## Local playlists store structure, and nothing is backed up

The feature list contains the honest limitation in bold, and it is worth quoting in substance. Local playlist management stores only the structure of the lists the user created and does not include music files, and the tip that goes with it says that local data is kept only on the user's device with no cloud backup, so the user needs to back it up themselves to avoid losing data.

So the playlists are metadata: a name, an ordering, a reference to a track. That is a deliberate design rather than an omission, since the music itself comes from a plugin and the application is not in the business of holding files. The consequence is that the user owns the only copy of the playlist structure, and a reinstall of the application, or a change of device, means the playlists have to be exported and imported by hand.

The renderer already has the tooling for that, since utils/playlist/ contains playlistExportImport.ts alongside playlistManager.ts. The export and import path exists in the application, and the user has to know to use it before they wipe something.

The second limitation is the plugin supply, and it is the one that decides whether the application is usable at all on a given day. The plugin is the user's to obtain, the project ships no default plugin, and there is no catalogue of known plugins in the README to point at. The documentation site at ceru.docs.shiqianjiang.cn is where that information would live.

There is a third, quieter limitation in the licence. The package manifest says AGPL-3.0-only, and the repository carries both a LICENSE file and a separate EULA.txt. For an application whose plugin architecture is the point, that is a licence combination a team should read closely before building on it.

## Weekly releases and a plugin developer page in the repository

The release history shows a project that is moving quickly. The listed tags are v2.3.1 on 2026-10-10, v2.2.1 on 2026-10-07 and v2.2.0 on 2026-10-05, and the last push was on 2026-10-10.

Three releases in six days is a fast cadence for a desktop application, and it has an obvious consequence for anyone who depends on it. A plugin built against one version of the plugin host may not work against the next, and the project does not describe a plugin API stability policy in the README. The release notes are in CHANGELOG.md at the repository root, so the practical habit is to read it before updating, and to pin the application version a plugin was tested against.

The repository also carries a few things that describe how the project is run rather than what it does. There is an AGENTS.md and a CLAUDE.md for tooling, a contributor-merge-checklist.md, a .codegraph/ directory, a qodana.yaml for static analysis, a jest.config.js alongside the Vitest style tooling, and separate update-server/ and vendor/ directories, which suggests the application talks to its own update server and bundles some dependencies rather than fetching everything at runtime.

The plugins/ directory at the top level is worth a look for anyone planning to write a plugin, since it holds what the project ships in the way of plugin related material, next to the website/ directory with pluginDev.html.

The overall picture is of a project that is explicitly two things at once, a usable player for someone who installs a plugin, and a worked example of a desktop application for people learning to build one. The README says both, and the release cadence suggests the second reading is the active one.

## Conclusion

Ceru Music fits a developer who wants a desktop player with a working plugin framework, or who wants to write a plugin for a music service and needs the host to exist, and the project presents itself as both a tool and a learning case for desktop application development. It is the wrong choice for someone who wants an application that plays music on installation, since there is no source until you install one. Verify first which plugin you will use and where it comes from, because the project deliberately ships none, and read EULA.txt alongside the AGPL terms before you base a product on it.

## FAQ

### Does Ceru Music come with any music sources?

No. The README is explicit that it only provides the plugin running framework and playback features, without directly storing or providing any music source files, and that users obtain music data by choosing and installing compliant plugins themselves. The CeruPlugins runtime ships without default plugins.

### What technology is Ceru Music built with?

Electron for the cross platform desktop application, Vue 3 for the front end, TypeScript for type safety, Pinia for state management, Vite as the front end build tool, and CeruPlugins as the plugin runtime environment. The source tree is split into main, preload, renderer and common directories.

### How do I build Ceru Music for macOS?

There are separate scripts in the package manifest: build:mac for macOS in general, build:mac:intel for a dmg and a zip on x64, build:mac:arm64 for the same on arm64, and build:mac:universal for a universal binary. Each one runs the build first, which itself runs a packaging check and the type checks before electron-vite build.

### What does Ceru Music store locally?

Only the structure of the playlists the user created, and no music files. The README also notes that local data is kept only on the user's device with no cloud backup, so users need to back it up themselves, and the renderer includes playlist export and import utilities.

### Under what licence is Ceru Music released?

The package manifest records AGPL-3.0-only, and the repository holds a LICENSE file alongside a separate EULA.txt. The version in the manifest is 2.3.1, the newest listed release, and the last push was on 2026-10-10.

## Sources

- [Issues](https://github.com/timeshiftsauce/CeruMusic/issues)
- [Project website](https://ceru.docs.shiqianjiang.cn)
- [README](https://github.com/timeshiftsauce/CeruMusic/blob/main/README.md)
- [Releases](https://github.com/timeshiftsauce/CeruMusic/releases)
- [timeshiftsauce/CeruMusic on GitHub](https://github.com/timeshiftsauce/CeruMusic)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/timeshiftsauce-cerumusic
