Profile
Back to NewsBack
GitHub Trending 8 min
Reader Mode
folivoraAI/BetterTouchToolPlugins: Development of BetterTouchTool Plugins

folivoraAI/BetterTouchToolPlugins: Development of BetterTouchTool Plugins

9 hours ago

BetterTouchTool Plugins

This repository is the public home for BetterTouchTool plugin examples, reviewed community plugins, and the older Xcode bundle development project.

For most new plugins, use a single Swift source file. Drop the .swift file onto the BetterTouchTool preferences window, or copy it into the BetterTouchTool Plugins folder. BetterTouchTool will ask before compiling and loading it.

Official Documentation

Read the BetterTouchTool plugin documentation for the complete plugin API overview, installation flow, and current development guidance.

Plugin Gallery

The repository includes a static, searchable plugin gallery in site. It reads the official and community plugin manifests and can be published with GitHub Pages.

Update the generated gallery catalog after changing plugin metadata:

node tools/build-site-catalog.mjs

The GitHub Pages workflow in .github/workflows/plugin-gallery.yml runs the same generator and publishes the site folder.

Repository Structure

.github/workflows/plugin-gallery.yml  GitHub Pages publisher for the gallery
site/                                Static searchable plugin gallery
tools/build-site-catalog.mjs          Gallery catalog generator

plugins/ index.json Reviewed plugin registry official/ Examples maintained by BetterTouchTool community/ Reviewed user-submitted plugins _template/ Starting point for pull requests

xcode-bundle-examples/ Advanced / legacy Xcode bundle project BetterTouchToolPluginDevelopment.xcodeproj BTTPluginSupport/ BTTDisplayNotificationActionPlugin/ BTTStreamDeckPluginCPUUsage/ BTTTouchBar...

LICENSE README.md

Plugin Types

BetterTouchTool supports these plugin types:

| Type | Typical Use | |---|---| | Launcher | Add native rows, commands, saved instances, and surfaces to the BTT launcher | | Action | Add a custom action to the action picker | | Trigger | Observe external state and fire BTT triggers | | FloatingMenuWidget | Add native widgets to floating menus | | StreamDeck | Add Stream Deck widgets | | TouchBar | Add Touch Bar widgets |

Swift Source Plugins

A Swift source plugin is just a .swift file with metadata comments and a class that conforms to one of the BTT plugin protocols.

// BTT-Plugin-Name: Hello Launcher
// BTT-Plugin-Identifier: com.example.hello-launcher
// BTT-Plugin-Type: Launcher
// BTT-Plugin-Icon: hand.wave

import Cocoa

final class HelloLauncher: NSObject, BTTLauncherPluginInterface { weak var delegate: (any BTTLauncherPluginDelegate)?

static func launcherPluginName() -> String { "Hello Launcher" } static func launcherPluginDescription() -> String { "Shows one launcher result." } static func launcherPluginIcon() -> String { "hand.wave" }

func launcherResults(for context: BTTLauncherPluginContext) -> [BTTLauncherPluginResult]? { let result = BTTLauncherPluginResult() result.itemIdentifier = "hello" result.title = "Hello from BetterTouchTool" result.subtitle = "This row came from a Swift source plugin." result.systemImageName = "hand.wave" return [result] } }

SwiftUI State Compatibility

For SwiftUI source plugins that support standalone Command Line Tools and older macOS SDKs, use a uniquely named local alias for the State property wrapper:

import SwiftUI

private typealias MyPluginState<Value> = SwiftUI.State<Value>

private struct EditorView: View { @MyPluginState private var text = ""

var body: some View { TextField("Text", text: $text) } }

SDK 27 also declares an @State macro, but some standalone tools packages lack its SwiftUIMacros implementation. The distinct alias selects the existing property wrapper and retains its earlier initialization behavior. This does not provide other missing macros or the new macro's lazy initialization semantics. The Quick Links example uses this pattern.

Install

Use one of these:

  • drag the .swift file onto the BetterTouchTool preferences window
  • use File > Open in BetterTouchTool and select the .swift file
  • copy the file to ~/Library/Application Support/BetterTouchTool/Plugins/
BetterTouchTool compiles source plugins with swiftc. Xcode Command Line Tools must be installed.

Official Examples

| Plugin | Type | What It Shows | |---|---|---| | Sample Launcher | Launcher | Rows, children, commands, variables, named triggers, and a native surface | | Quick Links | Launcher | Saved plugin instances, editor surfaces, URL templates, and commands | | 1Password Launcher Example | Launcher | Searching 1Password items through the op CLI | | Google Search Launcher | Launcher | Opening launcher queries as Google searches | | Caffeinate | Launcher | Toggling a background caffeinate process from the launcher | | Launcher Falling Blocks | Launcher | A SwiftUI game hosted in a launcher surface | | Launcher Pong | Launcher | Another interactive SwiftUI launcher-surface game | | Clipboard Change | Trigger | Firing BTT triggers when the clipboard changes | | File Watcher | Trigger | Watching a configured file or folder and firing BTT triggers | | Compress Finder Selection | Action | Creating zip archives from Finder selections | | Finder Convert Selected Image to JPEG | Action | Converting a selected Finder image to JPEG | | Analog Clock | FloatingMenuWidget | A native analog clock floating menu widget |

