Skip to content
GitHub

Hooks

Hooks let you run shell commands at specific points in the bino pipeline. Define them in bino.toml and they execute automatically during build, preview, or serve.

Hooks are defined in bino.toml as arrays of shell commands mapped to checkpoint names.

Shared hooks apply to all commands unless overridden per-command:

[hooks]
pre-datasource = ["python scripts/fetch_data.py"]

Per-command hooks override shared hooks for the same checkpoint name (they are not merged):

[build.hooks]
pre-build = ["./scripts/validate_env.sh"]
post-build = ["./scripts/upload.sh"]

[preview.hooks]
pre-preview = ["python scripts/generate_fixtures.py"]

[serve.hooks]
pre-serve = ["./scripts/warmup.sh"]

If both [hooks] and [build.hooks] define pre-datasource, only the [build.hooks] version runs during bino build.

CheckpointFires whenAvailable in
pre-buildAfter manifest loading, before buildingbuild
pre-datasourceBefore rendering HTML per artefactbuild, preview, serve
pre-renderAfter HTML rendered, before PDF generationbuild
post-renderAfter PDF generated and signed per artefactbuild
post-buildAfter all artefacts builtbuild
pre-previewOnce, after server created, before first loadpreview
pre-refreshBefore each hot-reload refresh cyclepreview
pre-serveOnce, after server created, before requestsserve
pre-requestBefore each on-demand render requestserve
  • Commands in a checkpoint array run sequentially in order.
  • Each command runs through the platform shell: sh -c on Unix, cmd /C on Windows.
  • The working directory is set to the project root (the directory containing bino.toml).
  • Stdout is logged at info level; stderr at warn level.
  • Commands inherit the parent context and are cancelled if the CLI is interrupted.

Every hook receives these environment variables:

VariableDescriptionExample
BINO_MODECurrent commandbuild, preview, serve
BINO_WORKDIRAbsolute path to project root/home/user/reports
BINO_REPORT_IDReport ID from bino.toml550e8400-...
BINO_HOOKCheckpoint namepre-build
BINO_VERBOSEWhether verbose mode is active0 or 1

pre-datasource, pre-render, and post-render also receive:

VariableDescription
BINO_ARTEFACT_NAMEName of the current artefact
BINO_ARTEFACT_KINDKind of artefact (report, screenshot, document)
VariableDescription
BINO_OUTPUT_DIRAbsolute path to the output directory
BINO_INCLUDEComma-separated --artefact values
BINO_EXCLUDEComma-separated --exclude-artefact values
VariableDescription
BINO_PDF_PATHAbsolute path to the generated PDF
VariableDescription
BINO_LISTEN_ADDRServer listen address
BINO_REFRESH_REASONWhat triggered the refresh (pre-refresh only)
VariableDescription
BINO_LISTEN_ADDRServer listen address
BINO_LIVE_ARTEFACTName of the LiveReportArtefact
CodeMeaningBehaviour
0SuccessContinue normally
78SkipLogged at info level, treated as success
OtherFailurePropagated as an error (see error handling below)

Exit code 78 is useful for scripts that conditionally opt out:

#!/bin/bash
# Skip if data is fresh (less than 1 hour old)
if [ -f data.csv ] && [ $(($(date +%s) - $(stat -f %m data.csv))) -lt 3600 ]; then
  exit 78
fi
curl -o data.csv https://api.example.com/data

How hook failures affect each command:

CommandOne-time hooks (pre-build, pre-preview, pre-serve)Per-cycle hooks (pre-refresh, pre-request, etc.)
buildBuild failsBuild fails
previewPreview fails to startRefresh skipped, error logged, CLI continues
serveServer fails to startRequest returns error, server continues

Hooks run through the platform shell automatically:

  • macOS / Linux: sh -c "<command>"
  • Windows: cmd /C "<command>"

No additional configuration is needed. Write scripts that work on your target platform.