Script applications
Avoid UI scripting when possible
Recognize when Accessibility-driven clicks are brittle and replace them with files, URLs, dictionaries, Shortcuts actions, or APIs.
10 minute lesson
UI scripting searches windows and controls, then simulates user actions. Through System Events, AppleScript can click any button and choose any menu item. That sounds like the universal automation tool, right up until you have to maintain one of these scripts.
Here is what it looks like:
tell application "System Events"
tell process "Notes"
set frontmost to true
click menu item "New Note" of menu "File" of menu bar 1
end tell
end tell
Nothing in that script expresses intent. It encodes where things happen to be: a menu named “File”, an item named “New Note”, a process that must be frontmost when the click lands. Labels, timing, focus, localization, and layout changes can break it. A macOS update that renames a menu item, a slow launch that makes the click arrive early, a French system where the menu is “Fichier” — all fatal, all silent until they strike.
It also demands the broadest permission on the system. System Events needs Accessibility access (System Settings → Privacy & Security → Accessibility), and a tool holding that grant can drive any application, not just the one you meant.
So before enabling Accessibility, check for a Shortcuts action, AppleScript dictionary command, URL scheme, command-line interface, or documented API. These interfaces express intent instead of screen position. Work down the list in order: the app’s dictionary first, then its Shortcuts actions, then its documentation. For Notes, the dictionary command make new note does what the click script above does, in one line that survives redesigns and localization.
If UI scripting is unavoidable, contain it. Narrow permission to one trusted tool, verify the active application before sending events, add timeouts, and stop on an unexpected window. A UI script that keeps clicking after a surprise dialog appears is typing into the wrong app with your permissions.
Treat every UI script as debt with a review date. Note the app version it was built against, and retest it after each update of that app or of macOS.
Lesson completed