documentation
Git Hooks
Push bundle stats automatically using git hooks, Husky, or Lefthook
Note: Git hooks don't run in most CI environments — CI runners clone repos without executing hooks. For automated tracking on every push, see CI Integration instead. Git hooks are best suited for local workflows or small teams that don't use a CI pipeline.
Approach 1: Post-build npm script
The most reliable approach — run the snapshot upload as part of the build script, not a git hook. This fires on every build regardless of git state, which is usually what you want for CI compatibility too.
Commit the Quick Start push script as scripts/push-bundle.sh, then chain it after the build:
{
"scripts": {
"build": "webpack --json=stats.json && ./scripts/push-bundle.sh"
}
}
No hook configuration needed. Works in CI, local development, and any environment that calls npm run build.
Approach 2: Manual git pre-push hook
Runs before git push. Use this when you want to capture stats only on pushes to a remote, not on every local build.
Create .git/hooks/pre-push and make it executable:
chmod +x .git/hooks/pre-push
.git/hooks/pre-push:
#!/bin/sh
set -e
# Only run on pushes to main/master
BRANCH=$(git rev-parse --abbrev-ref HEAD)
if [ "$BRANCH" != "main" ] && [ "$BRANCH" != "master" ]; then
exit 0
fi
# Build and capture stats
npm run build -- --json=stats.json
# Submit the snapshot to dendrobundle
curl -s -X POST "https://dendrobundle.com/api/push?branch=$BRANCH&commit=$(git rev-parse HEAD)" \
-H "Authorization: Bearer $DENDROBUNDLE_TOKEN" \
-H "Content-Type: application/json" \
--data @stats.json
Limitation: Files inside .git/ are not committed to the repository. Each developer must install the hook manually. Use Husky or Lefthook (below) to share hooks with the team via version control.
Approach 3: Husky
Husky installs git hooks as files in .husky/, which are committed to the repo and automatically installed for anyone who runs npm install.
Install:
npx husky init
.husky/pre-push:
#!/bin/sh
npm run build -- --json=stats.json
curl -s -X POST "https://dendrobundle.com/api/push?branch=$(git branch --show-current)&commit=$(git rev-parse HEAD)" \
-H "Authorization: Bearer $DENDROBUNDLE_TOKEN" \
-H "Content-Type: application/json" \
--data @stats.json
Add the prepare script so Husky installs hooks on npm install:
{
"scripts": {
"prepare": "husky"
}
}
Approach 4: Lefthook
Zero-dependency alternative to Husky. Configuration lives in lefthook.yml at the repo root.
npx lefthook install
lefthook.yml:
pre-push:
commands:
push-bundle:
run: |
npm run build -- --json=stats.json
curl -s -X POST "https://dendrobundle.com/api/push?branch={push_remote_branch}&commit=$(git rev-parse HEAD)" \
-H "Authorization: Bearer $DENDROBUNDLE_TOKEN" \
-H "Content-Type: application/json" \
--data @stats.json
Lefthook uses {push_remote_branch} as a built-in placeholder for the branch being pushed.
Environment variables
All approaches require DENDROBUNDLE_TOKEN to be available in the shell environment when the hook runs.
Locally — add to your shell profile or a .env file (sourced by your shell, not automatically by git hooks):
export DENDROBUNDLE_TOKEN=eyJhbGciOiJIUzI1NiJ9… # the token shown once on creation
If you use a .env file, source it explicitly at the top of the hook script:
#!/bin/sh
set -a
. "$(git rev-parse --show-toplevel)/.env"
set +a
In CI — set DENDROBUNDLE_TOKEN as a CI/CD secret variable. See CI Integration for pipeline-specific instructions.
Never commit the token to the repo. Add .env to .gitignore.