MCPcopy Index your code
hub / github.com/Moekotori/ECHO

github.com/Moekotori/ECHO @26.7.1

Chat with this repo
repository ↗ · DeepWiki ↗ · release 26.7.1 ↗ · + Follow
12,186 symbols 39,801 edges 882 files 83 documented · 1%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

ECHO NEXT

ECHO NEXT

A source-available desktop music player for local libraries, HiFi output, and long-term maintainability.

Chinese README  |  Official Site  |  Latest Release  |  QQ Group  |  Discord  |  Quick Start  |  User Guide  |  Plugin Authoring  |  Linux Build Guide  |  Development

Version GitHub stars GitHub downloads Electron 42 React 18.2 TypeScript 5 Platform

ECHO NEXT interface preview


What ECHO NEXT Is

ECHO NEXT is the next-generation desktop music player in the ECHO family. It is not a simple reskin of the previous app. It rebuilds the project around local library management, stable playback, native audio output, lyrics, MV, remote sources, plugins, and clearer Electron architecture boundaries.

The priorities are intentionally strict: reliable local playback, stable audio behavior, responsive large-library browsing, user data safety, and network features that extend the player without turning it into a thin online-platform shell.

[!IMPORTANT] ECHO NEXT is still a local music player at its core. When reporting issues, please include reproducible steps, system information, app version, screenshots, logs, and the exact path you took in the app. Requests to bypass memberships, copyright restrictions, platform restrictions, or DRM are not accepted.

Who It Is For

If you want to ECHO NEXT focuses on
Manage your own music files Folder scanning, SQLite library storage, metadata reading, cover caching, album grouping
Tune serious output on Windows System output, WASAPI, ASIO, EQ, sample-rate status, bit-perfect hints
Keep a large library usable Virtualized lists, paged loading, cover caches, and bounded background work
Control lyrics, MV, covers, and metadata Local-first data, manual selection, source priorities, and local cache boundaries
Extend the app without breaking playback Plugins, remote libraries, downloaders, streaming helpers, and network metadata behind controlled boundaries

Core Features

Local library Folder imports, songs, albums, artists, inbox, liked tracks, history, playlists, duplicate filtering, and tag editing. Stable playback Playback queue, bottom player, system media controls, output-device state, playback diagnostics, error reporting, and recovery boundaries. HiFi output WASAPI Shared, WASAPI Exclusive, ASIO, EQ, preamp, ReplayGain, sample-rate status, and bit-perfect hints.
Lyrics and MV Local lyrics, online candidates, translation, romanization, Japanese kana enhancement, lyric offset, MV matching, quality selection, and external-playback boundaries. Network extensions WebDAV, Jellyfin, Emby, SMB, SSHFS, Subsonic, streaming search, downloaders, network proxy settings, and remote background tasks. Maintenance and diagnostics Plugin permissions, logs, crash recovery, library health, cache migration, settings backup, and dangerous-operation confirmation.

Quick Start

Download a release

Most users should start from GitHub Releases. Windows users usually want the installer or portable build. Linux users can use the AppImage or deb package when those artifacts are available for a release.

On first launch, import a small folder first and confirm that scanning, covers, playback, and lyrics work as expected. Import your full library after that initial check.

Recommended first run

Step Action
1 Import a small local music folder
2 Check Songs, Albums, and Inbox for tracks, covers, and album grouping
3 Try playback, liking, queue actions, playlists, and context menus
4 Adjust lyrics, MV, EQ, output device, and appearance
5 Enable remote sources, streaming, downloads, or plugins only when needed

The detailed user guide is currently in Chinese: docs/USER_GUIDE.md.

Page Guide

Page Purpose
Songs Full-library browsing, search, sort, multi-select, tag editing, duplicate filtering
Albums Album wall, album details, whole-album playback, cover and tag cleanup
Artists Browse tracks and albums by artist
Folders Manage local import folders and scan state
Inbox Review newly scanned tracks
Queue Manage the temporary playback order
Liked Keep quick access to favorite tracks
History Recover recently played music
Playlists Manage long-lived playlists
Lyrics Immersive lyrics and playback view
Streaming Search, preview, and discover online candidates
Downloads URL downloads, search downloads, and library import
Cloud / Remote Remote sources and remote library indexing
Connect Local-network playback features such as DLNA and AirPlay
Plugins Local plugins, permissions, logs, import, and export
Settings Playback, lyrics, MV, EQ, appearance, library, integrations, diagnostics, and dangerous operations

