# go-musicfox: a NetEase Cloud Music client for the terminal

> go-musicfox is a Go TUI client for NetEase Cloud Music with UnblockNeteaseMusic, Last.fm scrobbling, MPRIS and DLNA support. It suits Linux and macOS users who already live in a terminal and have a NetEase account, and it needs a real terminal emulator rather than the macOS default or Windows CMD.

**go-musicfox/go-musicfox** — go-musicfox是用Go写的又一款网易云音乐命令行客户端，支持UnblockNeteaseMusic、各种音质级别、lastfm、MPRIS、MacOS交互响应（睡眠暂停、蓝牙耳机连接断开响应、菜单栏控制等）...

- Repository: https://github.com/go-musicfox/go-musicfox
- Website: https://musicfox.anhoder.com
- Stars: 2,572 · Forks: 161
- Language: Go
- License: GPL-3.0
- Published: 2026-09-28 · Updated: 2026-09-28 · Language: en
- Canonical page: https://hysenlabs.com/projects/go-musicfox-go-musicfox

## What go-musicfox replaces, and for whom

The README describes go-musicfox as "yet another" NetEase Cloud Music command line client written in Go, which is a fair summary of a crowded niche. The problem it addresses is narrow: NetEase Cloud Music has no official Linux client, and the desktop clients it does ship are not usable over SSH, in a tmux pane, or on a machine where you would rather not run an Electron stack. go-musicfox puts the catalogue, playlists and playback controls into a TUI built on the Charm stack (bubbletea, bubbles and lipgloss are all direct dependencies in go.mod), so the whole client is a single terminal program.

