Features Videos Help About Updates
Menu Buy Now

Hooks

First Steps:
Getting Started
Live-Reload Browsers
Browser Sync
Set Language Options
Set Output Paths & Action
Second Steps:
Defaults For New Projects
Build Your Project
Set Target Browsers
Stuff To Know:
CodeKit + Git
Troubleshooting
License Recovery
PostCSS Tools:
Autoprefixer
PurgeCSS
Custom PostCSS Plugins
Other Tools:
npm
Babel — (JS Transpiler)
Terser — (JS Minifier)
Rollup — (JS Bundler)
Cache-Buster
HTML-Minifier
LightningCSS
Bless
Languages:
Sass
Less
Stylus
JavaScript
CoffeeScript
TypeScript
Pug
Haml
Slim
Kit
Markdown
JSON
Image Optimizers:
WebP
PNG
JPEG
SVG
GIF
Frameworks:
CodeKit Frameworks
Tailwind
Bootstrap
Bourbon
Bitters
Zurb Foundation
Susy
Nib
Jeet
Syntax Checkers:
ESLint
Advanced:
Hooks
Environment Variables
Adding Custom Languages
Team Workflows
Scripting CodeKit
Editor Plugins:
Nova
Atom
Sublime Text
Coda 2
More
Read-Only Mode
Upgrading From 2.0
FAQ

What's a Hook?

Hooks let you extend CodeKit to handle any kind of file. You provide a custom command in either Bash or AppleScript, then tell CodeKit which files should trigger that command. Your command becomes another processing step for files of that type.

Adding a Hook

Open the Project Settings area, then choose the Hooks category:

The Hooks category of Project Settings in the CodeKit window

Click the button to add a Hook. Customize the name, choose the type of script your Hook will run (AppleScript or Bash), then define the rules for file-matching.

Rules

Use the Rule Editor to tell CodeKit which files should trigger this Hook. The "Path From Disk Root" option refers to a file's full input path, starting at the root of your drive:

/Macintosh HD/Users/john/documents/project/scripts/file.js 

Assuming "project" is the folder you've added to CodeKit, then the "Path From Project Root" would be:

/scripts/file.js 
Matching Operators
A screenshot of the Hook rule editor options in CodeKit

All matching operators are case-insensitive and ignore diacritic marks (é and e are the same.)

Wildcards are not supported in any operator other than Matches RegEx. Invalid RegEx will cause your Hook to fail. CodeKit uses ICU V3 RegEx Syntax. RegEx is slower than other matching operators and should be used only as a last resort.

If you use Begins With, keep in mind that input and output paths start with a leading slash. Likewise, if you use the Is operator, you must provide a full, matching string.

Hook Order

If a file triggers more than one Hook, the Hooks are run in top-down order. Drag Hooks up or down in Project Settings to change that order.

If your Hook targets filetypes for which CodeKit has built-in processing, your Hook always runs after CodeKit's built-in steps complete.

Hooks Do Not Run On Copy

Your Hook will run only on files that have their Output Action set to Process/Compile. If the Output Action is set to Copy or Ignore, Hooks do not run. For details, see Setting Output Paths & Actions.

Custom Languages

If your Hook targets a type of file that is not one of CodeKit's built-in languages, you should read Adding Custom Languages To CodeKit.


Determining Changed Files

If your Hook is a Bash script, you can use two special environment variables to determine which file triggered the Hook:

  • $CK_INPUT_PATH will be the input path of the changed file.
  • $CK_OUTPUT_PATH will be the full output path, as specified in CodeKit.

The screenshot above shows these variables in action. In this Hook, handlebars is called to compile the changed file at $CK_INPUT_PATH and it's told to write the output to $CK_OUTPUT_PATH.

NOTE: Trigger Files

The paths in these variables may not be those of the file that was actually saved. For example, if parent.scss imports child.scss and you save child.scss in your editor, CodeKit will compile parent.scss and that's the path you'll find in the environment variables. (Unless you have enabled an output file for child.scss, in which case CodeKit would compile both files and run any matching Hook twice.)


Getting The Project's Root Folder

You can use the environment variable $CK_PROJECT_ROOT to get the project's root folder. (In CodeKit 3.0.5 and above.)

For example, if you've installed custom NPM packages in your project and want to call one of them in a Hook, you might write:

$CK_PROJECT_ROOT/node_modules/myModule doStuff --optionA

Logging Output

A screenshot of a Hook log entry in the CodeKit window

Hook output appears in CodeKit's log entry for the affected file, just like output from CodeKit's built-in processing steps.

If your Hook exits with a non-zero code, the entry will be marked as an error and CodeKit will log whatever your Hook writes to StdErr. If your Hook exits with code 0, CodeKit will log whatever it writes to StdOut.

Note: You can also use CodeKit's Scripting API to log something at any time.


Limitations

Hooks cannot be interactive. That is, your script cannot have prompts that require human input. Additionally, your script must be able to run under the privileges of the current user—sudo is prohibited.


Security

Imagine that you have a shared CodeKit project and an evil co-worker adds this Hook: rm -rf ~/Documents. Your co-worker commits his changes, you pull, and CodeKit syncs the project. Are you about to delete your Documents folder next time you save?

A screenshot of the checkbox to disable a Hook in the CodeKit window

No. CodeKit automatically detects when a Hook's source code has changed since you last saw it. When this happens, you'll see an alert and the app will automatically disable the new/changed Hooks. Once you verify that the source code for each Hook is safe, you can manually re-enable them by checking the box pictured.

That said, there is no safety net to protect you from yourself. CodeKit will run exactly what you tell it to run, every time the criteria you specify are met. So if YOU add the Hook that deletes your Documents folder...I hope you have a backup.


Performance & Stability

Keep Hooks short and simple. Remember that each Hook will be run once for every matching file. Malformed Hooks can crash CodeKit, so be sure to double-check your code.

Threading

If your Hook is a Bash script, CodeKit runs it on a background thread. AppleScript Hooks must run on the main thread because AppleScript is not thread-safe. CodeKit's UI may become unresponsive while your Hook completes. CodeKit caches the compiled version of each AppleScript Hook after it runs the first time. Subsequent runs should be significantly faster than the initial one.

WARNING: Hooks Run In Parallel

CodeKit compiles many files at once during builds. This means it's likely that your Hook will run simultaneously on different threads for different files. Write your Hooks with this in mind.

For example, if you create a Hook that always writes to a single file, like ~/Documents/log.txt, that will likely cause problems because five instances of your Hook will be competing for access to that file from five different threads. This may slow down compiling or it may, in the worst case, corrupt data or cause a crash.

Parallel programming is hard. Welcome to my world.

Made in San Diego, CA

Follow the Developer on Twitter

Email Support

Report a Bug

Privacy Policy