Open-source project
qier222/YesPlayMusic avatar
qier222/YesPlayMusic

YesPlayMusic: the manifest says MIT, the readme forbids commercial use, and the compose file disables TLS checks

高颜值的第三方网易云播放器,支持 Windows / macOS / Linux :electron:

33,335 stars4,660 forksVueMIT

At a glance

What is it?
YesPlayMusic is a Vue and Electron client for NetEase Cloud Music on Windows, macOS and Linux, with six documented deployment routes including Vercel, your own server, a control panel, Docker and Replit. The version line is split, with the 0.4 series in maintenance and a 2.0 alpha on the releases page. Two things in the repository deserve reading before anyone deploys it: a licence statement that contradicts itself, and a compose file that turns off certificate verification and impersonates the real music hostnames.
Who is it for?
Use YesPlayMusic if you want a NetEase Cloud Music client on a desktop or self-hosted and you read the deployment section before you deploy rather than after. Do not build anything commercial on it without settling the licence question, because the manifest declares MIT while the readme restricts the project to personal study and prohibits commercial and illegal use, and the two statements are not the same.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 109 days ago.
What is it written in?
Mainly Vue, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The licence section and the manifest say different things

The licence section is two statements, and they pull in opposite directions.

The first says the project is for personal study and research only, and that commercial and illegal use is prohibited. The second says the project is open sourced under the MIT licence.

Those cannot both be the operative terms. MIT grants broad permission to use, copy, modify, merge, publish, distribute, sublicense and sell copies, subject to retaining the notice. A readme sentence that forbids commercial use is not a term of the MIT licence; it is a statement of intent by the author, and the repository's own licence field records MIT.

For an engineer this matters in a specific way. If you are evaluating the project for internal use at a company, you will find no ambiguity in the licence field and a clear prohibition in the prose, and those two signals point in different directions. The only way to resolve it is to ask the author, and the answer you get may differ from the file the tooling read. Nothing else in the repository addresses the conflict.

The 0.4 line is in maintenance and a 2.0 alpha lives on the releases page

The version state of this project is unusual and the README states it plainly.

The new version section announces that a 2.0 alpha test build has been released and points to the releases page to download it. And then the sentence that decides what you install: the current version will enter maintenance mode, and apart from major bug fixes no new features will be updated.

The installation itself is short. Download a build from the releases page, or use one of the two package manager lines, one for each of the platforms that has one:

bash
brew install --cask yesplaymusic
scoop install extras/yesplaymusic

The README states that the desktop version is adapted and maintained by two named people for all three platforms.

Now put the tags next to that. The three most recent releases are 0.4.10 from October 2025, 0.4.9 from November 2024, and a 0.4.8 revision two from March 2024. The manifest version is 0.4.10. So the published tags are the maintenance line, the alpha lives somewhere the tags do not describe, and the last push to the repository was 2026-06-14, which is after the newest tag.

The practical consequence is that there is no version number a deployment can point at and be sure of. A tag gives you the maintenance line, which the author has said will not gain features. The features are in a build the tags do not name. That is workable for a personal install and awkward for anything you intend to keep up to date.

The compose file disables certificate checks and aliases the real hostnames

This is the part of the repository an engineer deploying it should read first, and it is not in the prose.

The compose file defines two services on a bridge network. The second pulls a third-party image and registers a set of network aliases: the real music hostnames, two interface hostnames, and two more under a different domain. The first service then depends on it. In other words, the unblocking proxy is wired into the network so that requests addressed to the music service's own hostnames are answered by the proxy instead.

The first service also sets one environment variable whose name says what it does: it disables TLS certificate verification for the Node process, and the value is zero.

Both of these are doing legitimate work for this project, and both of them are the kind of setting that changes what your deployment is. Certificate verification off means a TLS failure in that process will not stop it, so a man-in-the-middle or a misconfigured endpoint is invisible to it rather than fatal. Hostname aliases mean the application's notion of which server it is talking to is not the real one. Neither is wrong for a personal music client on a home network, and both are things to know about before putting the same compose file on a shared host.

The image build hard-codes three Chinese mirrors and two dated bases

The Dockerfile is where the project's geography shows.

The build stage is based on a Node 16 alpine image. Before installing anything it rewrites the Alpine package repositories to a university mirror, installs a C toolchain, copies the manifest and lockfile, and then sets the Electron download mirror and the package registry to a different mirror, and rewrites the registry host inside the lockfile with a text substitution before running the install. So the lockfile itself is modified as part of the build, which means the build is not installing the dependency set the lockfile describes.

The runtime stage is based on an older nginx alpine image, rewrites repositories again, installs a Node runtime and package manager, and then reads the manifest with a text-processing one-liner to extract the version of the API package and installs that version globally.

For an adopter this is the practical obstacle. The build succeeds only where those mirrors are reachable, and the two base images are old enough that they carry their own published issues. Both are the kind of thing a rebuild on another network turns into a wall of failed fetches, and the fix is editing the Dockerfile rather than anything the project documents.