ECHO NEXT vs ECHO

ECHO is the earlier full-featured player. It focuses on putting local playback, lyrics, MV, downloads, plugins, casting, and shared-listening features into one desktop app.

ECHO NEXT is a deeper rebuild. It separates the library, audio engine, renderer, preload bridge, main process, native hosts, and system integrations so the project can keep growing without piling more risk onto old code paths.

For users, the goal is a more stable large-library experience, clearer HiFi output state, safer settings and data handling, and feature boundaries that are easier to maintain over time.

Development And Builds

Recommended environment:

Dependency Recommended version
Node.js 20 LTS
npm 9 or newer
Windows build tools Visual Studio 2022 Desktop development with C++
Linux build tools CMake, g++, pkg-config, fakeroot, dpkg, rpm, binutils, and audio-related system dependencies
git clone https://github.com/moekotori/echo.git
cd echo
npm install
npm run dev

If you also need to build the audio host and Windows SMTC host before launching development mode:

npm run dev:full

Common commands:

Command Purpose
npm run dev Start the Electron + Vite development environment
npm run dev:full Build the audio host and SMTC host, then start development mode
npm run typecheck Run TypeScript type checking
npm run test Run Vitest tests
npm run build Typecheck and build main, preload, and renderer output
npm run build:win Build Windows installer and portable artifacts
npm run build:linux Build Linux packages on a Linux x64 environment
npm run verify:ffmpeg Verify the FFmpeg toolchain
npm run smoke:audio-host Smoke-test the audio host
npm run smoke:smtc-host Smoke-test the Windows SMTC host

Markdown-only documentation changes usually need only content review and a diff check. Playback, database, scanning, native audio host, SMTC, and packaging changes should be validated with focused checks for the touched area.

Nix / Flake Development And Builds

The project provides a Nix flake with a dev shell, build derivation, and nixpkgs overlay:

Command Purpose
nix develop Enter the dev shell (Node 22 + CMake + ALSA + GTK3 + Electron + etc.)
nix build Build ECHO NEXT (uses system Electron, result in result/)
nix run Run the built application directly
nix flake check Verify all flake outputs

Using the overlay in your nixpkgs configuration:

{
  inputs.echo-next.url = "github:moekotori/echo";

  outputs = { self, nixpkgs, echo-next, ... }: {
    nixosConfigurations.my-machine = nixpkgs.lib.nixosSystem {
      modules = [
        ({ pkgs, ... }: {
          nixpkgs.overlays = [ echo-next.overlays.default ];
          environment.systemPackages = [ pkgs.echo-next ];
        })
      ];
    };
  };
}

Or run directly:

nix run github:moekotori/echo

direnv users can run direnv allow to automatically load the development environment.

[!IMPORTANT] nix run produces a fully functional desktop app on Linux x86_64, including the library SQLite, image thumbnails, IPC, playback queue and Wayland UI. See "Coverage" below.

Coverage

Capability Status Notes
Electron main + renderer Uses nixpkgs electron_42
better-sqlite3 (library, history) buildPhase rebuilds it offline against electron.headers
sharp (cover thumbnails) musl variant is removed so RPATH is not mis-bound
Wayland / XDG data dirs See the "Data Directories" section
Pro features (Connect / AirPlay / cloud sync) ⛔ refused Public stubs force license-check to false; business logic auto-falls back to the "locked" branch
native/audio-host (JUCE HiFi/ASIO/DSD) ⛔ missing cmake FetchContent pulls JUCE 8.0.12 over the network; UI falls back to HTML Audio
native-scanner ⛔ missing Same reason; pure-JS scanner is used as a fallback
Windows / macOS ⛔ unsupported nixpkgs has no MSVC/WinRT; a macOS branch can be added later following Joplin's pattern

Running

LICENSE is source-available, not OSS, so meta.license = lib.licenses.unfree and you must explicitly allow it:

# Ad-hoc
NIXPKGS_ALLOW_UNFREE=1 nix run --impure .#echo-next

# Or pin it in your NixOS config
nixpkgs.config.allowUnfreePredicate = pkg:
  builtins.elem (lib.getName pkg) [ "echo-next" ];

