Skip to content

BetterTouchTool

BetterTouchTool is a macOS automation app for customizing gestures, shortcuts, Touch Bar controls, Stream Deck buttons, menu bar items, and other system-level workflows.

Usage

There are two ways to use this library:

  • On-Demand import from subpaths enables tree-shaking and keeps bundles small.
  • Full Import from the root package is convenient but includes all app modules.

Pick On-Demand for production builds; Full Import is fine for quick scripts or demos.

Select Installation Method

On-Demand
Recommended. Optimized for production.
Full Import
Convenient. Good for quick scripts.

Trigger Named

Run a named trigger, pass values to it as BetterTouchTool variables, or cancel its delayed execution.

On-Demand
ts
import { triggerNamed } from 'protocol-launcher/bettertouchtool'

const reviewUrl = triggerNamed({
  triggerName: 'Daily Review',
})

const projectUrl = triggerNamed({
  triggerName: 'Open Project',
  variables: {
    projectName: 'Protocol Launcher',
  },
})

const cancelUrl = triggerNamed({
  triggerName: 'Daily Review',
  cancelDelayed: 1,
})

Trigger Named Async Without Response

Run a named trigger asynchronously without waiting for a response.

On-Demand
ts
import { triggerNamedAsyncWithoutResponse } from 'protocol-launcher/bettertouchtool'

const url = triggerNamedAsyncWithoutResponse({
  triggerName: 'Refresh Dashboard',
})

Cancel Delayed Named Trigger Execution

Cancel a pending delayed execution of a named trigger.

On-Demand
ts
import { cancelDelayedNamedTriggerExecution } from 'protocol-launcher/bettertouchtool'

const url = cancelDelayedNamedTriggerExecution({
  triggerName: 'Daily Review',
})

Execute Assigned Actions For Trigger

Execute all assigned actions for an existing trigger identified by UUID.

On-Demand
ts
import { executeAssignedActionsForTrigger } from 'protocol-launcher/bettertouchtool'

const url = executeAssignedActionsForTrigger({
  uuid: '0E2F7963-E64C-403A-8591-C3725D4D9ADC',
})

Trigger Action

Run a BetterTouchTool predefined action from an action JSON object.

On-Demand
ts
import { triggerAction } from 'protocol-launcher/bettertouchtool'

const url = triggerAction({
  json: {
    BTTPredefinedActionType: 153,
    BTTPredefinedActionName: 'Move Mouse To Position',
    BTTMoveMouseToPosition: '{100, 10}',
    BTTMoveMouseRelative: '6',
  },
})

Refresh Widget

Run all scripts assigned to a script widget and update its contents.

On-Demand
ts
import { refreshWidget } from 'protocol-launcher/bettertouchtool'

const url = refreshWidget({
  uuid: 'CC46E199-B07D-4BF7-AC36-48AAE558540B',
})

Update Touch Bar Widget

Update the contents of a Touch Bar Script Widget.

On-Demand
ts
import { updateTouchBarWidget } from 'protocol-launcher/bettertouchtool'

const url = updateTouchBarWidget({
  uuid: 'CC46E199-B07D-4BF7-AC36-48AAE558540B',
  text: 'Build passed',
  iconPath: '/Users/andi/Desktop/status.png',
  backgroundColor: '200,200,100,255',
})

Update Stream Deck Widget

Update the contents of a Stream Deck widget.

On-Demand
ts
import { updateStreamDeckWidget } from 'protocol-launcher/bettertouchtool'

const url = updateStreamDeckWidget({
  uuid: 'CC46E199-B07D-4BF7-AC36-48AAE558540B',
  text: 'Deploy',
})

Update Menubar Item

Update the contents of a menu bar item.

On-Demand
ts
import { updateMenubarItem } from 'protocol-launcher/bettertouchtool'

const url = updateMenubarItem({
  uuid: 'CC46E199-B07D-4BF7-AC36-48AAE558540B',
  text: 'Ready',
})

Update Trigger

Update the configuration of an existing trigger.

On-Demand
ts
import { updateTrigger } from 'protocol-launcher/bettertouchtool'

const url = updateTrigger({
  uuid: '0E2F7963-E64C-403A-8591-C3725D4D9ADC',
  json: {
    BTTTouchBarButtonName: 'New Name2',
    BTTTriggerConfig: {
      BTTTouchBarItemIconHeight: 30,
    },
  },
})

Add New Trigger

Add a new trigger to BetterTouchTool from a trigger JSON object.

On-Demand
ts
import { addNewTrigger } from 'protocol-launcher/bettertouchtool'

