A tiny, free, open-source window switcher for macOS, inspired by AltTab.
Hold Option, tap Tab: a grid of live thumbnails appears — one per open window (not per app). Keep tapping Tab (or Shift+Tab) to cycle, release Option or click a thumbnail to switch. Prefer ⌘Tab? Assign it from the menu bar and TabLab takes over the system app switcher entirely.
No settings window, no themes, no telemetry, no Dock icon — just a menu bar item with a hotkey picker and Quit.
- Per-window switching — an app with 3 windows shows 3 thumbnails, including minimized windows and windows on other Spaces.
- Live thumbnails in a multi-row grid (up to 5 columns), sized for readability.
- Choice of trigger: ⌥Tab (default) or ⌘Tab. The hotkey is intercepted with a
CGEventTapand consumed, so when assigned to ⌘Tab, macOS's native switcher never appears — TabLab owns the shortcut. The choice persists across launches. - Keyboard & mouse: Tab / Shift+Tab to cycle, release to switch, click to switch instantly, Esc to cancel.
- ~600 lines of Swift, zero dependencies.
- macOS 13+
- Xcode Command Line Tools (
xcode-select --install) to build
git clone https://github.com/mmukhlef/TabLab.git
cd TabLab
./build.sh
open TabLab.app # or: cp -r TabLab.app /Applications/ firstbuild.sh signs the bundle with your first available "Apple Development" identity so the code-signing identity stays stable across rebuilds and macOS doesn't drop the app's permissions each time you rebuild. Without one it falls back to ad-hoc signing, which works but requires re-granting permissions after every rebuild.
On first launch TabLab asks for two permissions, both in System Settings → Privacy & Security:
- Accessibility — required. Used to intercept the trigger hotkey globally and to raise/focus windows. TabLab polls until you grant it (menu bar icon shows ⏳ while waiting, ⇥ once ready).
- Screen Recording — optional but recommended. Used only to capture window thumbnails. Without it, TabLab falls back to app icons.
| Action | Effect |
|---|---|
| Hold modifier + Tab | Open switcher (selection starts on the previous window) |
| Tab / Shift+Tab (still holding) | Cycle forward / backward |
| Release modifier | Switch to selected window |
| Click a thumbnail | Switch to it immediately |
| Esc | Cancel |
To change the trigger: click the ⇥ menu bar icon → Option ⌥Tab or Command ⌘Tab.
To launch at login: System Settings → General → Login Items → add TabLab.app.
| File | Role |
|---|---|
Sources/TabLab/HotkeyMonitor.swift |
Session-level CGEventTap that intercepts and consumes the trigger hotkey |
Sources/TabLab/WindowManager.swift |
Enumerates windows via the Accessibility API (AXUIElement), orders them by z-index, captures thumbnails, raises/focuses on selection |
Sources/TabLab/SwitcherPanel.swift |
The non-activating HUD panel with the thumbnail grid |
Sources/TabLab/SwitcherController.swift |
Selection state between hotkey events and the panel |
Sources/TabLab/AppDelegate.swift |
Menu bar item, permission flow, hotkey preference |
tools/generate_icon.swift |
Procedurally renders the app icon (origami paper Tab keycap) and emits the iconset |
The app is a plain SwiftPM executable wrapped into a .app bundle by build.sh — no Xcode project.
TabLab is intentionally minimal. Settings windows, themes, per-app filtering, window previews on hover, and similar are out of scope. If you need the full-featured experience, use AltTab — it's excellent and also free.
MIT. Inspired by AltTab's UX; implemented independently from scratch.