A tiny menu bar app that runs shell scripts when macOS switches between Light and Dark mode.
- Automatically detects macOS appearance changes
- Supports separate scripts for Light and Dark modes
- Optional command-line arguments for each script
- Sets
THEME_MODE=darkorTHEME_MODE=lightenvironment variable for scripts - Remembers the last theme state — scripts only run on actual changes, not on every app launch
- Menu bar icon reflects the current mode (☀️ / 🌙)
- "Run Dark Script" / "Run Light Script" menu items for quick testing
- Optional Launch at Login
- 30-second execution timeout for safety
- Script validation (checks if file exists and is executable)
Download the latest ThemeSync.app.zip from GitHub Releases, unzip, and drag ThemeSync.app to /Applications.
The app is ad-hoc signed (no Apple Developer ID). On first launch, right-click → Open to bypass Gatekeeper.
make appThis creates build/ThemeSync.app. The bundle is stamped with the latest git tag's version (0.0.0 if no tags exist); override with make app VERSION=x.y.z.
- Launch the app (double-click the
.app). - Click the menu bar item (shows as "TS" with a sun or moon icon).
- Click Open Settings to configure your scripts:
Script on Dark- path to script that runs when switching to Dark modeArgs on Dark- optional command-line arguments for the dark mode scriptScript on Light- path to script that runs when switching to Light modeArgs on Light- optional command-line arguments for the light mode scriptLaunch at Login- automatically start ThemeSync when you log in
- Use the Choose… buttons to browse for script files.
- Use Run Dark Script / Run Light Script from the menu to test without toggling system appearance.
make release VERSION=1.1.0This tags v1.1.0 and pushes the tag, which triggers a GitHub Actions workflow that builds the app and publishes a release.
- Scripts are executed directly, so use full paths to executables
- Scripts receive
THEME_MODE=darkorTHEME_MODE=lightas an environment variable - Arguments support whitespace splitting, quoted values, and backslash escaping; shell expansion and command chaining are not evaluated
- Scripts must be executable (
chmod +x your_script.sh) - Script execution times out after 30 seconds for safety; the timeout terminates the script and any processes it started
- The app validates script paths and logs errors if scripts are missing or not executable
- The app is a menu bar accessory and will not show in the Dock
- Minimum supported macOS version is 13.0 (Apple Silicon)
- Check Console.app for log messages from "com.likewinter.theme-sync" if scripts aren't running
- Ensure your scripts have execute permissions:
chmod +x /path/to/your/script - Test your scripts manually first to ensure they work correctly