Perch is a macOS menu bar app that places a persistent pill-shaped island at the top center of your screen. On MacBooks with a physical notch, it integrates naturally into the notch area. On non-notch Macs, it floats as a standalone Dynamic Island–style pill.
Hover or click to expand. Get at-a-glance information on your AI usage, what's playing, and upcoming developer features — all without leaving your current app.
Note
Perch is not distributed via the Mac App Store. It uses window level APIs and authentication methods incompatible with the sandbox. Distribution is via GitHub Releases and Homebrew Cask.
Warning
Perch is currently in beta and not yet publicly available for download. The options below will be enabled at v1.0 release.
Homebrew Cask (coming at v1.0):
brew tap tukuyomil032/tap
brew install --cask perchGitHub Releases (coming soon): Download the signed .dmg from the Releases page and drag Perch.app to your Applications folder.
Once installed, Perch launches at login and appears as a pill at the top center of your screen. No further configuration is required to get started.
- Pill-shaped overlay window positioned relative to the physical notch (or floating on non-notch screens)
- Hover to expand, auto-collapse on mouse leave
- Metal SDF metaball animation during transitions
- Menu bar icon, login item support
- Detects playback from Spotify, Apple Music, and YouTube Music
- Album artwork, playback controls (play/pause, skip)
- Lyrics display via LRCLIB
- Audio waveform visualizer
- Tracks usage for Claude, Codex, OpenAI, and OpenRouter
- Displays remaining quota, cost estimate, and reset countdown
- Per-provider cards in the expanded island view
Perch's tabs are not feature switches — they are user-defined widget layout presets. New features are implemented as widgets conforming to PerchWidget and registered at launch:
nonisolated struct MyWidget: PerchWidget {
let id = "myWidget"
let supportedSizes: Set<WidgetSize> = [.compact, .standard]
func body(size: WidgetSize) -> AnyView { ... }
}
// In AppDelegate:
appState.widgetRegistry.register(MyWidget())The preset and widget infrastructure (PresetStore, WidgetRegistry, WidgetLayout, WidgetProtocol) is stable and must not be modified without understanding the full system.
| Requirement | Version |
|---|---|
| macOS | 14 Sonoma or later |
| Xcode | 16 or later |
| Swift | 6 |
| Architecture | Apple Silicon, Intel |
Clone and open in Xcode:
git clone https://github.com/tukuyomi032/perch.git
open perch.xcodeprojBuild from the command line:
xcodebuild -scheme perch -configuration Debug buildUsing just (requires brew install just xcbeautify):
just build # Debug build
just test # Run unit tests
just format # Format Swift source filesTip
Run just setup to verify dev tools are installed and configure Git hooks via Lefthook.
UI Layer (SwiftUI)
├─ CompactPillView — pill UI, hover trigger
├─ ExpandedIslandView — full card layout
├─ DesignSystem — design tokens (grid, radius, animation curves)
└─ SettingsView — preferences UI
Core Layer
├─ AppState — @Observable global state
├─ EventBus — decoupled event propagation
├─ PresetStore — widget preset CRUD + persistence
├─ WidgetRegistry — widget registration and lookup
└─ RefreshScheduler — actor-based periodic update loop
Integration Layer (AppKit)
├─ IslandWindow — transparent NSWindow overlay
├─ NotchDetector — detects notch presence and dimensions
├─ IslandGeometry — frame calculation per screen/mode
└─ MouseEventMonitor — hover and click detection
AppKit handles all window management. SwiftUI handles all visible content. They are bridged via NSHostingController.
| Package | Version | Purpose |
|---|---|---|
| BigInt | 5.7.0 | Arbitrary-precision integer arithmetic |
| CryptoSwift | 1.10.0 | Cryptographic functions |
| Defaults | 9.0.6 | Type-safe UserDefaults persistence |
| FrameworkToolbox | 0.7.1 | AppKit/Cocoa framework utilities |
| KeyboardShortcuts | 2.4.0 | Global keyboard shortcut registration |
| LyricsKit | 1.9.0 | Lyrics fetching and parsing |
| mediaremote-adapter | master | MediaRemote framework bridge |
| Regex | 1.0.1 | Regular expression matching |
| swift-async-algorithms | 1.1.4 | Async sequence algorithms |
| swift-collections | 1.5.1 | Efficient data structures |
| swift-log | 1.13.1 | Structured logging |
| swift-syntax | 602.0.0 | Swift parser and syntax utilities |
| SwiftCF | 0.2.2 | CoreFoundation Swift wrappers |
| Sparkle | 2.9.1+ | Over-the-air updates (Phase 6) |
| Phase | Version | Scope | Status |
|---|---|---|---|
| 0 | — | Project scaffolding | ✅ |
| 1 | v0.1 | Core Island UI | ✅ |
| 2 | v0.2 | Now Playing | ✅ |
| 3 | v0.3 | AI Usage tracking | ✅ |
| 3.5 | — | Visual polish, Now Playing fixes | 🚧 In progress |
| 4 | v0.4 | File Shelf (drag & drop, Quick Look, AirDrop) | Planned |
| 5 | v0.5 | Dev Status (GitHub Actions, CI notifications) | Planned |
| 6 | v1.0 | Sparkle, Homebrew Cask, stabilization | Planned |
perch/
App/ — entry point, AppDelegate, MenuBarController
Core/ — AppState, EventBus, Preferences, WidgetRegistry
Island/ — IslandWindow, NotchDetector, IslandGeometry, MouseEventMonitor
UI/ — SwiftUI views and DesignSystem
Features/ — NowPlaying, AIUsage (self-contained feature modules)
Providers/ — Claude, Codex, OpenAI, OpenRouter
Resources/ — Assets, Info.plist, Entitlements, Localizations
perchTests/ — Unit tests
docs/ — Design references, progress log, specs
@MainActoron all UI-touching classes (AppState, view models, controllers)@Observablefor state management — avoidObservableObject/@Publishedactorfor concurrent services (e.g.RefreshScheduler)- AppKit for window control; SwiftUI for display content
DesignSystem.swift is the single source of truth for visual constants:
| Token | Value |
|---|---|
| Grid unit | 4pt |
| Pill corner radius | 17pt (continuous) |
| Card corner radius | 28pt (continuous) |
| Typography | SF Pro / SF Mono (system fonts only) |
| Background material | NSVisualEffectView .ultraDark vibrancy |
Note
Perch follows hallmark anti-AI-slop design rules. Avoid generic LLM-flavored UI. When in doubt, reference macOS HIG and the existing DesignSystem.
- Boring Notch — Dynamic Island UI, Now Playing patterns
- NotchDrop — transparent window control, notch detection
- CodexBar — AI usage monitoring, provider separation design