Maintenance notes

  • Updating npmDepsHash: after touching package-lock.json, set npmDepsHash back to lib.fakeHash in package.nix, run nix build .#echo-next once, then copy the got: sha256-… value from the error back into the file.
  • npm_config_nodedir must be unset: npmConfigHook injects the Node 22 source headers into the env, which overrides any --nodedir CLI flag. When rebuilding better-sqlite3 you must env -u npm_config_nodedir node-gyp …, otherwise it links against nodejs instead of electron's V8 14 and throws undefined symbol: v8::HandleScope::HandleScope(v8::Isolate*) at runtime.
  • Do not drop --ignore-scripts: postinstall runs ensure-native-abi.mjs, which invokes @electron/rebuild and downloads electron headers, which the sandbox forbids. The buildPhase replaces it with an explicit offline node-gyp rebuild --nodedir=${electron.headers}, which is also faster and more deterministic.
  • The sharp musl variant must be deleted: autoPatchelfHook would otherwise bind sharp-linux-x64.node's libvips RPATH to sharp-libvips-linuxmusl-x64, causing ERR_DLOPEN_FAILED: libc.musl-x86_64.so.1 at runtime. The rm -rf node_modules/@img/sharp-linuxmusl-x64{,-libvips} line in buildPhase is not optional.
  • The public repo ships stubs: src/main/plugins/{MachineIdentity,EchoProLicensePlugin}.ts are public stubs (see the two ! whitelist lines in .gitignore); nix build and npm run typecheck succeed without the private overlay. Run npm run pro:pull to fetch the ECHOPrivate sibling repo when you need the real Pro features — its files override the stubs at the same paths.

Expected runtime warnings (not bugs)

After nix run you will see the following messages; all expected:

  • [DiscordPresence] RPC initialization failed { error: 'Could not connect' } — Discord IPC socket is unreachable when Discord is not running.
  • wayland_wp_color_manager.cc … Unable to set image transfer function — Chromium's own warning when the compositor lacks the wp_color_manager protocol; rendering is unaffected.
  • Error occurred in handler for 'connect:*': Error: echo_pro_required — Pro stubs route Connect / AirPlay calls into the "locked" branch; expected for the public build.

Data Directories (XDG Base Directory)

On Linux, ECHO

Extension points exported contracts — how you extend this code

RemoteSourceAdapter (Interface)
(no doc) [10 implementers]
src/main/library/remote/remoteTypes.ts
Window (Interface)
(no doc)
src/renderer/main.tsx
Window (Interface)
(no doc)
src/preload/apiTypes.ts
NetworkMetadataProvider (Interface)
(no doc) [7 implementers]
src/main/library/network/NetworkMetadataProvider.ts
Window (Interface)
(no doc)
src/renderer/i18n/I18nProvider.tsx
FileScanner (Interface)
(no doc) [23 implementers]
src/main/library/workers/FileScanner.ts
Window (Interface)
(no doc)
src/renderer/integrations/spotify/spotifyPlayback.ts
MetadataReader (Interface)
(no doc) [21 implementers]
src/main/library/workers/MetadataReader.ts

Core symbols most depended-on inside this repo

push
called by 1355
native/audio-host/src/main.cpp
get
called by 814
src/main/streaming/StreamingMemoryCache.ts
has
called by 652
src/main/streaming/StreamingProviderRegistry.ts
set
called by 618
src/main/streaming/StreamingMemoryCache.ts
resolve
called by 493
src/main/mv/OnlineMvProviders.ts
getStatus
called by 414
src/main/integrations/discord/DiscordPresenceService.ts
normalizeSettings
called by 381
src/main/app/appSettings.ts
dispatchEvent
called by 345
src/main/plugins/PluginService.ts

Shape

Function 8,218
Method 3,321
Class 622
Interface 13
Enum 12

Languages

TypeScript92%
C++8%

Modules by API surface

src/main/library/LibraryStore.ts322 symbols
src/main/audio/AudioSession.ts272 symbols
src/renderer/pages/SettingsPage.tsx267 symbols
src/main/library/LibraryService.ts226 symbols
src/main/connect/AirPlayReceiverSpikeService.ts221 symbols
native/audio-host/src/main.cpp213 symbols
src/main/downloads/DownloadService.ts136 symbols
src/main/app/dataProtection.ts121 symbols
src/main/audio/AudioCore.test.ts117 symbols
src/main/mv/MvService.ts112 symbols
src/main/plugins/PluginService.ts102 symbols
src/renderer/pages/LyricsPage.tsx101 symbols

For agents

$ claude mcp add ECHO \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact