
Security News
n8n Tops 2025 JavaScript Rising Stars as Workflow Platforms Gain Momentum
n8n led JavaScript Rising Stars 2025 by a wide margin, with workflow platforms seeing the largest growth across categories.
ostui is a terminal client for *sonic music servers, inspired by ncmpcpp and musickube.
Releases
★
★
★ Changelog
★ Software metrics
★ Issues
★ Mailing List
★
★
★
★
★
★
★
getLyricsBySongId/. Currently, a PR in gonic provides this through
filesystem .lrc files. This version of gonic is in the main branch of
@danielepintore's fork.search3/), or
search-by-genre (via getSongsByGenre/. As part of this, switching to the
genre search in the search tab with 'g' also shows a list of all known genres,
which can be browsed.The queue shows many of the features added by this fork: song info, synced lyrics, and cover art.

Each page has a help dialog, showing both global and page-specific key bindings.

This fork has an advanced search, which can search by name or by genre.

tview has fixed the issue, so piping stderr is no longer necessary.
There are four ways to install ostui:
With your package manager. Packages should be in Arch AUR, and Alpine Testing.
With a binary release. If a binary for your OS/architecture is not available, let me know via the mailing list, and I will add it to the CI if at all possible.
The Go Way: go install ser1.net/ostui@latest
From source:
# Either grab a sourcecode tarball -- pick your version
curl -L -o ostui.tgz https://hg.sr.ht/~ser/ostui/archive/v0.1.0.tar.gz
tar -xzf ostui.tgz
# Or, if you have Mercurial installed, clone the repo:
hg clone hg.sr.ht/~ser/ostui
# And then build it:
cd ostui
go build .
Note that this project depends on libraries that have C bindings to native libraries: mpv and ncurses. Because of this, it can take a while to compile the first time. If you're used to blindingly fast Go build speeds, be patient the first time.
apt install pkg-config libmpv libmpv-devbrew install pkg-config mpv (not the cask)The METRICS.md file contains detailed information about:
This file is updated by the CI process (see .build.yml, and in particular the script that generates the file)
The CHANGELOG.md contains a list of all tagged releases and signficant changes, as well as a list of contributors.
Compile ostui with go build. Cgo is needed for interfacing with libmpv.
ostui can be installed without checking out the repository by running:
go install ser1.net/ostui@latest
ostui looks for a configuration file named config in either
$HOME/.config/ostui or the directory containing the executable.
[auth]
username = 'admin'
password = 'password'
plaintext = true # Use 'legacy' unsalted password authentication (default: false)
[server]
host = 'https://your-subsonic-host.tld'
scrobble = true # Use Subsonic scrobbling for last.fm/ListenBrainz (default: false)
[client]
random-songs = 50
[ui]
spinner = '▁▂▃▄▅▆▇█▇▆▅▄▃▂▁'
Q: Quit1: Folder view2: Queue view3: Playlist view4: Search view5: Log (errors, etc.) viewEscape/Return: Close modal if openThese controls are accessible from any view:
p: Play/pauseP: Stop>: Next song-/=: Volume down/volume up,/.: Seek -10/+10 secondsr: Add 50 random songs to the queuec: Start a server library scanEnter: Play song (clears current queue)a: Add album or song to queuey: Toggle star on song/albumA: Add song to playlistR: Refresh the list (if in artist directory, only refreshes that artist)/: Search artistsn: Continue search forwardN: Continue search backwardS: Add similar artist/song/album to playlistd/Delete: Remove currently selected song from the queueD: Remove all songs from queuey: Toggle star on songi: Toggle song info panelk: Move song up in queuej: Move song down in queues: Save the queue as a playlistS: Shuffle the songs in the queuel: Load a queue previously saved to the serverWhen ostui exits, the queue is automatically recorded to the server, including
the position in the song being played. There is a single queue per user that
can be thusly saved. Because empty queues can not be stored on Subsonic servers,
this queue is not automatically loaded; the l binding on the queue page will
load the previous queue and seek to the last position in the top song.
If the currently playing song is moved, the music is stopped before the move, and must be re-started manually.
The save function includes an autocomplete function; if an existing playlist is
selected (or manually entered), the Overwrite checkbox must be checked, or
else the queue will not be saved. If a playlist is saved over, it will be
replaced with the queue contents.
n: New playlistd: Delete playlista: Add playlist or song to queueR: Refresh playlists from serverThe search tab performs a server-side search for text in metadata name fields. The search results are filtered into three columns: artist, album, and song, where each entry matches the query in name or title.
In any of the columns:
/: Focus search field.Enter / a: Adds the selected item recursively to the queue.←, →) navigate between the columns↓, ↑) navigate the selected column listg: toggle genre searchIn the search field:
Enter: Perform the query.Escape: Escapes into the columns, where the global key bindings work.Note that the Search page is not a browser like the Browser page: it displays the search results returned by the server. Selecting a different artist will not change the album or song search results.
In Genre Search mode, the genres known by the server are displayed in the middle
column. Pressing Enter on one of these will load all of the songs with that
genre in the third column. Searching with the search field will fill the third
column with songs whose genres match the search. Searching for a genre by typing
it in should return the same songs as selecting it in the middle column. Note
that genre searches may (depending on your Subsonic server's search
implementation) be case sensitive.
To enable MPRIS2 support (Linux only), run ostui with the -mpris flag. Ensure
you have D-Bus set up correctly on your system.
On MacOS, ostui integrates with the native MediaPlayer framework to handle system media controls. This is automatically enabled if running on MacOS. Note: This is work in progress.
Contributions are welcome! Feel free to open issues or submit pull requests on GitHub. For major changes, please discuss first to ensure alignment with the project goals. You'll need:
Please base your PRs against the main branch.
To profile the application, use the following flags:
-cpuprofile=<file>: Write CPU profile to file-memprofile=<file>: Write memory profile to fileThese flags are useful for performance debugging and analysis.
View logs and error messages in the log view by pressing 4. This can help diagnose issues with server connections, playback, or other functionalities.
Here's the canonical, opinionated view for ostui, and one of the main reasons for the fork:
Metadata takes precidence over directory structure.
There is a fundamental issue in how music servers organize media, and it's
exacerbated by different servers having strong, conflicting opinions. Many
servers make an implicit assumption that music is organized on disk following a
pattern of the metadata, usually ARTIST/ALBUM/SONG. This has a number of
problems, not least of which is the unlikelyhood that people with large and
long-lived music libraries rarely have perfectly clean directory structure. And
what do we do when the music metadata tags don't match the file structure?
The crux of the issue is that the OpenSubsonic API documentation is ambiguous about the distinction between filesystem and metadata structure, and server implementations vary on how they interpret this. Subsonic, and Navidrome, assume that the directory structure matches the metadata:
musicFolder/
artist/
album/
song
In practice, users often have their music only losely organized on disk. This should be a valid structure:
musicFolder/
artist1/
album1/
song
artist1-album1/
song
artist2/
song
album3/
artist3/
song
album4/
song
song
artist5/
album5/
disc 1/
song
Some of these examples may be contrived and seem silly, but some seem (to me)
entirely reasonable. If I have a Beetles anthology, the last folder (artist5)
would seem utterly sane. Increasingly, there are artists who release songs
only as singles and not under albums, in which case the third subfolder
(artist3) makes sense. In Subsonic and Navidrom, artist1, artist1-album1,
artist2, album3, album4, and artist5 would all be different artists.
However, the view you see when you use different OpenSubsonic API calls -- file system vs metadata -- can be different and worse, can vary between servers. Mistagged songs might not be reachable at all through the metadata API calls, and wild directory structures can present lies to the use if browsed through the filesystem calls. For example, I can easily imagine someone structuring their music this way simply because of the circumstances in which they live:
musicfolder/
Amy Grant/
Praise the Lord/
Sabbath Bloody Sabbath.mp3
If the song is properly tagged, the OpenSubsonic API would consider the song "Sabbath Bloody Sabbath" to belong to both the artist "Amy Grand" and "Black Sabbath".
getMusicFolders. The returned items have IDs, but in neither
Navidrome nor Gonic do these IDs refer to any object that can be fetched by any
other API call -- in particular, not getMusicDirectory, getArtist, or
getAlbum.getMusicFolder (singlular)getIndexes returns "a list of authors." In Navidrome, this
is mostly true, in that the returned object IDs are indeed artist IDs; in gonic,
this is not true, and the IDs returned can be used only with
getMusicDirectory.getMusicDirectory could be either an artist, an album, or any other folder
in the filesystemstmp, and stmps, take the position that directory structure takes
precedence over metadata. stmp and stmps start with getIndexes, and this
information powers the main browser. getIndexes is a list of IDs which are
supposed to be both directory IDs that are also artist IDs. Any directory at
the top level is considered an artist, even if that directory is, in reality,
an album or in fact contains songs belonging to a different artist. If this is
TLD == Artist is not true, then the user is wrong.
ostui instead starts with getArtists, and it is Artists which power the main
browser. Albums are under artists, and when the album is not identified for a
song, it becomes [UNKNOWN ALBUM] -- this is how both Navidrome and gonic
present such metadata. Additional divisions such as disk number are ignored for
hierarchical purposes, and are only displayed as song metadata.
A problem with ostui's approch is that song metadata (tags) are often not clean.
By depending on getArtists, we omit songs that lack an ARTIST tag -- whether
because the song has no tags or because it is simply missing that one. This is
an issue that ostui still needs to address, by somehow identifying untagged
music and providing a virtual structure for them -- perhaps one built on
filesystem hierarchy.
The OpenSubsonic API, in attempting to serve two masters (following the inventor of the API, Subsonic, and yet trying to be a formal specification) can be ambiguously interpreted, leading to different behaviors by different servers. The same API calls to Subsonic, Navidrome, and gonic can return different results. Subsonic is self-authoritative; I'm not aware they recognize OSAPI. Navidrome follows OSAPI, but adds its own extensions and tries to be compatible with Subsonic. gonic recognizes the irreconcilable issues in OSAPI, and diverges from the spec in several ways.
There are features allowed by OSAPI for which there is not yet agreement about how servers should support them. Many result from trying to satisfy different audio container formats. Examples of this are: cover art -- embeded, or external file? Should synchronized lyrics be embedded or in external files? If synchronized lyrics are embedded, what are the tags calld -- in MP3, in Opus, in OGG, in Flac? As of yet, there is no consensus between containers, let alone between servers, about how to answer these questions. ostui attempts to support these as defined by OSAPI, regardless of how servers resolve them on the backend.
ostui tries to walk the middle path of interpreting OSAPI in a way that works with all servers. This means sometimes avoiding parts of the API definition which are problematic or self-conflicting.
The application necessarily lazily makes calls to the server in response to user actions. This can easily result in "laggy" UI behavior, and is an issue that dates back to the stmp project.
One possible fix, which was actually in the code base for Playlists a while, was a sort of "fetch everything in the background, and just work with a local cache." This had a number of issues:
Rather than going further down this path, and motivated by having experienced exactly these issues in other projects, my plan is to refactor the interface to keep a space-constrained FILO cache that's filled on demand by user actions, with some pre-emptive localized pre-fetching. This will not be a small job, and will be a substantial rewrite.
The implementation will consist of four components, two of which are in place.
ostui is a hard fork of stmps, which is itself a hard fork of stmp. The main justifications for the fork are:
ostui is licensed under the GNU General Public License v3.0 (GPL-3.0-only). This license allows you to freely use, modify, and distribute the software, provided that any distributed versions of the software, or derivative works, are also licensed under the GPL-3.0-only.
For more details, refer to the LICENSE file in the repository. For all licenses for dependencies, see METRICS.
FAQs
Unknown package
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
n8n led JavaScript Rising Stars 2025 by a wide margin, with workflow platforms seeing the largest growth across categories.

Security News
The U.S. government is rolling back software supply chain mandates, shifting from mandatory SBOMs and attestations to a risk-based approach.

Security News
crates.io adds a Security tab backed by RustSec advisories and narrows trusted publishing paths to reduce common CI publishing risks.