Architecture
Technical overview of youtube-music-cliβs architecture.
Overview
youtube-music-cli is built with:
- React + Ink - Terminal UI framework
- TypeScript - Type-safe development
- Bun - Fast JavaScript runtime
- mpv + yt-dlp - Audio playback
Project Structure
youtube-music-cli/
βββ source/
β βββ cli.tsx # CLI entry point
β βββ app.tsx # App setup
β βββ main.tsx # Root component with providers
β β
βββ components/ # UI Components
β βββ layouts/ # Main view layouts
β βββ player/ # Player components
β βββ favorites/ # Favorites view
β βββ search/ # Search components
β βββ plugins/ # Plugin management UI
β β βββ settings/ # Settings UI
β β βββ common/ # Shared components
β β
β βββ services/ # Business logic
β β βββ player/ # Audio playback
β β βββ youtube-music/ # YouTube Music API
β β βββ plugin/ # Plugin system
β β βββ config/ # Configuration
β β βββ logger/ # Logging
β β
β βββ stores/ # State management
β β βββ player.store.tsx
β β βββ navigation.store.tsx
β β βββ plugins.store.tsx
β β
β βββ hooks/ # Custom React hooks
β βββ types/ # TypeScript definitions
β βββ contexts/ # React contexts
β βββ immersive/ # Immersive Windows TUI
β β βββ renderer/ # Frame buffer, braille canvas, ANSI codes
β β βββ visualizer/ # Audio collector, disco engine
β β βββ effects/ # Particle system, color extractor
β β βββ native/ # Console, tray, notifications, hotkeys
β β βββ components/ # Immersive player component
β βββ utils/ # Utilities
β
βββ plugins/ # Plugin submodule
βββ templates/ # Plugin templates
βββ docs/ # Documentation
βββ dist/ # Compiled output
State Management
Uses React Context + useReducer pattern:
βββββββββββββββββββ
β Providers β
β β
β βββββββββββββββ β
β βThemeProviderβ β
β βββββββββββββββ β
β βββββββββββββββ β
β βPlayerProviderβ β
β βββββββββββββββ β
β βββββββββββββββ β
β βFavProvider β β
β βββββββββββββββ β
β βββββββββββββββ β
β βNavProvider β β
β βββββββββββββββ β
β βββββββββββββββ β
β βPluginsProviderβ β
β βββββββββββββββ β
βββββββββββββββββββ
β
βΌ
βββββββββββββββββββ
β MainLayout β
β (Router) β
βββββββββββββββββββ
Player Store
Manages playback state:
- Current track
- Queue
- Playback status
- Volume, shuffle, repeat
Favorites Store
Manages favorite tracks:
- Toggle favorite status
- Persistence to
favorites.json - Optimized list rendering
Navigation Store
Manages view navigation:
- Current view
- View history
- Navigation actions
Plugins Store
Manages plugin state:
- Installed plugins
- Plugin status (enabled/disabled)
- Installation operations
Service Layer
Services encapsulate external dependencies:
PlayerService
Wraps mpv/yt-dlp for audio playback.
const player = getPlayerService();
await player.play(track);
player.pause();
player.setVolume(80);
MusicService
Wraps YouTube Music API (Innertube).
const music = getMusicService();
const results = await music.search('query');
const suggestions = await music.getSuggestions(videoId);
FavoritesService
Wraps favorites persistence.
const favs = getFavoritesService();
await favs.saveFavorites(tracks);
const data = await favs.loadFavorites();
PluginRegistryService
Manages plugin lifecycle.
const registry = getPluginRegistryService();
await registry.loadAllPlugins();
await registry.enablePlugin('adblock');
Plugin System
Plugin Lifecycle
Install β Load β Init β Enable β (Running) β Disable β Destroy β Uninstall
Plugin Context
Plugins receive a context object with APIs:
{
player, // Playback control
navigation, // View navigation
config, // Configuration storage
logger, // Logging
filesystem, // File operations
audio, // Audio stream hooks
on/off/emit, // Event system
}
Event Flow
User Action β Store Dispatch β State Update β Plugin Hook β UI Re-render
β
βΌ
Plugin Event Emitted
Immersive Mode (Windows)
A fullscreen Windows-only TUI experience wired to the real player stack (PlayerService, YouTube Music API). It renders ANSI graphics directly to the terminal using an alternate screen buffer.
Architecture
βββββββββββββββββββββββββββββββββββββββ
β cli.tsx --win32 / immersive-entry β
ββββββββββββββββ¬βββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββ
β immersive-app.ts (bridge) β
β queue state + mpv IPC + search β
ββββββββββββββββ¬βββββββββββββββββββββββ
β
βββββββββ΄ββββββββ¬βββββββββββ¬βββββββββββ
βΌ βΌ βΌ βΌ
βββββββββββ βββββββββββββ ββββββββββ ββββββββββ
βRenderer β βVisualizer β βEffects β β Native β
β β β β β β β β
β-FrameBufβ β-HybridAud β β-Particleβ β-Tray β
β-Braille β β-DiscoEng β β-ColorExβ β-Hotkey β
β-ANSI β β β β β β-DPI β
βββββββββββ βββββββββββββ ββββββββββ ββββββββββ
Components
- Bridge (
source/immersive/immersive-app.ts) - Connects player services, queue state, library/search overlays, favorites, mix creation, and notifications - Actions (
source/immersive/actions/playback-actions.ts) - Shared play-from-search, mix creation, favorites, and saved playlist helpers - UI overlays (
source/immersive/ui/) - Search browse with type tabs, artist/album filters, adjustable limits, Shift+D download, library menu, 23-row settings overlay, two-line footer with mode status; player volume uses=/+/-(TUI parity) - Renderer (
source/immersive/renderer/) - Frame buffer, braille canvas for 2x4 pixel density, flicker-free ANSI output - Visualizer (
source/immersive/visualizer/) - Hybrid playback-synced audio bars, disco color cycling with beat detection - Effects (
source/immersive/effects/) - Particle system for disco mode, dominant color extraction - Native (
source/immersive/native/) - Console alt buffer, tray icon (icon.ico) with right-click Settings/Exit menu,@bun-win32DPI/hotkeys via runtime FFI loader
Entry Points
# Development
bun run dev:win32
# From main CLI
youtube-music-cli --win32 --search "query"
# Production build
bun run build:win32
# Output: dist/ymc-win32.exe
# Build all (bun + node + win32 + web)
bun run build:all
Build
Uses bun build --compile --target bun-windows-x64 to produce a standalone Windows executable with the immersive bridge entry point.
Component Architecture
Layouts
Each view has a dedicated layout component:
PlayerLayout- Main player viewSearchLayout- Search interfacePluginsLayout- Plugin managementConfigLayout- Settings
Ink Primitives
Components use Inkβs Box and Text:
<Box flexDirection="column" padding={1}>
<Text color="green">Now Playing</Text>
<Text>{track.title}</Text>
</Box>
Data Flow
ββββββββββββ ββββββββββββ ββββββββββββ
β Input βββββΆβ Store βββββΆβ UI β
β(Keyboard)β β(Reducer) β β(React) β
ββββββββββββ ββββββββββββ ββββββββββββ
β
βΌ
ββββββββββββ
β Services β
β(Side FX) β
ββββββββββββ
Build Process
- TypeScript Compilation (
tsc) - Output to
dist/ - Entry:
dist/source/cli.js
bun run build # Runs format β lint β typecheck β tsc
Testing
- AVA - Test runner
- ink-testing-library - Component testing
bun run test