Manage your Switcheroo keyboard remapper configuration from Raycast.
Store status: submission #31064 is awaiting Raycast review. There is no Store install yet. For local use, see Local install before Store approval.
The extension edits configuration and requests service restarts. The separate Switcheroo daemon performs the remapping. Installing one does not install the other, and you can use the daemon without Raycast.
If you already have a standalone daemon, follow the migration guide before starting a Homebrew service. Never run both providers at once.
brew tap mitchelljphayes/switcheroo
brew install switcheroo
The active file is ~/.config/switcheroo/config.toml. This creates a sample only when no existing file or symlink is present:
mkdir -p "$HOME/.config/switcheroo"
config="$HOME/.config/switcheroo/config.toml"
if [ ! -e "$config" ] && [ ! -L "$config" ]; then
cp "$(brew --prefix)/etc/switcheroo/config.toml" "$config"
fi
open -e "$config"
Review the sample before enabling it—it changes keyboard behavior. Existing configs are not overwritten.
Run echo "$(brew --prefix switcheroo)/Switcheroo.app" to get the app path. In System Settings → Privacy & Security → Accessibility, click +, use ⌘⇧G to navigate to that path, add Switcheroo.app, and enable access.
For a standalone install, the app is at ~/.local/bin/Switcheroo.app. Grant permission to the daemon app, not just Raycast.
Note: ad-hoc signing means Accessibility permission may need re-granting after each
brew upgradeor rebuild.
brew services start switcheroo
brew services info switcheroo
switcheroo --version
Test a configured mapping before opening the extension. For standalone builds, use the source installation guide instead of Homebrew service commands.
The extension supports both install layouts:
brew services): label homebrew.mxcl.switcheroo,
restarted via launchctl kickstart -k. This is the pre-existing
Homebrew lifecycle managed by brew services.install.sh): label
com.mitchelljphayes.switcheroo. When loaded, the extension requests
a graceful launchctl kill SIGTERM (the daemon handles SIGTERM to
clean up kernel-level mappings) and verifies the plist has
KeepAlive=true so launchd relaunches the daemon automatically.
The UI reports "Restart requested" — relaunch is asynchronous and
not polled or guaranteed. When absent, the extension bootstraps
the daemon from the verified plist. The extension verifies the
plist identity before restarting and refuses ambiguous or foreign jobs.The extension auto-detects which layout is active and refuses to restart a foreign/ambiguous job. If neither is running, it shows an actionable error with install instructions.
Requires Raycast and Node.js/npm. The latest submitted extension is on the PR's fork branch; it may be ahead of the copy in the daemon repository:
git clone --depth 1 --filter=blob:none --sparse --branch ext/switcheroo https://github.com/mitchelljphayes/raycast-extensions.git switcheroo-raycast
cd switcheroo-raycast
git sparse-checkout set extensions/switcheroo
cd extensions/switcheroo
npm ci
npm run dev
When the build finishes, open View Remaps in Raycast. Stop the development watcher with Ctrl+C when done; the built extension remains available, and the daemon keeps running independently. Start the watcher again only when developing.
Once Raycast approves the Store submission, install the Store version and remove any duplicate local development entry in Raycast Settings → Extensions.
npm run dev from the extension directory. Homebrew installs the daemon, not Raycast's compiled commands.~/Library/Logs/com.mitchelljphayes.switcheroo/.For the Homebrew daemon, use brew update, brew upgrade switcheroo, then brew services restart switcheroo. Recheck Accessibility permission after an upgrade. To uninstall, stop it with brew services stop switcheroo before brew uninstall switcheroo. See the tap README for migration and recovery cautions.
Removing the Raycast UI in Settings → Extensions is separate from stopping or uninstalling the daemon. Keep your config if you plan to reinstall.
From an existing extension checkout, use npm ci and npm run dev. Run npm run build to validate a distribution build.
This extension has two lint tiers:
npm run lint:ci — local code-quality gate (ESLint + Prettier on
src/**). Used by CI and for everyday development. No network access.npm run lint (i.e. ray lint) — full Raycast Store validation.
This additionally validates package.json metadata (schema, icons) and
performs an external Store-author API check against
https://www.raycast.com/api/v1/users/<author>. The author field must
be a registered Raycast Store author handle (not a display name) for
this check to pass. Run it before submitting to the Raycast Store; Store
submission CI also runs the full check.