mStream: a self-hosted music server that also downloads and seeds
The easiest music streaming server available. Save music from youtube to wherever you want in your filesystem mStream can manage your torrents for you.
At a glance
- What is it?
- mStream is a GPL-3.0 Node.js music streaming server with torrent, YT-DLP, DLNA and federation features built in. It is quick to start and hard to expose safely, and the docs leave several things to figure out.
- Who is it for?
- Adopt mStream if you want a single Node.js process that serves your library to a browser and a phone, and you are willing to run it behind a VPN or a reverse proxy rather than expose it. Do not adopt it if you need a documented permission model before you trust it with a shared or public instance, or if you expect the README to tell you how to roll back a release.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 25, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What mStream is for, and who ends up running it
mStream is a music streaming server written in JavaScript. The README calls it "the easiest music streaming sever" (the typo is theirs) and the pitch is that you point it at a folder of music and get a web player plus mobile apps. What separates it from a plain file server is the surrounding tooling: a torrent client integration, YT-DLP integration for pulling YouTube audio into your filesystem, DLNA support, transcoding, automatic backup to any connected drive, lyrics with search-by-lyrics, an Auto DJ queue, jukebox mode for controlling a browser remotely, and local server audio playback. The last one is explicitly noted as not working on Docker, which tells you the project expects people to run it on the same machine as their speakers.
The audience is the person who already has a music folder and wants one process to serve it, rather than a person building a media platform for a household. The public mode default reinforces that: the demo site needs no sign-in because mStream is publicly accessible by default, and the README frames this as convenient for a secured network. Once you add a user, the system becomes password protected. That single sentence is the whole access control story as far as the README is concerned, and it is the first thing I would want more detail on before putting this on a VPS.
How the server actually works: scanners, caches and federation
The repository layout shows a Node.js application with a Rust component. rust-parser/ and rust-launcher/ sit alongside src/ and webapp/, and package.json exposes build-rust as cd rust-parser && cargo build --release. The credits explain the split: Lofty is the audio tag reader powering the Rust scanner, music-metadata is "the metadata parser used by the JS scanner fallback", and Symphonia is a pure-Rust decoder used to render waveform previews during a scan. So scanning is not one code path. There is a Rust scanner and a JavaScript fallback, and if you build from source without running the Rust build, you are on the fallback.
Two top-level directories, image-cache/ and waveform-cache/, are the on-disk result of that work: album art that mStream retrieves automatically, and waveform previews rendered during scans. That is the data flow. Files on disk get parsed for tags, artwork is fetched and cached, waveforms are generated, and the results feed the web player and the API.
Federation and P2P discovery are the unusual part. When discovery is enabled, the server downloads music discovery data from other mStream servers and uses it to surface songs that are not in your collection but are similar to what you are playing. The README is careful here: "this is discovery only. You will have to find these songs on your own." Federation changes that by giving federated servers read access to each other's data, at which point discovery can stream the discovered music instead of just naming it. Read access is the documented scope; the README does not describe a write path between federated servers.
Quick Sync is the third networking idea. Enabling it in the admin panel lets you reach mStream without port forwarding, DNS or SSL, and the README describes it as a free VPN-like service powered by Iroh. The constraint is stated plainly: it only works for the mobile apps and the upcoming desktop app, and the webapp will not work, which the README calls "the price of not having to setup DNS/SSL".
Installing mStream and getting a library scanned
The README points at three install routes: platform binaries from the releases page, a Docker image maintained by LinuxServer.io, and install-from-source via docs/install.md. There is also install.sh and install.ps1 at the repository root and a Terraform option for AWS. As of v6.20 the README says releases ship one standalone bundle per platform with no Electron, so the desktop face is a double-clickable binary rather than an Electron shell.
From source, the package requires Node 22.5.0 or newer. The package.json defines a wizard script that installs production dependencies and boots the server in one step.
npm run wizardThe same file defines start as node cli-boot-wrapper.js, and the bin entry maps the mstream command to that same wrapper, so a global install gives you an mstream executable. If you want the Rust scanner rather than the JavaScript fallback, build it before starting:
npm run build-rust
npm startDocker users should follow the LinuxServer.io instructions rather than the source steps. One thing to note before you choose: local server audio playback, the feature that plays through the server's own speakers, will not work on Docker, so a container install and a bare-metal install are not equivalent for that use case.
Once the server is up, the README's install docs and the admin panel are where library configuration lives; the README itself does not print a config file example, so treat docs/install.md as the source of truth. The first real use is the same in every install flavor: add a user, which flips the instance from public to password protected, then point it at your music and let the scan populate the image cache.
The access model is the weakest documented part
Public by default is a deliberate design choice, and for a machine on a home LAN it is defensible. The problem is the gap between that default and the moment you decide to expose the server. The README says adding a user makes the system password protected. It does not describe roles, per-user library scoping, share links, rate limiting or session handling, and there is no mention of what a user can reach through the API once authenticated. The repository does carry docs/openapi.yaml with redocly lint and build scripts in package.json, so an API specification exists, but an OpenAPI file describes endpoints, not the authorization rules behind them.
Federation compounds this. Federated servers have read access to each other's data. If you federate, you are trusting another operator's instance with read access to yours, and the README does not document how to revoke that or what read access covers in practice. Similarly, Quick Sync routes mobile traffic through a third-party service. It is free and it removes a real amount of setup work, but it is a relay you do not control, and the webapp exclusion means your browser access still needs its own path.
The honest summary: mStream is easy to start and under-documented at the point where difficulty begins. If you need a permission model you can reason about before deployment, this is the wrong tool today.
Where mStream stops being the right choice
Three concrete cases. First, a multi-user household where different people should see different libraries. Nothing in the README describes per-user library scoping, so you would be guessing. Second, a public-facing instance. Public mode plus a password toggle is not a security posture, and the README does not claim otherwise; it recommends public mode for a secured network. Third, anything that depends on local audio playback inside a container, which the README rules out for Docker.
There is also an operational failure mode worth naming. The scanner has two implementations, Rust and JavaScript, and the credits describe the JS one as a fallback. If a source build skips the Rust step, scanning behavior can differ from a release binary. The README does not document how to tell which scanner ran, so a slow or incomplete scan is hard to diagnose from the documentation alone. The same silence applies to upgrades: the repository has a CHANGELOG.md and releases are frequent, with v6.24.0, v6.23.0 and v6.22.0 all landing in August 2026, but the README does not document rollback. Back up your database and your caches before you move versions.
mStream against Navidrome and Plex, and how to pick
The obvious alternative for a self-hosted library is Navidrome, which is built around the Subsonic API. That difference matters more than any feature list. Navidrome's model is a music server that speaks a protocol many third-party clients already implement, so you choose your client separately. mStream ships its own web app and its own official mobile apps, with source at IrosTheBeggar/mstream_music, plus third-party apps from Niera Tech. You get a more integrated experience and less client choice.
Plex and Jellyfin sit further away. They are media platforms that handle video, users, and remote access as first-class concerns. mStream does not attempt that. What it has instead is the torrent client integration, the YT-DLP integration, and the discovery and federation features, which are about acquiring and finding music rather than about streaming a household's media. If your problem is "I keep downloading music and want the server to manage that too", mStream is aimed at you in a way the media platforms are not. If your problem is "I want a polished multi-user media server", it is not.
The practical test is whether you already have a client you like. If you do, and it speaks Subsonic, mStream's own apps are a cost rather than a benefit.
Licence, maintenance and upgrade cost
mStream is GPL-3.0. That is a copyleft licence, and the practical consequence for most readers is that if you modify mStream and distribute it, you are expected to publish your changes under the same terms. Running it on your own server for yourself is not distribution. If you plan to fork it into a product, or to ship a modified server to customers, read the licence text in LICENSE and get proper advice; this is not legal advice and the GPL has real obligations attached to distribution. The mobile apps are described as open source in the README, but they are a separate repository, and the README does not state their licence.
Maintenance looks current rather than dormant. The repository is not archived, the last push was on 2026-08-26, and the release cadence in August 2026 was three versions in a week. The package.json version is 6.27.0 while the newest listed release is v6.24.0, which suggests the repository tracks ahead of tagged releases, so a source build is not the same artifact as a release binary.
Upgrade cost is low in the normal case and uncertain in the awkward case. There is a CHANGELOG.md to read before you move, and the Docker path is maintained by a separate group, so the image and the binary releases do not necessarily move together. Nothing in the README documents a downgrade path, and the caches under image-cache/ and waveform-cache/ are regenerable, so the thing worth backing up is whatever holds your library and user data.
Editorial conclusion
Adopt mStream if you want a single Node.js process that serves your library to a browser and a phone, and you are willing to run it behind a VPN or a reverse proxy rather than expose it. Do not adopt it if you need a documented permission model before you trust it with a shared or public instance, or if you expect the README to tell you how to roll back a release. Verify two things first: whether the bundled Rust parser or the JavaScript fallback is doing your scanning, and whether Quick Sync is acceptable for your mobile clients given that the webapp is excluded from it.
Frequently asked questions
What is mStream?
mStream is a self-hosted music streaming server written in JavaScript and licensed GPL-3.0. Beyond streaming, it includes torrent client integration, YT-DLP downloading, DLNA support, transcoding, automatic backup and lyrics with search-by-lyrics.
What is an alternative to mStream?
Navidrome is the closest alternative for a self-hosted library, and the difference is the client model: Navidrome is built around the Subsonic API, so you pick a third-party client, while mStream ships its own web app and official mobile apps. Plex and Jellyfin handle video and multi-user access as first-class concerns, which mStream does not attempt.
How do I set up mStream?
You can use the platform binaries from the releases page, the Docker image maintained by LinuxServer.io, or install from source following docs/install.md. From source, package.json requires Node 22.5.0 or newer and provides an npm run wizard script that installs production dependencies and boots the server.
Does mStream need a password?
Not by default. The README states that mStream is publicly accessible by default, which is why the demo site requires no sign-in, and that once you add a user the system becomes password protected. The README recommends public mode only for a secured network.
Does mStream work on Windows, macOS and Linux?
The README lists binaries for Windows, macOS and Linux, and states that as of v6.20 releases ship one standalone bundle per platform with no Electron. The desktop face is mStream.exe on Windows, mStream.app on macOS and mstream-desktop on Linux, and the linux-arm64 and musl bundles contain only the headless mstream-server.
Does mStream work on Docker?
Yes, through the Docker image maintained by LinuxServer.io, and the README links to those instructions. One documented exception is local server audio playback, which the README says will not work on Docker.
Official sources
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.
[](https://hysenlabs.com/projects/irosthebeggar-mstream)