Imported from Quanta-Naut/hypersonic (
AGENTS.md). Install upstream withnpx skills add Quanta-Naut/hypersonic. Copyright stays with the author.
Build a Premium OpenSubsonic Web Client for Navidrome
0. ROLE
You are a senior product designer, UX engineer, frontend architect, and full-stack engineer.
Build a production-quality, modern OpenSubsonic-compatible web music client, primarily targeting Navidrome as the backend.
The application should feel like a next-generation alternative to Spotify's web application, but it must NOT simply copy Spotify. It should take the strongest usability concepts from Spotify, Apple Music, Tidal, YouTube Music, Plexamp, and modern desktop music applications, then improve upon them.
The final product should feel:
- Premium
- Fast
- Minimal
- Immersive
- Modern
- Music-centric
- Highly polished
- Desktop-first but fully responsive
- Extremely smooth
- Keyboard-friendly
- Accessible
- Information-rich without becoming cluttered
The application must feel like a real music product, not an admin dashboard or generic CRUD application.
1. CORE PRODUCT
The application is a web client for an OpenSubsonic-compatible music server.
Primary backend target:
Navidrome
The frontend must communicate through the OpenSubsonic/Subsonic API, rather than assuming Navidrome-specific private APIs wherever possible.
The architecture should make the backend replaceable.
Conceptually:
Web Client
↓
OpenSubsonic API Layer
↓
Navidrome
↓
Music Library
Do not tightly couple the UI to Navidrome-specific implementation details unless absolutely necessary.
The application should support:
- Authentication
- Server URL configuration
- User authentication
- Library browsing
- Artists
- Albums
- Songs
- Genres
- Playlists
- Favorites
- Recently played
- Recently added
- Search
- Album pages
- Artist pages
- Queue
- Playback
- Shuffle
- Repeat
- Seek
- Volume
- Lyrics
- Cover art
- Metadata
- Play history
- Ratings/favorites
- Playlists
- Offline-aware UI architecture
- Responsive layouts
- Keyboard controls
- Persistent player state
2. DESIGN PHILOSOPHY
Do NOT make the interface look like a traditional media server.
Avoid:
- Generic Bootstrap dashboards
- Excessive borders
- Excessive cards
- Bright gradients everywhere
- Huge headers
- Dense tables as the primary UI
- Excessive rounded rectangles
- Excessive glassmorphism
- Random decorative elements
- Excessive animations
- Cluttered navigation
- Unnecessary icons
- Spotify logo imitation
- Spotify branding
Instead, create a unique visual identity.
The application should feel like:
"A premium music workstation."
It should be equally comfortable for:
- casually listening to music
- exploring a large library
- managing playlists
- discovering albums
- browsing artists
- managing a serious personal music collection
3. COLOR SYSTEM
Use a dark-first design.
Primary background:
#0B0B0D
Secondary background:
#111114
Tertiary surface:
#18181C
Elevated surface:
#202024
Hover surface:
#27272C
Primary text:
#F5F5F7
Secondary text:
#A1A1AA
Muted text:
#71717A
Borders:
rgba(255,255,255,0.07)
Primary accent:
#B8FF4A
Use the lime accent sparingly.
It should communicate:
- active playback
- primary actions
- selected navigation
- progress
- favorites where appropriate
- important interactive states
Do NOT make the entire interface lime.
Additional semantic colors:
Success:
#4ADE80
Warning:
#FBBF24
Error:
#F87171
Information:
#60A5FA
4. TYPOGRAPHY
Use a modern UI font.
Preferred:
Inter
Fallback:
system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif
Typography hierarchy:
Page title
Large, bold:
32–40px
font-weight: 700–800
Section title
20–24px
font-weight: 650–700
Album title
14–16px
font-weight: 600
Metadata
13–14px
font-weight: 400–500
Small labels
11–12px
Avoid excessive font sizes.
5. GLOBAL APPLICATION LAYOUT
Desktop layout:
┌──────────────────────────────────────────────────────────────┐
│ Sidebar │ Main Content │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
├─────────┴─────────────────────────────────────────────────────┤
│ Persistent Player │
└──────────────────────────────────────────────────────────────┘
The application consists of four major regions:
- Sidebar
- Top navigation/header
- Main content area
- Persistent bottom player
The player must remain available across navigation.
Do NOT reload the player when changing pages.
6. SIDEBAR
Desktop sidebar width:
240–260px
It should be fixed/sticky.
Background:
#0B0B0D
The sidebar should have generous spacing.
Top
Application logo / wordmark.
Example:
◉ SONORA
Do not use this exact name if another name is provided later.
The logo should be simple and monochrome with the accent color used subtly.
Primary navigation
Home
Icon:
House
Route:
/
Search
Icon:
Search
Route:
/search
Library
Expandable navigation.
Children:
Artists
Albums
Songs
Genres
Playlists
Expandable.
Children:
Your Playlists
Create Playlist
Favorites
Icon:
Heart
History
Icon:
Clock
Recently Added
Icon:
Sparkles / Plus
7. SIDEBAR ACTIVE STATE
Active navigation item:
- Slightly brighter surface
- Accent icon
- White text
- Small visual indicator
Example:
┌────────────────────────┐
│ ● Home │
└────────────────────────┘
Do not use a giant colored block.
The active state should feel subtle and premium.
8. SIDEBAR COLLAPSED MODE
Allow sidebar collapse.
Expanded:
260px
Collapsed:
72px
Collapsed mode should show:
- Icons
- Tooltips
- Logo mark
The application must continue functioning normally.
Remember the user's sidebar preference.
9. TOP BAR
The top bar should be sticky.
It should contain:
Left:
- Back
- Forward
Center/left:
- Contextual search where appropriate
Right:
- Connection status
- User avatar
- User menu
Do NOT permanently occupy half the screen with a huge search bar.
10. CONNECTION INDICATOR
Show a small connection indicator.
Examples:
● Connected
or:
● Offline
Use subtle visual treatment.
If the server becomes unavailable:
Unable to connect to server
Retry
Do not destroy the current UI state.
11. HOME PAGE
The home page should be highly personalized based on the user's library.
Structure:
Good evening
[Continue Listening]
[Recently Played]
[Recently Added]
[Your Favorites]
[Made For You / Recommendations]
[Artists You Follow / Frequently Played]
[Genres]
Do not blindly show every section if there is insufficient data.
Sections should intelligently disappear when empty.
12. GREETING
Use time-aware greetings:
Morning:
Good morning
Afternoon:
Good afternoon
Evening:
Good evening
Night:
Good night
Do not make this the dominant visual element.
13. HERO / CONTINUE LISTENING
The first section should prioritize listening rather than browsing.
Example cards:
┌────────────────────────────────┐
│ Album artwork │
│ │
│ Continue listening │
│ Album / Artist │
│ ━━━━━━━━━━━━━━━ │
└────────────────────────────────┘
Show:
- Album artwork
- Track
- Artist
- Album
- Progress if available
- Play button
Clicking the card should resume playback.
14. ALBUM CARDS
Album cards are fundamental components.
Structure:
┌───────────────┐
│ │
│ │
│ COVER ART │
│ │
│ │
└───────────────┘
Album Name
Artist Name
2026 • Album
Artwork should use a 1:1 ratio.
Border radius:
8–12px
Do not use extremely rounded cards.
15. ALBUM CARD HOVER
On hover:
- Slightly raise card
- Reveal play button
- Slightly darken artwork
- Show subtle shadow
Example:
Album artwork
▶
Animation duration:
150–200ms
No exaggerated scaling.
16. ARTIST CARDS
Artist cards should use circular artwork where appropriate.
Structure:
┌─────────┐
│ │
│ ARTIST │
│ │
└─────────┘
Artist Name
Artist artwork should be circular.
17. SONG ROW
Songs should have a compact but beautiful list representation.
Example:
┌─────────────────────────────────────────────────────────────┐
│ # │ Cover │ Song Title │ Artist │ Album │ Duration │ ⋮ │
└─────────────────────────────────────────────────────────────┘
On smaller screens:
Cover | Song + Artist | Duration | ⋮
Show:
- Track number
- Artwork
- Title
- Artist
- Album
- Duration
- Favorite
- More actions
Do not show every column on mobile.
18. SONG ROW INTERACTION
Hover:
- Track number changes to play icon
or:
▶
Click:
- Start playback
Double click:
- Start playback immediately
Right click / More menu:
Play
Play next
Add to queue
Add to playlist
Go to album
Go to artist
Favorite
View lyrics
Download
Only show Download if supported by the server/client configuration.
19. ARTIST PAGE
Artist page should feel immersive.
Structure:
┌───────────────────────────────────────────────┐
│ │
│ Artist artwork │
│ │
│ ARTIST │
│ Artist Name │
│ 52 albums • 624 songs │
│ │
│ ▶ Play Shuffle ♡ │
└───────────────────────────────────────────────┘
Popular
1 Song
2 Song
3 Song
4 Song
5 Song
Albums
[Album] [Album] [Album] [Album]
Singles & EPs
[Album] [Album]
Appears On
[Album] [Album]
20. ALBUM PAGE
Album page:
┌──────────────────────────────────────────────┐
│ │
│ Album Artwork ALBUM │
│ Album Name │
│ Artist │
│ 2026 • 12 tracks │
│ │
│ ▶ Play ♡ ⋮ │
└──────────────────────────────────────────────┘
01 Track Name 3:42
02 Track Name 4:01
03 Track Name 3:28
...
Below the track list:
More by Artist
Show related albums.
21. GENRE PAGE
Genres should be visually browsable.
Use compact genre tiles.
Examples:
Rock
Electronic
Hip-Hop
Pop
Jazz
Classical
Ambient
Soundtrack
Use artwork-derived background imagery when available.
Do not make genre cards excessively colorful.
22. LIBRARY PAGE
The library should have a strong information architecture.
Top tabs:
Albums
Artists
Songs
Genres
Playlists
Support:
- Grid view
- List view
Provide sorting:
Recently Added
Alphabetical
Artist
Year
Play Count
Rating
Provide filtering.
Example:
Filter
Artist
Genre
Year
Rating
23. SEARCH
Search should be extremely fast.
Search should query:
- Songs
- Artists
- Albums
- Playlists
- Genres
Search UI:
Search your library
As the user types, show grouped results:
Songs
────────────
Song 1
Song 2
Artists
────────────
Artist 1
Albums
────────────
Album 1
Keyboard:
/
should focus search.
Escape closes search overlays.
24. SEARCH RESULTS PAGE
Full results should have:
Top Result
Songs
Artists
Albums
Playlists
The result ranking should prioritize exact matches.
Search must debounce API requests.
Do not request the server for every keystroke without debouncing.
25. PLAYLIST PAGE
Playlist header:
Playlist artwork
Playlist Name
Description
12 songs • 47 min
▶ Play
Shuffle
⋮
Track list underneath.
Support:
- Add songs
- Remove songs
- Reorder songs
- Rename playlist
- Delete playlist
- Duplicate playlist
- Add playlist to queue
Drag-and-drop ordering should be supported where practical.
26. FAVORITES
Favorites page should combine:
- Favorite songs
- Favorite albums
- Favorite artists
Provide tabs:
Songs
Albums
Artists
Favorite action should immediately update the UI optimistically.
27. HISTORY
History should show:
Today
Song
Artist
Album
Played 4 minutes ago
Group by:
Today
Yesterday
This Week
Earlier
Clicking an item should play it.
28. RECENTLY ADDED
Display recently added music.
Allow sorting:
Newest
Oldest
Album
Artist
Use album-centric presentation.
29. PERSISTENT MUSIC PLAYER
The bottom player is one of the most important components.
Height:
76–88px
Layout:
┌─────────────────────────────────────────────────────────────┐
│ Artwork │ Song Info │ Controls │ Volume │ Queue │
└─────────────────────────────────────────────────────────────┘
Left:
- Album artwork
- Track title
- Artist
- Favorite button
Center:
- Previous
- Play/Pause
- Next
- Shuffle
- Repeat
Bottom or integrated:
- Progress bar
Right:
- Volume
- Queue
- Lyrics
- More
30. PLAYER ARTWORK
Artwork:
48x48px
Desktop.
Use:
56x56px
when appropriate.
Artwork should be sharp and use cached image URLs.
31. PLAYER PROGRESS
Progress bar should be easy to interact with.
Display:
1:42 ━━━━━━━━━━━━━━━ 3:58
Clicking anywhere on the bar seeks.
Dragging should provide accurate seeking.
The progress bar should use the primary accent.
32. PLAYER CONTROLS
Controls:
Previous
Play/Pause
Next
Shuffle
Repeat
Play/Pause should be visually dominant.
Use circular button.
Do not make all controls equally large.
33. QUEUE DRAWER
Clicking Queue opens a right-side drawer.
Desktop:
┌──────────────────────────────┐
│ Queue × │
│ │
│ Playing │
│ ┌──────────────────────────┐ │
│ │ Cover Song │ │
│ └──────────────────────────┘ │
│ │
│ Next │
│ Track │
│ Track │
│ Track │
│ │
│ Clear queue │
└──────────────────────────────┘
Queue must support:
- Reordering
- Remove
- Clear
- Play immediately
- Add to playlist
34. NOW PLAYING EXPERIENCE
The player should have an expanded "Now Playing" view.
This can be a modal/full-screen page.
Layout:
┌───────────────────────────────────────────────┐
│ × │
│ │
│ │
│ LARGE ARTWORK │
│ │
│ │
│ Song Title │
│ Artist │
│ │
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
│ │
│ Previous Play Next │
│ │
└───────────────────────────────────────────────┘
On desktop, optionally show:
Lyrics
Queue
Track information
alongside the artwork.
35. LYRICS
Lyrics must be a first-class feature.
If lyrics are available through the server:
Display them beautifully.
Use:
- Large readable text
- Generous line spacing
- Current line highlighting when synchronized lyrics exist
- Auto-scroll for synchronized lyrics
Current line:
- Higher contrast
- Accent color or subtle glow
Non-current lyrics:
- Lower opacity
If no lyrics exist:
No lyrics available
Do not show a broken-looking empty panel.
36. FULLSCREEN NOW PLAYING
Support a fullscreen immersive player.
Use album artwork as the visual centerpiece.
Optional:
- blurred enlarged album artwork behind the interface
- subtle gradient derived from artwork
- lyrics panel
- queue panel
Important:
Do not make the gradient overpower the actual UI.
37. MINI PLAYER ON MOBILE
On mobile:
┌───────────────────────────────────┐
│ Cover │ Song Name ▶ │
└───────────────────────────────────┘
The mini player sits immediately above bottom navigation.
Tapping opens the full player.
38. MOBILE NAVIGATION
Mobile should not use the desktop sidebar.
Use bottom navigation:
Home
Search
Library
Playlists
Player remains persistent.
Profile/settings can be accessed through a menu.
39. RESPONSIVE BREAKPOINTS
Implement responsive behavior approximately around:
< 640px Mobile
640–1024 Tablet
1024–1440 Desktop
> 1440 Large desktop
Do not simply scale desktop down.
Actually redesign layouts for mobile.
40. MOBILE ALBUM PAGE
Mobile:
Artwork
Album Name
Artist
2026 • 12 songs
▶ Play Shuffle
Track list
Do not use multi-column tables.
41. MOBILE ARTIST PAGE
Mobile artist header:
Circular Artist Image
Artist Name
X albums • X songs
▶ Play
Shuffle
Then:
Popular
Albums
Singles
42. CONTEXT MENUS
Every major media object should have a context menu.
Album:
Play album
Play next
Add to queue
Add to playlist
Favorite
Go to artist
Song:
Play
Play next
Add to queue
Add to playlist
Favorite
Go to album
Go to artist
View lyrics
Artist:
Play
Shuffle
Favorite
Playlist:
Play
Shuffle
Edit
Duplicate
Delete
43. TOAST NOTIFICATIONS
Use subtle toast notifications.
Examples:
Added to queue
Added to playlist
Removed from favorites
Playlist updated
Connection restored
Toasts should not obstruct the player.
44. LOADING STATES
Do NOT show a blank screen during loading.
Use skeleton loaders.
Album skeleton:
[████████████]
[████████████]
Song skeleton:
[██] █████████████
Skeletons should match the actual component dimensions.
45. EMPTY STATES
Every empty page needs a meaningful empty state.
Example:
No favorite songs yet
Songs you favorite will appear here.
[Explore your library]
Avoid generic:
No data
46. ERROR STATES
Errors should be understandable.
Example:
Couldn't load your library
The music server didn't respond.
[Try again]
Never expose raw API errors directly to users.
47. OFFLINE / SERVER FAILURE
If Navidrome becomes unreachable:
- Preserve current UI
- Preserve current player state
- Show connection indicator
- Allow already-loaded content to remain visible
- Retry automatically
- Provide manual retry
Do not instantly redirect to login.
48. AUTHENTICATION
Create a beautiful server setup/login screen.
Initial state:
Welcome
Connect your music server
Server URL
[ https://music.example.com ]
Username
[ ]
Password
[ ]
[ Connect ]
Support OpenSubsonic authentication correctly.
Do not hardcode a specific Navidrome URL.
49. SERVER CONFIGURATION
Allow users to configure:
Server URL
Username
Password
Store credentials securely.
Do not expose credentials in logs.
If browser architecture requires a token/password hash, follow OpenSubsonic authentication requirements correctly.
50. SETTINGS
Settings page should be organized into sections.
Account
- Username
- Server
- Logout
Playback
- Default volume
- Crossfade
- Gapless playback
- Auto play
- Replay behavior
Only show options actually supported by the backend/browser.
Appearance
- Theme
- Accent color
- Compact mode
- Sidebar behavior
Interface
- Show album years
- Show track numbers
- Grid density
- Animation level
Audio
- Streaming quality
- Transcoding preferences where supported
Advanced
- Server information
- API version
- Cache
- Clear cached data
- Debug information
51. THEMING
Support:
Dark
Light
System
Dark should be the default.
The entire UI must be designed around semantic CSS variables rather than hard-coded colors.
Example conceptual tokens:
--background
--surface
--surface-elevated
--surface-hover
--text-primary
--text-secondary
--text-muted
--border
--accent
--danger
--success
This makes the design maintainable.
52. ACCENT COLOR
Default accent:
#B8FF4A
Allow changing the accent in settings.
Potential presets:
Lime
Purple
Blue
Orange
Pink
But keep the default lime identity.
53. ARTWORK HANDLING
Album artwork is extremely important.
Implement:
- Lazy loading
- Caching
- Proper aspect ratio
- Blur placeholders
- Error fallback
- Responsive image sizes
Do not load huge artwork files when a smaller version is sufficient.
54. IMAGE PLACEHOLDER
When artwork is missing:
Display a tasteful dark placeholder with:
- Music note icon
- Album/artist initials when appropriate
Do not show broken image icons.
55. PLAYER AUDIO ENGINE
Create a dedicated audio playback service.
It should be independent from React/UI components.
Conceptually:
AudioEngine
├── play()
├── pause()
├── seek()
├── next()
├── previous()
├── setVolume()
├── setQueue()
├── shuffle()
├── repeat()
└── destroy()
The UI subscribes to player state.
Do NOT make the audio element depend directly on individual page components.
56. PLAYER STATE
Maintain:
currentTrack
queue
queueIndex
playing
position
duration
volume
shuffle
repeatMode
Persist appropriate state locally.
When the page reloads, restore:
- Queue where possible
- Current track
- Playback position
- Volume
- Shuffle
- Repeat
Do not unexpectedly start playback without user interaction if browser autoplay policies prohibit it.
57. QUEUE MODEL
Separate:
Queue
from:
Playlist
A playlist is persistent user data.
The queue is temporary playback state.
Do not confuse the two.
58. PLAYBACK HISTORY
When supported by OpenSubsonic/Navidrome:
Record playback correctly.
Do not send excessive API requests.
Use debouncing/throttling where appropriate.
59. FAVORITES
Favorites should synchronize with the server.
Use optimistic UI updates:
Click heart
↓
UI changes immediately
↓
API request
↓
Rollback only if request fails
If the API fails, restore the previous state and show an error.
60. API ARCHITECTURE
Create a clean API abstraction.
Example conceptual structure:
/api
auth
albums
artists
songs
playlists
search
favorites
history
lyrics
stream
coverArt
Create typed models for API responses.
Do not scatter raw fetch calls throughout components.
61. OPEN SUBSONIC COMPATIBILITY
Implement the OpenSubsonic API carefully.
At minimum, design around operations such as:
ping
getLicense
getUser
getArtists
getArtist
getAlbum
getSong
getAlbumList2
getRandomSongs
search3
getPlaylists
getPlaylist
createPlaylist
updatePlaylist
deletePlaylist
star
unstar
getStarred2
getNowPlaying
scrobble
stream
download
getCoverArt
getLyrics3
getGenres
getMusicDirectory
Use the appropriate API version and parameters according to the server's advertised capabilities.
Do not assume every OpenSubsonic server implements every optional feature.
Gracefully detect unsupported features.
62. NAVIDROME-SPECIFIC CONSIDERATIONS
The primary target is Navidrome.
Test against a real Navidrome installation.
Account for:
- Large libraries
- Thousands of albums
- Tens of thousands of songs
- Long artist lists
- Large playlists
- Large search results
Do not load the entire music library into the browser unnecessarily.
Use pagination, lazy loading, virtualized lists, or API-supported filtering where appropriate.
63. LARGE LIBRARY PERFORMANCE
The client must remain responsive with a very large library.
Use:
- Virtualized song lists
- Lazy-loaded album grids
- Debounced search
- Request caching
- Image caching
- Memoized components
- Pagination/infinite scrolling
- Background API requests where useful
Avoid rendering 20,000 DOM nodes.
64. DATA CACHE
Use a robust client-side server-state strategy.
For example:
TanStack Query
or an equivalent solution.
Cache:
- Artists
- Albums
- Songs
- Playlists
- Genres
- Search results
- User information
Invalidate caches intelligently after mutations.
65. UI STATE
Separate:
Server State
from:
Client State
Server state:
- Library
- Playlists
- Favorites
- User
- Metadata
Client state:
- Sidebar
- Modals
- Queue
- Player
- Theme
- Settings
Do not put everything into one giant global store.
66. ROUTING
Use clean routes.
Example:
/
/search
/library
/library/albums
/library/artists
/library/songs
/library/genres
/albums/:id
/artists/:id
/playlists/:id
/favorites
/history
/settings
Deep links must work.
Refreshing any route should not break the application.
67. URL STATE
Where appropriate, preserve UI state in URLs.
Examples:
/library/albums?sort=recent
/search?q=daft+punk
This makes pages shareable and refresh-safe.
68. KEYBOARD SHORTCUTS
Implement:
Space Play/Pause
N Next
P Previous
S Toggle Shuffle
R Toggle Repeat
M Mute
↑ Volume up
↓ Volume down
← Seek backward
→ Seek forward
/ Search
Q Queue
L Lyrics
Esc Close modal
Do not hijack keys while the user is typing in an input.
Provide a keyboard shortcuts section in Settings.
69. ACCESSIBILITY
Use:
- Semantic HTML
- ARIA labels where necessary
- Keyboard navigation
- Focus states
- Screen-reader-friendly controls
- Sufficient contrast
- Reduced motion support
Every icon-only button must have an accessible label.
Example:
aria-label="Play"
70. REDUCED MOTION
Respect:
prefers-reduced-motion
Disable or reduce:
- Artwork transitions
- Page transitions
- Hover movement
- Drawer animations
- Background effects
71. ANIMATION LANGUAGE
Animations should feel expensive and intentional.
Use approximately:
120–220ms
for normal interactions.
Use slightly longer animations for:
- drawers
- fullscreen player
- major transitions
Avoid:
- bouncing
- excessive spring animations
- unnecessary particle effects
- constant movement
72. PAGE TRANSITIONS
Page changes should feel smooth.
Do not make the application feel like separate websites.
Preserve:
- Player
- Sidebar
- Scroll state where sensible
73. ARTWORK-DERIVED VISUALS
For album/now-playing pages, optionally derive a subtle background from artwork.
Example:
Large blurred album artwork
↓
Darkened gradient
↓
Readable UI on top
The actual album artwork remains the visual focal point.
Never sacrifice text readability for visual effects.
74. PLAYER EXPANSION
Clicking the current track/player artwork should expand the player.
Transition:
Bottom player
↓
Fullscreen / large player
The transition should feel like the player is expanding rather than opening an unrelated page.
75. DRAG AND DROP
Where useful:
- Playlist ordering
- Queue ordering
- Adding tracks to playlists
Provide clear drag feedback.
On mobile, use touch-friendly alternatives.
76. RIGHT-CLICK SUPPORT
Desktop users should be able to right-click:
- Songs
- Albums
- Artists
- Playlists
Show the appropriate contextual menu.
Do not rely exclusively on right-click; always provide a visible "⋮" action.
77. RESPONSIVE GRID
Album grid should dynamically determine columns.
Example:
Desktop:
6–8 albums
Large display:
8–10 albums
Tablet:
4–6 albums
Mobile:
2 albums
Do not force fixed widths that create awkward whitespace.
78. DENSITY MODES
Support:
Comfortable
Compact
Comfortable:
- Larger album cards
- More whitespace
- Larger row height
Compact:
- Smaller cards
- Dense song lists
- Better for very large libraries
79. SORTING
Where sorting exists, provide a consistent dropdown.
Example:
Sort by
Recently Added
Recently Played
Name
Artist
Album
Year
Duration
Play Count
Rating
Only expose meaningful options for the current entity.
80. FILTERING
Filters should be non-destructive.
Example:
Albums
[Search albums...]
Filter:
Genre
Artist
Year
Allow clearing all filters.
81. TOOLTIPS
Use tooltips for unfamiliar icon-only controls.
Examples:
Shuffle
Repeat
Queue
Lyrics
Expand player
Do not use tooltips for obvious text buttons.
82. MODALS
Use modals for:
- Create playlist
- Rename playlist
- Server configuration
- Confirm destructive actions
- Keyboard shortcuts
- Track information
Avoid using modals for ordinary navigation.
83. DESTRUCTIVE ACTIONS
Deleting a playlist should require confirmation.
Example:
Delete playlist?
This will permanently remove the playlist.
Cancel
Delete playlist
Never make destructive actions one-click without confirmation.
84. TRACK INFORMATION
Provide a detailed track info panel.
Show:
Title
Artist
Album
Album Artist
Genre
Year
Track
Disc
Duration
Bitrate
Format
Path
Only display metadata that actually exists.
85. AUDIO FORMAT INFORMATION
Where available, show:
FLAC
MP3
AAC
Opus
etc.
Do not pretend a track is lossless if the server is transcoding it.
86. STREAMING
Streaming URLs must be generated through the OpenSubsonic-compatible API.
Never expose sensitive authentication information unnecessarily in URLs.
Handle:
- Authentication
- Range requests where appropriate
- Browser audio compatibility
- Transcoding
- Errors
- Expired URLs
87. CORS / SERVER ARCHITECTURE
The application must work correctly when:
Frontend
and
Navidrome
are hosted on different origins.
Design the API layer appropriately.
Clearly document any required:
- CORS configuration
- Reverse proxy configuration
- HTTPS requirements
Do not assume frontend and Navidrome are hosted on the same domain.
88. SECURITY
Never:
- Log passwords
- Store raw passwords unnecessarily
- Put secrets in source code
- Commit credentials
- Expose API credentials in analytics
- Use insecure HTTP when HTTPS is available
Use secure browser storage patterns.
89. FIRST-RUN EXPERIENCE
When there is no configured server:
Welcome to [APP NAME]
Your music.
Your server.
Your way.
Connect your OpenSubsonic server.
Server URL
Username
Password
[Connect]
Make this experience polished.
90. ERROR RECOVERY
If connection fails:
Couldn't connect to your music server.
Check the server URL and credentials.
[Try again]
[Edit server]
If authentication fails:
Incorrect username or password.
If server version is unsupported:
This server does not provide the required OpenSubsonic functionality.
91. SETTINGS SIDEBAR
Settings should have its own navigation.
Settings
Account
Playback
Appearance
Interface
Audio
Keyboard Shortcuts
Server
Advanced
92. DESIGN DETAILS
Use:
- 8px spacing base system
- 8–12px card radius
- subtle shadows
- subtle borders
- generous whitespace
- consistent icon sizing
Icons should generally be:
18–22px
Use a consistent icon library such as:
Lucide
Do not mix unrelated icon styles.
93. BORDER RADIUS
Recommended:
Buttons:
8px
Cards:
10px
Inputs:
8px
Player:
0–12px
Pills:
9999px
Do not turn every component into a pill.
94. SCROLLBARS
Use subtle custom scrollbars on desktop.
They should not visually dominate the interface.
On mobile, use native scrolling behavior.
95. CONTEXT-AWARE HOME
The home page should change based on available data.
If the user has:
- No history → show recently added
- History → show continue listening
- Favorites → show favorites
- Playlists → show playlists
- Large library → show recommendations/discovery sections
Do not show empty sections.
96. DISCOVERY
OpenSubsonic does not necessarily provide Spotify-style recommendation intelligence.
Therefore, do NOT fake a recommendation engine.
Instead provide intelligent library-based discovery:
Random
Recently Played
Recently Added
Most Played
Favorites
Similar Genre
Same Artist
Albums You May Have Missed
If a recommendation engine is added later, make it a separate abstraction.
97. RANDOM PLAY
Provide multiple random modes where meaningful:
Random song
Random album
Random artist
Random from genre
Random from library
98. SHUFFLE
Shuffle must operate on the queue rather than merely selecting another song.
Once shuffle starts:
- Generate a shuffled queue
- Preserve currently playing track
- Avoid immediately repeating the same track
99. REPEAT MODES
Support:
Off
Repeat Queue
Repeat Track
Clearly communicate the active state.
100. PLAY NEXT
When a user selects:
Play next
the song should be inserted immediately after the current track.
Do not replace the entire queue.
101. ADD TO QUEUE
"Add to queue" should append.
For an album:
Add entire album
For an artist:
Add artist songs
where practical.
102. DOUBLE-CLICK BEHAVIOR
Desktop:
Double-click song:
Start playing that song
Double-click album:
Play album
Single click should generally navigate unless interacting with an explicit play button.
103. MOBILE TOUCH TARGETS
All interactive elements should have sufficiently large touch targets.
Target approximately:
44x44px
minimum where practical.
104. PERFORMANCE BUDGET
The app should feel fast even on modest hardware.
Prioritize:
- Fast first paint
- Minimal JavaScript blocking
- Lazy loading
- Code splitting
- Image optimization
- API caching
Do not ship enormous dependencies without justification.
105. COMPONENT ARCHITECTURE
Organize components conceptually:
components/
layout/
Sidebar
TopBar
MobileNav
player/
Player
PlayerControls
ProgressBar
Queue
NowPlaying
Lyrics
music/
AlbumCard
ArtistCard
SongRow
SongList
AlbumGrid
ArtistGrid
playlist/
PlaylistCard
PlaylistHeader
PlaylistEditor
search/
SearchBar
SearchResults
SearchResultGroup
common/
Button
IconButton
Modal
Dropdown
Tooltip
Toast
Skeleton
EmptyState
ErrorState
Keep components reusable.
106. DESIGN SYSTEM
Create reusable primitives before building pages.
Examples:
Button
IconButton
Input
Select
Dropdown
Modal
Drawer
Tabs
Badge
Tooltip
Toast
Card
Avatar
Skeleton
Pages should be assembled from these primitives.
107. NO DUPLICATED UI LOGIC
Do not independently implement:
- favorite buttons
- play buttons
- song rows
- context menus
- loading states
in every page.
Create reusable components.
108. ICON BUTTON DESIGN
Icon buttons should have:
- 36–40px desktop hit area
- subtle hover background
- accessible label
- tooltip when needed
Example:
┌─────┐
│ ♡ │
└─────┘
109. HOVER BEHAVIOR
Desktop-only hover effects should not break touch interfaces.
Use media queries / pointer detection appropriately.
110. DATA FETCHING
Do not fetch the same entity repeatedly.
For example:
If Album A appears on:
- Home
- Artist page
- Search
- Recently added
reuse cached album data where possible.
111. API ERROR HANDLING
Every API request should have:
loading
success
empty
error
states.
Never assume success.
112. NETWORK RETRIES
Retry transient errors intelligently.
Do not repeatedly retry authentication failures.
Distinguish:
401 / authentication
403 / permission
404 / missing
5xx / server
network failure
113. NAVIDROME TESTING
Test the application against a real Navidrome instance containing:
- Hundreds of artists
- Thousands of albums
- Thousands of songs
- Playlists
- Favorites
- Album artwork
- Lyrics where available
- Multiple formats
- Long song titles
- Unicode artist names
- Missing artwork
- Missing metadata
The UI must not break with real-world music metadata.
114. EDGE CASES
Explicitly handle:
- Very long artist names
- Very long album names
- Songs with no album
- Albums with no artwork
- Artists with no image
- Multiple discs
- Compilation albums
- Various Artists
- Explicit metadata
- Unicode
- Japanese
- Korean
- Cyrillic
- Arabic
- Emojis
- Duplicate album names
- Duplicate artist names
- Empty playlists
- Huge playlists
- Network interruptions
- Expired sessions
- Missing lyrics
- Unsupported API methods
115. VERY IMPORTANT: VARIOUS ARTISTS
Do not treat:
Various Artists
as a normal individual artist in every context.
Compilation albums should have sensible presentation.
116. MULTI-DISC ALBUMS
Display:
Disc 1
01 Track
02 Track
...
Disc 2
01 Track
02 Track
Do not flatten multi-disc albums incorrectly.
117. METADATA DISPLAY
Never assume metadata exists.
Use graceful fallbacks.
For example:
Artist Name
Unknown Artist
rather than blank space.
118. LONG TEXT
Use ellipsis where appropriate:
A Very Long Album Ti...
But make the full value available through:
- tooltip
- details view
- accessible label
119. DESKTOP WINDOW SIZES
Test at:
1280x720
1440x900
1920x1080
2560x1440
The UI should not become excessively stretched on ultrawide displays.
Use reasonable maximum content widths where appropriate.
120. MOBILE TESTING
Test at:
390x844
393x852
412x915
and tablet layouts.
121. VISUAL QUALITY BAR
The final application should look like something that could realistically ship as a commercial music application.
It should NOT look like:
- a Tailwind template
- a dashboard template
- a student project
- a generic AI-generated SaaS UI
- a Navidrome admin interface
Every spacing value, typography choice, icon, hover state, animation, and component should feel intentional.
122. DESIGN REFERENCE
Use the following products as conceptual references, NOT as things to clone:
Spotify:
- excellent music discovery
- persistent playback
- simple navigation
Apple Music:
- strong album presentation
- immersive now playing
Plexamp:
- music-centric experience
- excellent library exploration
Tidal:
- premium presentation
- strong artwork emphasis
YouTube Music:
- quick discovery
- powerful search
Combine their strengths while creating an original visual system.
123. DO NOT CLONE SPOTIFY
The goal is:
Spotify-level usability, but a better interface for personal music libraries.
Do not copy:
- Spotify branding
- Spotify logo
- Spotify exact colors
- Spotify exact layout
- Spotify proprietary assets
- Spotify-specific terminology where unnecessary
Create an original product identity.
124. PRODUCT PERSONALITY
The application should communicate:
Your music.
Your server.
Your control.
It should feel like software made for people who actually care about their music collection.
125. OPTIONAL POWER-USER FEATURES
Where practical, support:
- Keyboard shortcuts
- Queue manipulation
- Drag and drop
- Multi-select songs
- Bulk playlist actions
- Bulk favorite/unfavorite
- Album download
- Track download
- Copy track information
- Open artist/album links
- Detailed metadata
- Server statistics
- Recently played
- Play counts
- Rating support
Only implement features when supported by the backend or browser.
126. MULTI-SELECT
Desktop users should eventually be able to select multiple songs.
Example:
☑ Song A
☑ Song B
☑ Song C
Then show:
3 selected
Play
Add to queue
Add to playlist
Favorite
Do not make this feature visually intrusive.
127. PERSISTENT STATE
Persist:
Theme
Accent
Sidebar state
Density
Volume
Playback preferences
Do not persist sensitive information unnecessarily.
128. FIRST IMPLEMENTATION PRIORITY
Build in this order:
Phase 1
- Authentication
- App shell
- Sidebar
- Routing
- Home
- Library
- Albums
- Artists
- Songs
- Search
- Persistent player
Phase 2
- Queue
- Playlists
- Favorites
- History
- Lyrics
- Now Playing
Phase 3
- Settings
- Keyboard shortcuts
- Responsive mobile UI
- Performance optimization
- Error recovery
- Accessibility
Phase 4
- Advanced power-user features
- Offline/cache improvements
- Recommendation/discovery layer
- Additional OpenSubsonic compatibility
129. DEVELOPMENT REQUIREMENTS
Before writing large amounts of code:
- Establish the architecture.
- Establish the design tokens.
- Establish routing.
- Establish API abstraction.
- Establish authentication.
- Establish player state architecture.
- Establish reusable UI primitives.
- Establish responsive layout system.
Then build pages.
Do not create every page independently and attempt to unify them later.
130. CODE QUALITY
Code should be:
- Typed
- Modular
- Maintainable
- Tested
- Reusable
- Documented where necessary
Avoid:
- giant components
- duplicated API calls
- duplicated UI
- deeply nested conditional rendering
- magic constants
- hard-coded server URLs
- hard-coded credentials
- unnecessary global state
131. TESTING
Include tests for:
API
- Authentication
- Search
- Album retrieval
- Artist retrieval
- Playlist creation
- Playlist modification
- Favorites
- Playback/scrobbling
Player
- Play
- Pause
- Seek
- Next
- Previous
- Shuffle
- Repeat
- Queue
- Volume
UI
- Navigation
- Search
- Responsive layouts
- Modals
- Context menus
- Empty states
- Error states
132. FINAL QUALITY CHECK
Before considering the project complete, verify:
- Can a user connect to Navidrome?
- Can they browse their entire library?
- Can they search?
- Can they play a song?
- Can they play an album?
- Can they play an artist?
- Does playback continue between pages?
- Does the queue work?
- Does shuffle work?
- Does repeat work?
- Can users favorite tracks?
- Can users create playlists?
- Can users edit playlists?
- Can users see lyrics?
- Does the mobile interface work?
- Does the application recover from server failures?
- Does it work with large libraries?
- Are loading states polished?
- Are empty states polished?
- Are errors understandable?
- Are keyboard shortcuts functional?
- Does the UI remain responsive?
- Is the application accessible?
- Does it actually feel premium?
133. MOST IMPORTANT DESIGN PRINCIPLE
Do not optimize for the number of features.
Optimize for:
How good it feels to listen to music.
A user should be able to open the application, see their music immediately, press play, and disappear into their library.
Every interaction should feel fast, obvious, and intentional.
The final result should feel like:
Spotify's usability + Plexamp's music obsession + Apple Music's presentation + the freedom of self-hosting.
But with a completely original visual identity.
134. FINAL IMPLEMENTATION INSTRUCTION
Build the application as a cohesive product, not as a collection of disconnected screens.
Start with the design system and application shell.
Then implement the OpenSubsonic API abstraction.
Then implement authentication.
Then implement the persistent audio player.
Then build the library experience around that player.
Every page must share the same:
- typography
- spacing
- color system
- interaction language
- animation language
- component system
- navigation
- player
Do not proceed by generating random UI screens.
Before implementing each major page, reason about:
- What is the user's goal?
- What information matters most?
- What action should be easiest?
- What happens when there is no data?
- What happens when the server fails?
- What happens on mobile?
- What happens with thousands of items?
Build accordingly.
The final result should be a production-grade OpenSubsonic web client optimized for Navidrome, with a premium music-first experience and a visual quality bar significantly above a typical Spotify-style clone.
