Spotify-reported play counts and primary-artist Top 10 ranks, directly in Spicetify playlist rows.
Gem Sort adds one focused Plays · Top 10 column to playlist-style tracklists. It prefers the space used by Album, leaves album and artist pages alone, and keeps the rest of Spotify's layout familiar.
| Title | Plays · Top 10 | Date added | Length |
|---|---|---|---|
| Example track | 385,244,129 · #1 |
Jul 20, 2026 | 3:42 |
- Shows the full, locale-formatted play count returned by Spotify—no
1.2Mabbreviation. - Shows
#1–#10when the track appears in the first-listed artist's Top 10, and—when it does not or the data is unavailable. - Recognizes Spotify's relinked and reissued copies without a relink database: exact track IDs take priority, followed by a unique same-title, near-identical-duration match within that artist's Top 10.
- Sorts the complete playlist view numerically by Plays or Top 10 rank without rewriting the playlist.
- Fetches missing play counts for a large sort in bulk and retrieves the remaining playlist pages concurrently instead of waiting for visible-row batches.
- Keeps ties in Spotify's original order and places unavailable values last.
- Starts new playback from an active sorted view with Shuffle off, so Next and Previous follow the displayed sort.
- Keeps native drag-out behavior for adding tracks to another playlist while blocking reordering drops inside the temporarily sorted source playlist.
- Retains Date added when the playlist has meaningful dates, but hides the empty field on radio, mixes, and other generated playlist views.
- Batches visible play-count lookups, deduplicates artist lookups, and reuses in-memory results within defined windows. No API key, Spotify developer app, or third-party service is required.
| Spotify view | Counts and ranks | Plays / Top 10 sorting | Layout |
|---|---|---|---|
| Playlist URLs | Yes | Yes | Replaces Album when detected; otherwise replaces native Plays or inserts a column |
| Radio, mixes, and generated playlist URLs | Yes* | Yes* | Hides Date added when the returned list has no meaningful dates |
| Liked Songs | Yes | No | Sorting is disabled on the current Spotify implementation |
| Album, artist, search, and other tracklists | Unchanged | — | Gem Sort does not modify these routes |
* Spotify must expose the playlist grid and list loader that Gem Sort expects. These are private interfaces and can change between Spotify releases.
Click either half of the column header:
- Plays: highest to lowest → lowest to highest → Spotify order
- Top 10:
#1to#10→#10to#1→ Spotify order. Within every rank—and within the unranked group—tracks are ordered by Plays from highest to lowest.
This is a temporary view sort. It loads and holds the current playlist result in memory, then serves that result back to Spotify in sorted order. It does not edit or rewrite the playlist.
To build that result, Gem Sort reuses the page Spotify has already loaded and requests missing pages with limited concurrency. A Plays sort asks Spotify's MetadataService for uncached counts in bulk before using album and track GraphQL fallbacks. A Top 10 sort deduplicates primary artists and uses a bounded adaptive worker pool: up to 10 requests for small sets, 16 for medium sets, and 20 for large sets. Row lookups and bulk sorting share the same 20-request ceiling. Play counts load in parallel with those artist requests, so compound Top 10 ordering does not add a second sequential loading phase.
While the sort is active:
- Dragging tracks to another playlist in the sidebar remains available. Dropping tracks back into the sorted source grid is blocked because that would make the temporary view order ambiguous.
- Starting playback from the playlist hands Spotify a temporary in-memory context containing the displayed order and starts that context with Shuffle off. Next and Previous then follow the sort; Spotify's manual queue can still take precedence, and Shuffle can be turned on again afterward.
- Sorting alone does not alter current playback. Clearing or changing the view sort does not interrupt a playback context that has already started.
An active sort clears when you click the active metric a third time, use a native column sort, filter the playlist, navigate away, or the playlist changes.
Clearing or navigating away invalidates the loading operation, prevents queued requests from being issued, and prevents late results from being installed. Capture, playlist-page, and metric requests are time-limited. Spotify's private interfaces do not expose a transport abort here, however, so a request already sent may still finish internally after Gem Sort has stopped waiting for it.
Gem Sort does not write track data to localStorage, IndexedDB, files, or an external database. Sort state and reusable metadata live only in Spotify's renderer RAM and disappear when Spotify closes.
For playlists with thousands of tracks, one active sort session keeps:
- one canonical record per source item, reused for both Plays and Top 10;
- one array of references in the current displayed order; and
- a playback context only after playback starts from the sorted view.
The session is released when the sort is cleared, the route or filter changes, the playlist changes, or the extension is destroyed. Switching between Plays and Top 10 reuses the same normalized records instead of retaining a second full record graph.
Reusable metadata is stored in touch-ordered, size-capped memory caches:
| Cache | Fresh for | Maximum entries |
|---|---|---|
| Track play counts | 1 hour | 20,000 |
| Primary-artist Top 10 | 30 minutes | 5,000 |
| Album fallback results | 6 hours | 5,000 |
| Failed lookup result | 2 minutes | Uses the relevant cache's cap |
Writes enforce the caps in constant time by evicting the least-recently used entry. While any cache is nonempty, Gem Sort also schedules one maintenance pass every five minutes. The pass is deferred to the renderer's idle queue when available, removes expired entries across all caches, and then rechecks the caps. This avoids a full cache scan for every track in a large sort while preventing expired entries from lingering through an unusually long Spotify session.
window.__spotifyGemSort.getStatus() reports live sizes, expired entries,
limits, cumulative expiry/LRU removals, maintenance timing, artist-request
throughput and failures, active Top 10 progress, and which metrics the active
sort has loaded. window.__spotifyGemSort.pruneCaches() runs the same
maintenance immediately and returns its removal summary.
Gem Sort is not yet listed in Spicetify Marketplace.
- macOS
- The Spotify desktop app in its standard
/Applicationslocation - Spicetify available on your
PATHor installed at~/.spicetify/spicetify
Live-tested on macOS 26.5.1 with Spotify 1.2.94.583 and Spicetify 2.44.0 on July 28, 2026. Private Spotify interfaces make this a compatibility snapshot, not a guarantee for later releases.
Download or clone this repository, open Terminal in its directory, and run:
./install.shThe installer copies gem-sort.js into the Extensions directory reported
by Spicetify, enables it, reapplies Spicetify, and restarts Spotify. It uses an
existing configured backup when one is present and creates a backup on the
first run. It overwrites an existing extension file with the same name and
removes the legacy stream-rank.js installation when upgrading from the
pre-release name.
mkdir -p ~/.config/spicetify/Extensions
cp gem-sort.js ~/.config/spicetify/Extensions/gem-sort.js
spicetify config extensions gem-sort.js
spicetify applySpicetify documents the standard extension locations and commands in its
Extensions guide.
If Spicetify is not on your PATH, substitute
~/.spicetify/spicetify for spicetify in the commands above and below.
Spotify updates can replace Spicetify's changes. Reapply them with:
spicetify backup applyIf Spicetify also needs updating:
spicetify update
spicetify restore backup applyGem Sort uses the Spotify desktop client's existing logged-in session to request data from Spotify's internal MetadataService and GraphQL interfaces. It does not collect credentials, add analytics, or send data to a third-party service.
The metric result caches are session-only: they are held in Spotify's process and disappear when Spotify reloads or closes. Entries use the reuse windows and hard count limits below:
| Cached data | Reuse window | Maximum entries |
|---|---|---|
| Track play counts | 1 hour | 20,000 |
| Artist Top 10 results | 30 minutes | 5,000 |
| Album fallback results | 6 hours | 5,000 |
| Failed or unavailable lookups | 2 minutes | Uses the relevant cache limit |
An active sort also retains one complete playlist result and its loaded
metrics until the sort is cleared. Large playlists can therefore use more
temporary memory and take longer to sort. Nothing is written to a database,
localStorage, IndexedDB, or a cache file, so cache data does not accumulate
on disk between sessions.
When playback is started from a sorted view, Spotify may also retain a temporary page containing that sorted track order for the playback context. Spotify controls that context's lifetime; Gem Sort never persists it.
Expiry is touch-based rather than swept in the background: an expired entry is removed when that key is requested again. Each cache also evicts the least-recently-used entries when its count limit is reached, so stale entries can remain during a session but cannot make those maps grow without bound. Clearing a sort releases its playlist snapshot, but does not clear the shared metric caches.
Gem Sort writes failure diagnostics to the Spotify DevTools console. Those messages may include Spotify track, album, or artist URIs. Its remembered diagnostic-key set is capped at 200 entries.
- Gem Sort depends on private Spotify data and UI interfaces exposed through Spicetify. Spotify can change them without notice.
- “Full play count” means the unabridged integer returned by Spotify; Gem Sort cannot independently audit Spotify's counting semantics.
- Top 10 rank is based on the first-listed artist and the order returned to the current logged-in Spotify client.
—can mean not in the artist's returned Top 10, a local file, or data that is missing or temporarily unavailable. Hover the cell for more detail.- Sorting Liked Songs is intentionally disabled because its current list loader cannot be safely view-sorted.
- Playlist capture and follow-up page requests are time-limited. Clearing a loading sort or receiving a playlist update prevents its result from being installed, but Spotify's underlying private request may still finish because it cannot be transport-aborted here.
- Sorted playback depends on Spotify's private page-backed context interface. Turning Shuffle back on, manually queued tracks, or a later playback action can intentionally change what plays next.
- Other extensions that replace tracklist columns, wrap playlist loaders, or
wrap
PlayerAPI.playmay conflict with Gem Sort. - The included installer targets macOS. Other desktop platforms have not been tested.
Disable the extension and reapply Spicetify:
spicetify config extensions gem-sort.js-
spicetify applyThis leaves the copied gem-sort.js file in Spicetify's Extensions
directory. Delete that file separately if you want to remove it completely.
To restore the unmodified Spotify client instead:
spicetify restoreThe shipped extension is dependency-free. Its Node test suite covers exported helpers for number decoding and formatting, playlist template transforms, stable metric ordering, pagination-range construction, response parsing, concurrency limiting, conservative relink matching, playback-context shaping, URI handling, API method-owner lookup, route eligibility, canonical large-playlist metric records, and timed LRU cache pruning.
npm test
npm run checkThese checks do not simulate Spotify's live list loader, player hook, DOM
lifecycle, network cancellation, or private event interfaces, and they do not
guarantee compatibility with a future Spotify release. In Spotify DevTools,
window.__spotifyGemSort.getStatus() exposes runtime diagnostics.
Parts of the MetadataService discovery and protobuf play-count decoding are adapted from Sort-Play under the MIT License. See THIRD_PARTY_NOTICES.md.
Sort-Play also provides play-count columns and sorting as part of a broader Spotify toolkit. Gem Sort is deliberately narrower: one combined playlist column, primary-artist Top 10 rank, playlist-aware layout, and temporary view sorting.
MIT © 2026 Gem Sort contributors.
Gem Sort is an unofficial community extension and is not affiliated with, maintained by, or endorsed by Spotify.