The registry for these plugins lives in plugins/index.json.

Community Plugins

plugins/community contains user-generated plugins submitted through pull requests. Each accepted plugin has its own folder with source, metadata, description, screenshots when useful, and safety notes.

The first imported community collection comes from jhasubhash/btt-plugins. Each imported plugin README includes the original source link, import commit, copyright attribution, and upstream license note.

| Plugin | Type | What It Shows | |---|---|---| | Copy Path / URL | Action | Copy the front app document path or active browser tab URL | | Cursor Launcher | Launcher | Open recent Cursor workspaces | | GitHub PR Monitor | Launcher | Browse open pull requests through the gh CLI | | Jira Issues | Launcher | Browse Jira issues and custom JQL results | | Kill Process | Launcher | List and terminate running processes | | News Search | Launcher | Search Google News with a native preview surface | | Quick Links | Launcher | Save and open reusable URL or path templates | | QuickTime Recording | Launcher | Start QuickTime recordings | | Stock Prices | Launcher | Track stock quotes and watchlists | | Code Launcher | Launcher | Open recent Visual Studio Code workspaces | | Xcode Recent Projects | Launcher | Open recent Xcode projects and workspaces |

Required folder shape:

plugins/community/launcher-my-plugin/
  README.md
  plugin.json
  MyPlugin.swift
  screenshots/
    main.png

Start from plugins/_template when creating a new submission.

Folder Naming

Plugin folders must start with a type prefix:

  • launcher- for launcher plugins
  • floating- for floating menu widget plugins
  • action- for action plugins
  • trigger- for trigger plugins
  • streamdeck- for Stream Deck plugins
  • touchbar- for Touch Bar plugins

Review And Whitelisting

Native Swift plugins run inside BetterTouchTool's process, so community plugins are reviewed before they are shown as trusted or installable.

In this repository, "whitelisted" means:

  • the plugin was accepted into plugins/community
  • the plugin has a plugin.json manifest
  • the plugin is listed in plugins/index.json
  • reviewStatus is community-reviewed or official
  • the plugin README documents privacy-sensitive behavior
Review checklist:
  • source code is readable and intentionally scoped
  • plugin identifier is unique and stable
  • metadata comments match plugin.json
  • file, network, shell, AppleScript, clipboard, and accessibility behavior is documented
  • plugin does not collect or transmit unnecessary data
  • plugin does not auto-run destructive actions
  • plugin has a screenshot or short explanation when the UI is not obvious
  • plugin compiles in BetterTouchTool from a clean .swift file
Acceptance into the repository is not a full security audit. It is a curated review that makes the plugin suitable for discovery by BetterTouchTool users.

Plugin Manifest

Each plugin folder must include a plugin.json file:

{
  "schemaVersion": 1,
  "name": "Plugin Name",
  "identifier": "com.example.btt.plugin-name",
  "type": "Launcher",
  "entry": "Plugin.swift",
  "author": {
    "name": "Your Name",
    "url": "https://example.com"
  },
  "description": "Short description of what this plugin does.",
  "minimumBetterTouchToolVersion": "TBD",
  "permissions": ["clipboard-read"],
  "screenshots": ["screenshots/main.png"],
  "reviewStatus": "submitted",
  "origin": {
    "repository": "https://github.com/example/source-repo",
    "source": "https://github.com/example/source-repo/blob/main/Plugin.swift",
    "importedFromCommit": "commit-sha"
  },
  "copyright": "Copyright (c) Original Author.",
  "license": "MIT"
}

Use origin, copyright, and license when a plugin is imported from another repository or adapted from existing source.

Allowed reviewStatus values:

  • submitted: used in pull requests before review
  • community-reviewed: accepted community plugin
  • official: maintained by the BetterTouchTool project
  • deprecated: kept for reference but hidden from normal discovery
Allowed permission labels:
  • clipboard-read
  • clipboard-write
  • file-read
  • file-write
  • network
  • open-url
  • shell
  • apple-script
  • accessibility
  • btt-variables
  • named-triggers
  • launcher-plugin-instances
  • user-defaults
  • process-control
  • spotlight

Submitting A Plugin

  1. Copy plugins/_template to a type-prefixed folder such as plugins/community/launcher-your-plugin-name.
  2. Rename Plugin.swift and update the metadata comments.
  3. Fill out plugin.json.
  4. Add screenshots if the plugin has visible UI.
  5. Add safety notes to the plugin README.
  6. Open a pull request.
Pull requests must keep plugin code self-contained. If your plugin needs an Xcode project, explain why and place it in a clearly named subfolder.

Xcode Bundle Plugins

The older multi-target Xcode project now lives in xcode-bundle-examples.

Use the Xcode bundle path when a plugin needs:

  • multiple source files
  • bundled resources
  • third-party dependencies
  • custom framework setup
  • explicit signing and notarization
Open:
xcode-bundle-examples/BetterTouchToolPluginDevelopment.xcodeproj

Bundle plugins are still useful, but the single-file Swift source plugin path is the default starting point for most users.

License

See LICENSE.

Our Related Projects
Farm Fresh Kikapu

An e-commerce platform for farm-fresh produce - an online st...

View Project
Chat with me