All apps
Featured

Spotish

huacnlee

An unofficial native Spotify client for macOS, Windows, Linux and the terminal. A Rust engine drives Spotify's own web player in a hidden browser; a native NSH interface draws it, with music-reactive shaders, layered animation and live Omarchy themes.

macOS / Linux / Windows · ★ 37 GitHub Stars

Spotish

Spotish is an unofficial, native desktop client for Spotify, built with Native Shell to put NSH's animation and rendering through an extreme test on a real, non-trivial app. Spotify's web player is as sluggish as an Electron app; Spotish keeps that player out of sight and draws a fast native interface over it. It runs on macOS, Windows and Linux, follows the Omarchy theme live, and also runs in the terminal.

Your Spotify account, free or Premium, does the playing, so the catalogue, your library, Spotify's ads and Premium all work exactly as Spotify intends. Spotish never blocks, skips, mutes or shortens an ad. It is not affiliated with, endorsed by or sponsored by Spotify; Spotify is a trademark of Spotify AB.

Home, with the library in the sidebar and the floating player bar

Features

The full-screen Now Playing view

How it works

Spotish is one Rust engine and one TSX interface, rendered through each platform's native views by NSH.

The engine (Rust). Widevine, the DRM that decodes Spotify's audio, comes only with a real desktop browser. So the engine finds an installed Chromium-family browser (Chrome, Chromium, Edge or Brave), starts it headless with a profile of Spotish's own, loads Spotify's web player and drives it over the Chrome DevTools Protocol. On macOS and Linux it talks through the browser's debugging pipe, so no port is opened at all; on Windows through a loopback WebSocket that web pages cannot reach. Signing in opens the same browser in a window. The engine copies an existing browser's Widevine component into its profile when it needs one, can import a login from an existing browser profile once (copying its cookie database consistently with SQLite's backup API), recovers when the browser exits, and exposes everything to TSX as a typed class: the player's state through listeners, data through async methods, and controls as methods.

The bridge (JavaScript in the web player). A script installed in the player's page before its own scripts run learns what the player itself uses to talk to Spotify, the headers of its GraphQL requests and the hashes of its persisted queries, so the app can ask for the same home page, searches, playlists, albums, artists and library. It reports the player's state, presses the player's own controls, and refuses seeking and skipping while an ad plays. Every page selector lives in this one file, it speaks a versioned protocol, and a newer bridge can ship in an over-the-air interface update and be swapped into the live page.

The interface (TSX on NSH). Pages, shells for desktop, phone and terminal, stores for the player, session and feedback, a cache-first data layer keyed by account, and a navigation stack. Images are decoded at the size they are shown, with a bounded memory budget, so long libraries stay light.

An artist page with its popular tracks

Animation and the music's light

Almost everything that can move does, in several layers, all on NSH's native animation and GPU shaders, and all honoring the system's reduced-motion setting.

Liked Songs, with the playing track highlighted

Scale

The first version was built in about ten hours: some 6,500 lines of Rust for the engine and platform integrations, about 1,300 lines for the bridge, and nearly 10,000 lines of TSX for the interface, with more than 130 tests that run against recorded bridge payloads and demo data, with no Spotify account or network.

The compact layout in a narrow window

Now Playing in a narrow window

Free and Premium

On Spotify Free, Spotish shuffle-plays playlists, albums and artists as Spotify's web player does, and ads play as Spotify serves them. Premium plays any track on demand without ads. Audio metering currently works on Linux; on macOS and Windows the visuals run at a resting level.

Website · GitHub repository