A native macOS WidgetKit widget that shows what's playing on Spotify — with album art, track info, and playback controls (play/pause, next, previous).
No Spotify API key required. Uses AppleScript to talk directly to the Spotify desktop app.
- 3 widget sizes — small, medium, large
- Real-time updates — reacts instantly to Spotify play/pause/skip via system notifications
- Playback controls — tap play/pause, next, previous directly from the widget
- Album art — fetched and cached automatically
- Menu bar app — runs silently in the background, no Dock icon
- Auto-starts at login — registers itself as a login item on first launch
- No API key — uses AppleScript to communicate with Spotify locally
- macOS 14.0 (Sonoma) or later
- Xcode 15+ with xcodegen (
brew install xcodegen) - Spotify desktop app installed
- Apple Developer account (free tier works)
macOS 26 Tahoe beta note: WidgetKit has a known rendering bug (NSHostingView SIGSEGV on dealloc) that causes third-party widgets to render blank. This is an Apple bug — bug report submitted (Feedback Assistant). The widget works correctly on macOS 14/15 Sonoma/Sequoia.
git clone https://github.com/saikiranchepuri/SpotifyWidget.git
cd SpotifyWidget
./setup.shThe script:
- Checks for
xcodegen(installs via Homebrew if missing) - Generates the Xcode project
- Builds and launches the app
- Clone the repo
- Run
xcodegen generate - Open
SpotifyWidget.xcodeproj - Set your Team in Signing & Capabilities for both targets
- Press ⌘R
- Right-click your desktop → Edit Widgets
- Search "Spotify"
- Drag to desktop or Notification Center
SpotifyWidget/
├── Shared/
│ ├── Constants.swift # App Group ID, keys, URL scheme
│ └── SpotifyState.swift # Shared data model
├── SpotifyWidgetApp/ # Main app (menu bar, no Dock icon)
│ ├── SpotifyAPI.swift # AppleScript bridge to Spotify
│ ├── DataManager.swift # Observes Spotify, writes to App Group
│ ├── AppDelegate.swift # Menu bar, URL scheme handler, login item
│ └── SpotifyWidgetApp.swift # @main entry point
└── SpotifyWidgetExtension/ # WidgetKit extension
├── SpotifyWidgetExtension.swift # TimelineProvider, Widget config
└── SpotifyWidgetView.swift # SwiftUI views (small/medium/large)
How it works:
- Main app observes
com.spotify.client.PlaybackStateChangedviaDistributedNotificationCenter - On change, reads track info via AppleScript and writes to shared
UserDefaults(App Group) - Calls
WidgetCenter.reloadAllTimelines()to trigger widget refresh - Widget extension reads from the shared
UserDefaultsand renders the SwiftUI view - Widget buttons use
spotifywidget://URL scheme → main app handles commands via AppleScript
- No network requests except fetching album art from Spotify's CDN
- No data sent anywhere — all local
- AppleScript access to Spotify required (macOS will prompt once)
PRs welcome. Known areas for improvement:
- Liked/unliked song toggle
- Progress bar / seek
- macOS 26 Tahoe compatibility (waiting on Apple WidgetKit fix)
MIT — free to use, modify, and distribute.
Inspired by Spotify4BigSur