const url = addNewTrigger({
  json: {
    BTTTriggerClass: 'BTTTriggerTypeKeyboardShortcut',
    BTTPredefinedActionType: 5,
    BTTPredefinedActionName: 'Mission Control',
    BTTAdditionalConfiguration: '1179658',
    BTTTriggerOnDown: 1,
    BTTEnabled: 1,
    BTTShortcutKeyCode: 2,
    BTTShortcutModifierKeys: 1179648,
    BTTOrder: 3,
  },
})

Delete Trigger

Delete a BetterTouchTool trigger by UUID.

On-Demand
ts
import { deleteTrigger } from 'protocol-launcher/bettertouchtool'

const url = deleteTrigger({
  uuid: '0E2F7963-E64C-403A-8591-C3725D4D9ADC',
})

Reveal Element In UI

Open the BetterTouchTool configuration UI and reveal an element by UUID.

On-Demand
ts
import { revealElementInUi } from 'protocol-launcher/bettertouchtool'

const url = revealElementInUi({
  uuid: '0E2F7963-E64C-403A-8591-C3725D4D9ADC',
})

Export Preset

Export a BetterTouchTool preset to a file.

On-Demand
ts
import { exportPreset } from 'protocol-launcher/bettertouchtool'

const url = exportPreset({
  name: 'Focus Mode',
  outputPath: '/Users/andi/Desktop/FocusMode.bttpreset',
  compress: 1,
})

Import Preset

Import a BetterTouchTool preset from a file path.

On-Demand
ts
import { importPreset } from 'protocol-launcher/bettertouchtool'

const url = importPreset({
  path: '/Users/andi/Desktop/FocusMode.bttpreset',
})

const keepExistingUrl = importPreset({
  path: '/Users/andi/Desktop/FocusMode.bttpreset',
  replaceExisting: 0,
})

Run Shortcut

Run an Apple Shortcuts shortcut by name and wait for its result.

On-Demand
ts
import { runShortcut } from 'protocol-launcher/bettertouchtool'

const url = runShortcut({
  shortcutName: 'Start Focus',
  input: 'Protocol Launcher',
})

Run Shortcut Async Without Response

Run an Apple Shortcuts shortcut asynchronously without waiting for a response.

On-Demand
ts
import { runShortcutAsyncWithoutResponse } from 'protocol-launcher/bettertouchtool'

const url = runShortcutAsyncWithoutResponse({
  shortcutName: 'Log Break',
  input: '5 minutes',
})

Set Persistent String Variable

Set a string variable that persists over BetterTouchTool relaunches.

On-Demand
ts
import { setPersistentStringVariable } from 'protocol-launcher/bettertouchtool'

const url = setPersistentStringVariable({
  variableName: 'currentProject',
  to: 'Protocol Launcher',
})

Set String Variable

Set a string variable for the runtime of BetterTouchTool.

On-Demand
ts
import { setStringVariable } from 'protocol-launcher/bettertouchtool'

const url = setStringVariable({
  variableName: 'sessionState',
  to: 'reviewing',
})

Set Persistent Number Variable

Set a number variable that persists over BetterTouchTool relaunches.

On-Demand
ts
import { setPersistentNumberVariable } from 'protocol-launcher/bettertouchtool'

const url = setPersistentNumberVariable({
  variableName: 'focusGoalMinutes',
  to: 45,
})

Set Number Variable

Set a number variable for the runtime of BetterTouchTool.

On-Demand
ts
import { setNumberVariable } from 'protocol-launcher/bettertouchtool'

const url = setNumberVariable({
  variableName: 'currentPomodoro',
  to: 2,
})

Import Via URL

Import a BetterTouchTool preset by providing a URL to download it from, optionally using the documented unzip path.

On-Demand
ts
import { importViaUrl } from 'protocol-launcher/bettertouchtool'

const url = importViaUrl({
  url: 'https://example.com/btt-presets/focus-mode.bttpreset',
})

const unzipUrl = importViaUrl({
  url: 'https://example.com/btt-presets/focus-mode.zip',
  unzip: true,
})

JSON Import

Import triggers directly via a base64-encoded JSON string in the URL.

On-Demand
ts
import { jsonImport } from 'protocol-launcher/bettertouchtool'

const url = jsonImport({
  encodedJson: 'BASE64_ENCODED_TRIGGER_JSON',
})

const uncompressUrl = jsonImport({
  encodedJson: 'BASE64_ENCODED_COMPRESSED_TRIGGER_JSON',
  uncompress: true,
})

Official Documentation