Skip to content

Snippets ​

A snippet is the simplest kind of PopClip extension, because it is just plain text. A snippet begins with a #popclip (or # popclip) marker line.

javascript
// #popclip
// name: Title Case
// icon: scale=120 move-x=3 circle filled Tc
const titled = popclip.input.text.replace(
  /\S+/g,
  (word) => word[0].toUpperCase() + word.slice(1).toLowerCase(),
);
popclip.pasteText(titled);

When you select the text of a snippet, PopClip offers an "Install" action, as shown in the introduction. (Try it!)

Size limit, and snippet files

When installed via text selection, snippets can be up to 5,000 characters long. Snippet files, on the other hand, have no maximum length. To install a snippet from a file, save it as a text file with one of these extensions: .ts, .js, .yaml and send it to PopClip using "Open With" in Finder, or drag the file onto PopClip's menu bar icon. A special file extension, .popcliptxt, can also be used: PopClip opens it when you double-click it.

Snippets come in two forms:

  • A code snippet is a script, with the extension's config in a comment header.
  • A config snippet is config alone, in YAML format — most useful for the no-code action types.

Code snippets ​

Here is a complete code snippet:

javascript
// #popclip
// name: Uppercase
// icon: square filled AB
popclip.pasteText(popclip.input.text.toUpperCase());

The config header is a run of comment lines starting at the #popclip marker, containing the extension's config as YAML. Everything after the header is the script itself.

Code snippets (formerly called inverted syntax) are supported for JavaScript, AppleScript and shell script actions. The whole text of the snippet becomes the javaScriptFile, module, appleScriptFile or shellScriptFile for the extension, as follows:

To interpret as...Include these fields...
javaScriptFile or moduleNothing needed: a code body under a // comment header is treated as TypeScript by default. (Specify language: javascript to treat as raw JavaScript instead.) A body that exports is loaded as module (see Module detection), otherwise as javaScriptFile.
appleScriptFileNothing needed: a body under a -- comment header is treated as AppleScript.
shellScriptFileSpecify interpreter, or start the snippet with a #! line.

Inference is new

Language and module inference is new in PopClip 2026.8.1 (6221). If you try to install a code snippet that specifies no language, interpreter or module on an older version of PopClip, it will fail with the error message "Specify language or interpreter".

Non-JavaScript snippets ​

Code snippets are not just for JavaScript — they can also be used with shell scripts and with AppleScript. The config header should be added using the appropriate comment style for the source language, as in the examples below.

Here is a Python example, using # for the comment header:

python
# #popclip
# name: Hello Python
# icon: circle hi
# after: show-result
# interpreter: python3
import os
print('Hello, ' + os.environ['POPCLIP_TEXT'] + '!', end='')

An alternative way to specify a shell script's interpreter is to put a shebang (#!) line at the top of the snippet, before the #popclip marker line. Then the interpreter field is not needed:

python
#!/usr/bin/env python3
# #popclip
# name: Hello Python (shebang)
# icon: circle hi
# after: show-result
import os
print('Hello again, ' + os.environ['POPCLIP_TEXT'] + '!', end='')

Using the -- comment prefix without specifying an interpreter tells PopClip that the body is AppleScript:

applescript
-- #popclip
-- name: LaunchBar
-- icon: LB
tell application "LaunchBar"
  set selection to "{popclip text}"
end tell

Config snippets ​

A config snippet is parsed as YAML 1.2. The body of the snippet defines the extension's config dictionary. For example:

yaml
#popclip
name: Urban Dictionary
icon: UD
url: https://www.urbandictionary.com/define.php?term=***

Comments in snippets

Note that # begins a YAML comment. Thus the entire snippet including the #popclip line parses as valid YAML.

More config snippet examples ​

A Shortcuts example:

yaml
# popclip shortcuts example
name: Run My Shortcut
icon: symbol:moon.stars # Apple SF Symbols
shortcutName: My Shortcut Name

A Service example (this time using flow-style YAML markup, with braces):

yaml
#popclip service example
name: Stickies
serviceName: Make Sticky

A Key Press example:

yaml
#popclip key press example
name: Key Press Example
keyCombo: command option J

A shell script example:

yaml
#popclip shellscript example
name: Say
interpreter: zsh
shellScript: say -v Daniel $POPCLIP_TEXT

A JavaScript example, including multiple actions:

yaml
#popclip js + multi action example
name: Markdown Formatting
requirements: [text, paste]
actions:
  - title: Markdown Bold # note: actions have a `title`, not a `name`
    icon: circle filled B
    javaScript: popclip.pasteText('**' + popclip.input.text + '**')
  - title: Markdown Italic
    icon: circle filled I
    javaScript: popclip.pasteText('*' + popclip.input.text + '*')

#1 rule of YAML: Do not indent with tabs!

When writing snippets in YAML with indented parts, as in the example above, do not use tabs for indenting. YAML does not allow it — use spaces instead.

Developing with snippets ​

PopClip will display any errors it encounters while trying to load the snippet in the PopClip bar itself.

PopClip bar showing error message.

In the absence of an identifier field, the name acts as the identifier for the extension. Installing a snippet with the same name as an existing snippet will replace it.

A snippet can do everything that a package extension can do. The only limitation is that it is completely self-contained: it can't refer to any additional files. If you want to include a custom icon file, additional source files, or resource files, use a package instead.