The engine allows Node 14 or 16, and the desktop shell is Electron 13

Two version declarations in the manifest date the project precisely, and neither is current.

The engine field allows Node 14 or 16 and nothing else. The desktop runtime is Electron at version 13. Both of those lines ended support years ago, and both are in the same file that a build system reads first.

The build scripts around them are otherwise careful. Every packaging target passes a flag that disables publishing, so a local build cannot upload anything, and there is a separate target that does publish with publishing enabled. The post-install and post-uninstall hooks both call the packager's dependency installer, which is what makes a native module work after an install or a removal rather than only after a fresh clone.

What the versions cost is straightforward. An Electron major version that old will not have current security fixes, and a Node engine constraint that narrow will refuse to install on a modern runtime, so a container base or a CI image has to be pinned backwards to match. The native module in the dependency list, which is a Rust addon, is the reason the engine range is narrow rather than wide: it constrains what can be built against it.

Six ways to deploy, and one of them pipes a download into a shell

The README documents more installation routes than most projects of this size, and they have very different shapes.

For a hosted deployment the route is a fork, a small configuration file that rewrites the application's API path onto your own API host, and an import into a serverless host with one environment variable set. The project's own demonstration site runs on that host. For your own server it is a recursive clone, a dependency install, an optional Nginx reverse proxy at the API path with a warning that a cross-origin setup causes bugs, a copied environment file, a build, and uploading the output directory. Then there is a control panel route, a Docker route with both a single container and a compose file, a hosted development environment route, and a self-packaging route for the desktop builds.

Two of those deserve a second look. The clone command is recursive, because the project carries submodules. And the hosted development environment route instructs you to run a command that downloads a shell script and executes it in one line, plus a fallback command for when the build runs out of memory, with the memory limit of the free and education plans given in the note beside it.

Both are what the project documents, and both are worth reading as a security decision rather than as an installation step.

The web build keeps a local database and the desktop build carries a native module

Two dependencies explain a surprising amount of the repository's shape.

One is a wrapper around IndexedDB, the browser's local database, in the dependency list. So the web build does keep data client side, which is a cache and a queue rather than a system of record, and it means a browser install and a self-hosted install do not store things the same way.

The other is a native addon for the audio-source replacement feature, published as a native Node interface package. A native module is why the clone is recursive, why the container build installs a C toolchain and a Python interpreter before the dependency install, and why the engine field is pinned to two old Node versions rather than left open: native addons have to be compiled against the runtime, and an addon built for one major version will not load in another.

So the answer to why this project needs a compiler where a music player normally would not is in that one dependency. It is also the dependency most likely to break on a modern toolchain, and it is the first thing to check if a fresh install fails on a current machine.

Editorial conclusion

Use YesPlayMusic if you want a NetEase Cloud Music client on a desktop or self-hosted and you read the deployment section before you deploy rather than after. Do not build anything commercial on it without settling the licence question, because the manifest declares MIT while the readme restricts the project to personal study and prohibits commercial and illegal use, and the two statements are not the same. Before you run anything: read the compose file, which sets an environment variable that disables TLS certificate verification for the Node process and registers network aliases for the real music hostnames, and confirm the mirrors baked into the image build are reachable from where you are; and check the engine declaration, which allows only Node 14 or 16, both long past end of life.

Frequently asked questions

What is YesPlayMusic?

It is a third-party player for NetEase Cloud Music on Windows, macOS and Linux, built with Vue and packaged with Electron, with a web version that can be installed as a progressive web app. The manifest version is 0.4.10, a 2.0 alpha exists on the releases page, and the project states that the current line is in maintenance mode for major bug fixes only.

How do I install YesPlayMusic?

Download a build from the repository's releases page, or use Homebrew on macOS with `brew install --cask yesplaymusic`, or Scoop on Windows with `scoop install extras/yesplaymusic`. The README states the Electron version is adapted and maintained by two named maintainers for macOS, Windows and Linux.

Can YesPlayMusic play tracks that are unavailable, including from outside China?

The feature list says overseas users can play directly provided they are logged in to a NetEase account, and that the app supports an audio-source replacement proxy which automatically replaces links to unavailable tracks. It notes the web version does not support that, that the enabled sources are the default ones, and that the YouTube source requires yt-dlp to be installed separately.

What Node version does YesPlayMusic need?

The manifest declares an engine of Node 14 or 16, and the container build is based on a Node 16 alpine image, so both of those lines are past end of life. The local development server port is set in the example environment file, and the desktop build carries a native module, which is what keeps the engine range narrow.

How do I run the NetEase API that YesPlayMusic needs?

The README says the API comes from a separate project. Locally the project starts it on its default port, or you deploy it separately and point the application at it with one environment variable, or reverse-proxy it at the API path with Nginx, with a note that a cross-origin setup causes some bugs. The Vercel route rewrites the API path to your own host instead.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/qier222-yesplaymusic.svg)](https://hysenlabs.com/projects/qier222-yesplaymusic)