The audience is correspondingly specific. You need a NetEase Cloud Music account, a terminal emulator that handles the rendering correctly, and enough comfort with config files to tune the defaults. The README is explicit that macOS Terminal.app and Windows CMD are not supported (issue #99), and it recommends iTerm2 or Kitty on macOS, Kitty on Linux, and Windows Terminal on Windows. If your daily driver is one of those, the client is aimed at you. If it is not, the first thing you will notice is the rendering, not the music.

The feature list beyond playback is where the project differentiates itself from a plain API wrapper: UnblockNeteaseMusic support, multiple audio quality levels, Last.fm scrobbling, MPRIS, DLNA casting, and macOS-specific behaviour such as pausing on sleep, reacting to Bluetooth headphone disconnects, and menu bar controls.

## How the TUI, playback engine and integrations fit together

The repository layout tells you most of the architecture. cmd/ holds the entry point, internal/ holds the application, configs/ holds configuration, external/ holds vendored or bundled non-Go pieces, and vendor/ is committed, so builds do not need network access for dependencies once the module tree is present. The UI layer is bubbletea v2 with bubbles and lipgloss, which means the interface is a message-driven model rather than a hand-rolled render loop.

The music data itself comes from github.com/go-musicfox/netease-music, a separate module by the same organisation. go-musicfox is therefore the client shell, not the API layer. That split matters when you are debugging: a change in how NetEase responds shows up in the netease-music module, not in the TUI code.

Playback is not one engine. The dependency list includes gopxl/beep, fhs/gompd for MPD, and the Termux note in the README tells Android users to switch to the MPD engine if playback stutters. So there is a built-in engine and an MPD-backed engine, and the choice is a configuration decision rather than a build-time one. Metadata handling is separate again: bogem/id3v2, frolovo22/tag and go-flac/flacpicture cover ID3 and FLAC tag writing and cover art, which is why libFLAC appears as a system dependency.

Desktop integration is handled per platform rather than through one abstraction. godbus/dbus provides MPRIS on Linux, go-ole and winrt-go handle Windows, and the macOS behaviour relies on native hooks. Last.fm scrobbling goes through shkh/lastfm-go, and the Makefile shows LASTFM_KEY and LASTFM_SECRET as build-time variables, which implies a self-built binary needs its own Last.fm API credentials if you want scrobbling to work.

## Installing go-musicfox and playing a first track

The README lists distribution packages as the recommended route on Linux. On Arch, the AUR has both a source build and a prebuilt binary:

```bash
paru -S go-musicfox-bin
```

After installation the command is musicfox. The README's entire usage section is that one word:

```bash
musicfox
```

On first run you log in to NetEase Cloud Music. The dependency list includes mdp/qrterminal and skip2/go-qrcode, so a QR code login flow is part of the client; the README does not spell out the exact keystrokes, so expect to follow prompts on screen rather than a documented sequence.

If you prefer Homebrew on macOS or Linux, the tap is installed with the fully qualified formula name:

```bash
brew install anhoder/go-musicfox/go-musicfox
```

Adding --head builds from master instead of the released tag. The README notes that if you previously had a formula called musicfox installed, you need to relink:

```bash
brew unlink musicfox && brew link --overwrite go-musicfox
```

On Windows the route is scoop, with the bucket added from the repository URL before the package:

```bash
scoop bucket add go-musicfox https://github.com/go-musicfox/go-musicfox.git
scoop install go-musicfox
```

Building from source needs Go 1.22 or newer according to the README, though go.mod currently declares go 1.26. On Linux you also need the libFLAC development package, installed as libflac-dev on Debian and Ubuntu, flac on Arch, and flac-devel on Fedora. The build itself is a make invocation:

```bash
git clone https://github.com/go-musicfox/go-musicfox
go mod download
make
```

The Makefile builds into bin/ and make install copies the binary to $GOPATH/bin. The default build target passes the enable_global_hotkey and purego build tags, so a plain go build will not reproduce the shipped binary exactly.

## Terminal rendering, libFLAC and the configuration you will actually edit

Two of the three warnings in the README's notes section are about rendering, and both are configuration fixes rather than bugs. If the layout looks wrong, the cause is the double-column display, and the README says to use a monospaced font or set doubleColumn to false. If the interface reacts to input you did not intend, such as moving the cursor or skipping tracks, the cause is mouse event handling, and the fix is enableMouseEvent set to false. Neither is documented with a full config example, so you will be editing the config file the application creates rather than copying a snippet from the README.

The third failure mode is a hard one. A prebuilt Linux binary links against libFLAC.so.8, and on distributions such as Ubuntu 23.10 the installed library is libFLAC.so.12. The README gives the exact error text, a dynamic linker message about libFLAC.so.8 being missing, and one workaround: symlink the installed library to the name the binary expects.

```bash
ln -s /xxx/libFLAC.so /xxx/libFLAC.so.8
```

The README truncates the alternatives at that point, so if you are uncomfortable symlinking a system library, building from source against your distribution's libFLAC is the safer path. This is the clearest case where the project's packaging and the host system disagree, and it is worth checking before you file a bug.

The README also does not document rollback, config migration between major versions, or what happens to a cached library when you change accounts. There is a BACKWARD_COMPATIBILITY.md at the repository root, which suggests compatibility is treated as a documented concern, but the README itself does not link to its contents.

## Where go-musicfox is the wrong choice

The dependency on NetEase Cloud Music is the boundary. Everything the client plays comes from that service, and login goes through it. If your library lives on a self-hosted server, in local files, or on another streaming platform, go-musicfox has nothing to offer you, and the UnblockNeteaseMusic integration does not change that: it affects how NetEase responds to requests, not where the catalogue comes from.

The terminal requirement is a real constraint, not a preference. The README states plainly that macOS Terminal.app and Windows CMD are not handled, and points to issue #99 for the reasoning. On a locked-down machine where you cannot install Kitty, iTerm2 or Windows Terminal, you are outside the supported environment.

There is also a platform asymmetry. The macOS feature set (sleep pause, Bluetooth disconnect handling, menu bar control) has no Linux equivalent described in the README. Linux gets MPRIS and DLNA instead. If you picked go-musicfox for the macOS interaction features and then moved to Linux, you would be running a different product.

Finally, the licensing is GPL-3.0. That is fine for personal use and for distributions, and it is already how the AUR, Copr, Flatpak and Nixpkgs packages ship it. It is a consideration only if you intend to reuse the code inside a proprietary product, and that is a question for a lawyer rather than for this article.

## YesPlayMusic and other NetEase clients: the difference in approach

YesPlayMusic appears in the related searches, and the comparison is instructive because the two projects solve the same problem in opposite directions. YesPlayMusic is an Electron desktop application: it renders a graphical interface, uses the web stack, and consumes far more memory and disk than a terminal program. go-musicfox is a TUI: no window, no bundled browser engine, and it runs in an SSH session or a tmux pane. If you want album art in a window and a familiar mouse-driven interface, the Electron approach is what you want. If you want to control playback from the same shell where you are working, it is not.

The same split applies against musicbox-style Python clients, which go-musicfox is explicitly positioned against in its own name (netease-musicbox is a topic on the repository). The Go implementation compiles to a single binary, which removes the Python runtime and virtualenv from the deployment story. That is the practical difference: not features, but what you have to install to get them.

Against a plain MPD setup, go-musicfox is an opinionated client rather than a protocol. MPD gives you a server and lets any client connect. go-musicfox gives you a NetEase client that can optionally play through MPD. If interoperability across many clients matters more than NetEase integration, MPD alone is the better foundation.

## Maintenance, releases and what upgrading costs

The repository is not archived, and the last push was on 2026-09-07. The most recent release listed is v5.1.0 on 2026-08-10, following v5.0.2 and v5.0.1 earlier in August. That is a tight release cadence, and it means the version you install from a distribution package may lag the tag by weeks, especially on Debian-family systems where the README itself warns that the Spark store sync is slow.

The upgrade cost depends on how you installed it. Distribution packages, Flatpak and scoop upgrade through their own tooling. The Homebrew formula follows the tap. A source build means re-running make after a pull, and the Makefile's LDFLAGS inject a version from github.com/go-musicfox/go-musicfox/internal/types, so the binary reports its own version and you can check what you are running.

The licence is GPL-3.0, stated in the LICENSE file at the repository root and in the GitHub licence badge. For end users this changes nothing. For anyone redistributing a modified binary, the GPL's source-availability terms apply to the whole derived work. The repository also carries a BACKWARD_COMPATIBILITY.md and a CHANGELOG.md, which is where you should look before a major version jump, since the README does not describe a migration path.

## Conclusion

Adopt go-musicfox if you have a NetEase Cloud Music account, work on Linux or macOS in Kitty, iTerm2 or Windows Terminal, and want playback, scrobbling and MPRIS control without leaving the shell. Skip it if you rely on the macOS Terminal.app or Windows CMD, or if you have no NetEase account, since login and playback both depend on that service. Before committing, verify that your system provides libFLAC.so.8, check whether your distribution ships a package, and read the configuration file to set doubleColumn and enableMouseEvent for your terminal.

## FAQ

### How do I install go-musicfox on Linux?

The README recommends a distribution package: paru -S go-musicfox-bin or paru -S go-musicfox on Arch, sudo dnf copr enable poesty/go-musicfox then sudo dnf install go-musicfox on Fedora, or the Spark store on Debian-family systems. Homebrew and Flatpak are also listed, and prebuilt binaries are on the Releases page.

### Which terminal emulator does go-musicfox require?

The README states that macOS Terminal.app and Windows CMD are not supported, and recommends iTerm2 or Kitty on macOS, Kitty on Linux, and Windows Terminal on Windows. It also warns that you should use a monospaced font or set doubleColumn to false to avoid layout problems.

### Why does go-musicfox fail to start with a libFLAC.so.8 error?

The README explains that this means the system does not contain libFLAC.so.8, which happens on distributions such as Ubuntu 23.10 where libFLAC.so.12 has replaced it. The documented workaround is to symlink the installed library to the expected name.

## Sources

- [go-musicfox/go-musicfox on GitHub](https://github.com/go-musicfox/go-musicfox)
- [License: GPL-3.0](https://github.com/go-musicfox/go-musicfox/blob/master/LICENSE)
- [Project website](https://musicfox.anhoder.com)
- [README](https://github.com/go-musicfox/go-musicfox/blob/master/README.md)
- [Releases](https://github.com/go-musicfox/go-musicfox/releases)

---

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