A modern macOS menu bar application for managing AeroSpace window manager spaces and windows with a beautiful SwiftUI interface
AeroSpaceBar is a macOS menu bar application that provides seamless integration with the AeroSpace window manager. Built with modern SwiftUI and following Clean Architecture principles, it offers an intuitive interface for managing your workspace spaces and windows directly from the menu bar.
- 🎨 Beautiful UI: Modern SwiftUI interface with smooth animations and hover effects
- ⚡ Lightning Fast: Optimized performance with efficient data refresh and icon caching
- 🔒 Privacy Focused: Runs entirely locally, no data sent to external servers
- 🔧 Spaces & Groups: Organize and manage workspace windows and menubar groups with custom ranges and settings
- 🎨 Advanced Theming: Comprehensive theme system with presets and per-space customization
- 🌐 System Integration: Automatic menu bar visibility matching and wallpaper detection
- 🔄 Software Updates: Automatic update checking and installation via Sparkle
- ⚙️ TOML Configuration: Native support for AeroSpace TOML configuration file monitoring
- ⌨️ Keyboard Shortcuts: Global key detection and shortcut support
- macOS 15.0+ (Sequoia or later)
- AeroSpace window manager installed and running
Note
By using AeroSpaceBar, you acknowledge that it's not notarized.
Notarization is a "security" feature by Apple. You send binaries to Apple, and they either approve them or not. In reality, notarization is about building binaries the way Apple likes it.
The Homebrew installation script is configured to
automatically delete the com.apple.quarantine attribute, that's why when installed via Homebrew the app should work out of
the box, without any warnings that "Apple cannot check AeroSpaceBar for malicious software".
If you install manually and macOS blocks the app from launching:
- Right-click the app in Finder and choose "Open", then click "Open" again in the dialog
- Or go to System Settings → Privacy & Security → click "Allow Anyway" for AeroSpaceBar
- Or run:
xattr -dr com.apple.quarantine "/Applications/AeroSpaceBar.app"
brew tap rdrkr/tap
brew install --cask aerospacebarOr in one command:
brew install --cask rdrkr/tap/aerospacebar- Visit the Releases page
- Download the latest
.zipfile - Extract and drag
AeroSpaceBar.appto your Applications folder
git clone https://github.com/rdrkr/AeroSpaceBar.git
cd AeroSpaceBar
./Scripts/build.shThe built app will be at build/Build/Products/Release/AeroSpaceBar.app.
You can also open AeroSpaceBar.xcodeproj in Xcode and build with Cmd + R.
- Ensure AeroSpace is running (
aerospace start) - Launch AeroSpaceBar - the app icon appears in your menu bar
- Click the menu bar icon to see all available spaces
- Click any space to switch to it, or hover to preview its windows
- Access Settings via the app menu (
Cmd + ,)
- General: Appearance, behavior, and basic settings
- Groups: Menu bar group organization and per-group visual customization
- Spaces: Per-space visual properties and appearance
- Advanced: Theme presets, TOML configuration, and software updates
- Developer: Logging, performance metrics, and feature flags
Cmd + ,: Open settings windowCmd + Q: Quit application
For keyboard-driven workflow, use Raycast (free for personal use):
press Cmd + Space, type "Search Menu Items", and search for "AeroSpaceBar" to quickly access menu options.
brew update
brew upgrade --cask aerospacebarAeroSpaceBar checks for updates automatically (configurable in Settings → Advanced → Software Updates). You'll be notified when a new version is available.
Download the latest release from the Releases page and replace the existing app in your Applications folder.
# Uninstall the app
brew uninstall --cask aerospacebar
# Remove all application data (optional)
brew uninstall --cask --zap aerospacebar# Delete the app
rm -rf /Applications/AeroSpaceBar.app
# Remove application data (optional)
rm -rf ~/Library/Application\ Support/com.rdrkr.AeroSpaceBar
rm -rf ~/Library/Caches/com.rdrkr.AeroSpaceBar
rm ~/Library/Preferences/com.rdrkr.AeroSpaceBar.plist- Xcode 16.3+ with Swift 6.2+
- SwiftFormat and SwiftLint:
brew install swiftformat swiftlint - pre-commit (optional):
brew install pre-commit && pre-commit install
AeroSpaceBar follows the MVVM Clean Architecture pattern with three SPM packages:
- Domain (
Packages/Domain): Business logic, entities, use cases, and gateway protocols. No external dependencies. - Data (
Packages/Data): Repository implementations, AeroSpace CLI client, and data models. - Presentation (
Packages/Presentation): SwiftUI Views and MVVM ViewModels using Combine.
Architecture Benefits:
- Separation of Concerns: Clear boundaries between business logic, data access, and UI
- Testability: Each layer can be tested independently
- Dependency Injection: Centralized dependency management through DependencyContainer
- Protocol-Oriented Design: Interface segregation and dependency inversion
- Use Case Pattern: Each business operation isolated in its own use case class
AeroSpaceBar/
├── 📁 AeroSpaceBar/ # Main application target
│ ├── 📄 AeroSpaceBarApp.swift # SwiftUI app entry point
│ ├── 📄 Info.plist # App customizations
│ ├── 📄 AeroSpaceBar.entitlements # App entitlements
│ └── 📁 Resources/ # App-specific resources
├── 📁 Packages/ # Swift Package Manager packages
│ ├── 📁 Data/ # Data Access Layer
│ ├── 📁 Domain/ # Business Logic Layer
│ └── 📁 Presentation/ # UI Layer
├── 📁 AeroSpaceBar.xcodeproj/ # Xcode Project
├── 📁 Scripts/ # Build, release, and automation scripts
├── 📁 Docs/ # Documentation and assets
├── 📄 appcast.xml # Sparkle update feed
├── 📄 CHANGELOG.md # Release notes and version history
└── 📄 README.md # This file
./Scripts/build.sh # Build Release
./Scripts/build.sh -c Debug # Build Debug
./Scripts/build.sh --clean # Clean and buildThe Xcode project includes a pre-build script that automatically runs SwiftFormat and SwiftLint. If linting fails, the build fails.
# Run all tests
xcodebuild test -project AeroSpaceBar.xcodeproj -scheme AeroSpaceBar
# Run specific test targets
xcodebuild test -project AeroSpaceBar.xcodeproj -scheme AeroSpaceBar -only-testing:DomainTests
xcodebuild test -project AeroSpaceBar.xcodeproj -scheme AeroSpaceBar -only-testing:DataTests
xcodebuild test -project AeroSpaceBar.xcodeproj -scheme AeroSpaceBar -only-testing:PresentationTestsOr press Cmd + U in Xcode.
- TOMLKit: TOML configuration file parsing
- AsyncFileMonitor: Async file system monitoring
- Sparkle: Software update framework
- LemonSqueezy: License management SDK
- ModifiedCopyMacro: Swift macro for immutable copy modifications
Releases are automated via ./Scripts/release.sh or GitHub Actions.
The app checks for updates via Sparkle at:
https://raw.githubusercontent.com/rdrkr/AeroSpaceBar/main/appcast.xml
AeroSpaceBar uses Sparkle 2 for automatic software updates. Updates are signed with EdDSA signatures to ensure authenticity.
-
Generate EdDSA Signing Keys (one-time setup)
# Download Sparkle tools from https://github.com/sparkle-project/Sparkle/releases/latest # Extract and run: ./Sparkle-2.x.x/bin/generate_keys
This outputs a private key (keep SECRET) and a public key (set as
SUPublicEDKeyin Info.plist). -
Store Credentials
macOS Keychain (recommended for local development):
# Store Sparkle private key security add-generic-password \ -s "sparkle-private-key" \ -a "sparkle" \ -w "YOUR_SPARKLE_PRIVATE_KEY_HERE" # Store GitHub token security add-generic-password \ -s "AeroSpaceBar-github-token" \ -a "github" \ -w "YOUR_GITHUB_TOKEN_HERE"
Release scripts check macOS Keychain first, then fall back to environment variables.
GitHub Secrets (required for CI/CD):
Secret Description CERTIFICATES_P12Base64-encoded Apple Developer ID certificate (P12) CERTIFICATES_PASSWORDPassword for the P12 certificate NOTARIZATION_APPLE_IDApple Developer account email NOTARIZATION_PASSWORDApp-specific password from appleid.apple.com NOTARIZATION_TEAM_IDApple Developer Team ID (10-character code) SPARKLE_PRIVATE_KEYSparkle EdDSA private key for signing updates
Automated (recommended):
./Scripts/release.sh --version 1.0.1This validates pre-flight checks, builds, signs, notarizes, creates a GitHub release, updates appcast.xml, and pushes.
Via GitHub Actions:
- Go to Actions → Release → Run workflow
- Enter the version number
Available Scripts:
| Script | Purpose |
|---|---|
version.sh |
Get current version from Xcode project |
bump-version.sh |
Update version in Xcode project |
build.sh |
Build app using xcodebuild |
preflight-check.sh |
Validate release readiness |
release.sh |
Complete automated release workflow |
sign-and-notarize.sh |
Code signing and Apple notarization |
create-dmg.sh |
Create distributable DMG |
update-appcast.sh |
Update appcast with new release entry |
update-cask.sh |
Update Homebrew cask formula |
verify-appcast.sh |
Validate appcast XML structure |
generate-appcast.sh |
Regenerate appcast from GitHub releases |
changelog-to-html.sh |
Convert CHANGELOG.md section to HTML |
We welcome contributions! Here's how:
-
Fork the repository
-
Create a feature branch:
git checkout -b feature/amazing-feature -
Make your changes and add tests for new functionality
-
Ensure code is formatted and tests pass:
swiftformat . swiftlint --fix ./Scripts/build.sh --clean xcodebuild test -project AeroSpaceBar.xcodeproj -scheme AeroSpaceBar
-
Submit a pull request with a clear description of changes
- Follow SwiftLint rules and Clean Architecture principles
- Write unit tests for new functionality
- Document public APIs using Swift documentation markup
- Include screenshots for UI changes
- Use meaningful commit messages
- 📖 Documentation: Check this README and Wiki
- 💬 Discussions: Ask questions and share ideas in GitHub Discussions
- 🐛 Bug Reports: Report issues on GitHub Issues
- 💡 Feature Requests: Suggest new features in GitHub Issues
- ⭐ Star the Project: Show your support!
- Be respectful and constructive
- Search existing issues before creating new ones
- Provide detailed information when reporting bugs
- AeroSpace: The amazing window manager that makes this possible
- VibeMeter: Inspiration for build and release automation scripts
- Clean Architecture MVVM: Architecture inspiration
- TOMLKit: TOML parsing library for AeroSpace configuration files
- AsyncFileMonitor: Async file monitoring for configuration changes
- Sparkle: Software update framework
- LemonSqueezy: License management SDK
- ModifiedCopyMacro: Swift macro for immutable modifications
Made with ❤️ by Ronen Druker
⭐ Star this repo | 🐛 Report a bug | 💡 Request a feature | 💬 Discussions
