Skip to content
Back to skills

Lefthook

ASecurity

Fast Git hooks manager written in Go. Use when a user asks to set up Git hooks without Node.js dependency, run parallel pre-commit checks, or find a faster alternative to Husky.

  • 142 stars
  • 0 votes
  • 0 copies
  • 4 views
  • Added May 29, 2026
developmentpythongorubybashnodegitapi

Works with

  • terminal
  • api

Security analysis

A92/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 2 files and shows the line behind each finding

Scanned October 4, 2026

npx -y skills add TerminalSkills/skills --skill lefthook --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Lefthook?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Lefthook
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/terminalskills-lefthook/badge)](https://www.skillsdirectory.com/skills/terminalskills-lefthook)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: lefthook
description: >-
  Fast Git hooks manager written in Go. Use when a user asks to set up Git hooks without Node.js dependency, run parallel pre-commit checks, or find a faster alternative to Husky.
license: Apache-2.0
compatibility: 'Any Git repository, any language; installs via npm, Homebrew, Go, gem or pipx'
metadata:
  author: terminal-skills
  version: 1.1.0
  category: development
  repository: https://github.com/evilmartians/lefthook
  tags:
    - lefthook
    - git-hooks
    - pre-commit
    - lint
    - go
---

# Lefthook

## Overview
Lefthook is a fast, polyglot Git hooks manager distributed as a single Go binary (current major version: 2.x). It does not need Node.js — you can install it with npm, Homebrew, Go, RubyGems or pipx — and it runs hook tasks in parallel, filters files by glob, and reads its settings from a YAML file in the repository root.

## Instructions

### Step 1: Install
```bash
# Node projects: dev dependency (the package downloads the right binary)
npm install --save-dev lefthook
# pnpm: pnpm add -D lefthook  (then allow its build script, see Guidelines)

# Any project
brew install lefthook
go install github.com/evilmartians/lefthook/v2@latest
gem install lefthook
pipx install lefthook
```

Write the config (Step 2), then install the hooks into `.git/hooks`:
```bash
npx lefthook install      # or: lefthook install
```
If `lefthook.yml` does not exist yet, `lefthook install` creates an empty one.

### Step 2: Configure
Config lives in `lefthook.yml` (also accepted: `.lefthook.yml`, `.config/lefthook.yml`, and `.yaml`, `.toml`, `.json`, `.jsonc` variants — keep only one file per project). The current format is a `jobs` list under each hook; the older `commands` map still works.

```yaml
# lefthook.yml — Git hooks configuration
pre-commit:
  parallel: true
  jobs:
    - name: lint
      glob: "*.{ts,tsx,js,jsx}"
      run: npx eslint --fix {staged_files}
      stage_fixed: true
    - name: format
      glob: "*.{ts,tsx,js,jsx,css,md,json}"
      run: npx prettier --write {staged_files}
      stage_fixed: true
    - name: typecheck
      run: npx tsc --noEmit

pre-push:
  jobs:
    - name: test
      run: npm test

commit-msg:
  jobs:
    - name: commitlint
      run: npx commitlint --edit {1}
```

Parallel jobs that rewrite the same files can race; if lint and format both modify files, drop `parallel: true` and list them in order (see Example 2).

### Step 3: Check and run
```bash
npx lefthook validate           # check the config for errors
npx lefthook run pre-commit     # run a hook by hand, without committing
npx lefthook dump               # print the final merged config
LEFTHOOK=0 git commit -m "wip"  # skip hooks once (LEFTHOOK_VERBOSE=1 for detail)
```

## Examples

### Example 1: Replace Husky in a Node project
**Request:** "Move our repo from Husky + lint-staged to lefthook."

```bash
npm uninstall husky lint-staged
npm install --save-dev lefthook
```
Delete the `.husky/` folder and the `lint-staged` block from `package.json`, add the `lefthook.yml` from Step 2, then run `npx lefthook install`. Check it with `npx lefthook run pre-commit`: it lists each job with its result, and exits non-zero if any job fails.

### Example 2: Python and Go monorepo without Node
**Request:** "Add pre-commit checks for our Python API and Go worker, but only on changed files."

```yaml
# lefthook.yml
pre-commit:
  jobs:
    - name: ruff
      root: "api/"
      glob: "*.py"
      run: ruff check --fix {staged_files}
      stage_fixed: true
    - name: gofmt
      root: "worker/"
      glob: "*.go"
      run: gofmt -l -w {staged_files}
      stage_fixed: true
```
```bash
brew install lefthook && lefthook install
```
Committing a change that touches only `worker/*.go` runs only the `gofmt` job; the `ruff` job is skipped because no file matches its glob.

## Guidelines
- `{staged_files}` expands to the files staged for the commit, `{push_files}` to the files in the push, `{all_files}` to every tracked file, and `{1}` to the hook's first argument (the commit-message file in `commit-msg`). Use `glob` and `root` to narrow them; no lint-staged needed.
- `stage_fixed: true` re-adds files a formatter changed, so fixes land in the same commit.
- Hooks are installed per clone. With the npm package, installing dependencies runs `lefthook install` for you; with pnpm you must allow the build script (add `lefthook` to `onlyBuiltDependencies` in `pnpm-workspace.yaml`), otherwise no hooks are installed. With other install methods, tell contributors to run `lefthook install`.
- Personal overrides go in `lefthook-local.yml` (add it to `.gitignore`); it can also be used without a main config.
- `lefthook run` and `lefthook validate` need a Git repository; outside one they exit with "not a git repository".
- Keep pre-commit fast (lint and format on changed files); put slow test suites on `pre-push` or in CI, because `LEFTHOOK=0` and `git commit --no-verify` can bypass local hooks.

Files in this skill

  • SKILL.md1.5 KB
  • _scores.json1.9 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.