# observing/pre-commit: npm Script Hooks for Git Repositories

> observing/pre-commit is a JavaScript package that installs a Git pre-commit hook and runs selected npm scripts before a commit. It fits Node.js repositories that want local test enforcement, but its hook replacement behavior and release history require attention.

**observing/pre-commit** — Automatically installs a git pre-commit script in your git repository which runs your `npm test` on pre-commit

- Repository: https://github.com/observing/pre-commit
- Stars: 1,881 · Forks: 148
- Language: JavaScript
- License: MIT
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/observing-pre-commit

## What observing/pre-commit Changes in a Node.js Repository

observing/pre-commit solves a narrow Git workflow problem: making npm-based checks run at the point where a developer creates a commit. The README describes it as a pre-commit hook installer for Git, with npm test as the default command and other package.json scripts available as explicit checks. This is intended for Node.js projects that already define commands such as tests, linting, coverage, or custom validation in package.json. It does not replace CI, validate a hosted deployment, or provide a general task runner. Its scope is local commit-time enforcement.

The default behavior is simple. According to the README, the hook tries to run npm test in the root of the Git repository unless npm init has set another default. A project can instead list the checks it wants and their order. The package therefore acts as a bridge between npm scripts and Git's hook lifecycle. The repository file list also includes index.js, install.js, uninstall.js, and hook, which matches the documented installation mechanism.

## How the Generated Git Hook Selects npm Scripts

Configuration lives in package.json. The documented key can be pre-commit or precommit, and its value can be an array, a comma-separated string, or an object with a run property. A canonical configuration is an array containing script names in execution order. The README's example runs npm run foo, then npm run bar, then npm run test. The final command returns an error code, so the commit fails.

The package accepts equivalent spellings, including a string under precommit, a string under pre-commit, or an object such as {"run": ["foo", "bar", "test"]}. This flexibility reduces sensitivity to formatting, but it can make configuration less obvious when several styles appear in one package.json. The README also documents silent, colors, and template options. These can be nested under pre-commit or precommit, or written as keys such as pre-commit.silent and pre-commit.colors. The documented purpose of template is to use a file's content as the Git commit body template.

The repository layout indicates that install.js runs through the package install script and that hook contains hook-related implementation. The exact source code for process behavior is not shown here, so the documented data flow is that package.json contains script names, the installed hook invokes them, and a non-zero command prevents the commit.

## Installation and a First Real Configuration

The README recommends installing the module as a devDependency because it is needed during development rather than by the package at runtime. Install it from the project root with the documented command:

```bash
npm install --save-dev pre-commit
```

The package declares an install script, so npm installation is also where the package arranges its Git hook. The README warns that installation overrides an existing .git/hooks/pre-commit file. Any existing hook is backed up as pre-commit.old in the same repository. A first configuration can then be added to package.json. The following is the README's basic array style:

```json
{
  "pre-commit": [
    "foo",
    "bar",
    "test"
  ]
}
```

The scripts named in that array must exist in the package's scripts field. The README illustrates them as npm run foo, npm run bar, and npm run test, in that order. Its test script deliberately returns error code 1, so a commit should be rejected after the first two commands pass. The repository also exposes example-pass and example-fail scripts, which provide check names used by the project's own test setup.

## Failure Behavior and the Existing-Hook Trade-off

The central limitation is explicit: installing observing/pre-commit replaces an existing pre-commit hook rather than composing with it. The original file is preserved as pre-commit.old, but the README does not document a command that restores it. A repository that already depends on formatting, secret checks, generated-file checks, or signing in that hook must account for the replacement before installation. The package is therefore a poor fit when multiple hook tools must share one file without a documented integration path.

The failure model is based on command status. A configured npm script that exits with a non-zero status causes the hook to fail and the commit to stop. This is useful for deterministic local checks, but it does not mean every check is trustworthy. npm test may depend on the environment, installed dependencies, generated files, or network access, none of which is specified as managed by this package. The README also documents an escape hatch: committing with Git's --no-verify option skips pre-commit hooks. That makes the hook advisory at the local command line level, even though it is useful as an intentional bypass for an exceptional situation.

The package does not document parallel execution, per-hook timeouts, recovery after a failed command, or a policy for hook removal. Those omissions matter for teams that need a controlled CI gate rather than a convenience hook.

## Configuration Choices That Affect Repository Workflow

The available options can change day-to-day output. Setting silent suppresses the prefixed pre-commit: messages when checks fail or when there is nothing to run. Setting colors controls whether the package writes color output. The README does not specify automatic terminal detection, so teams should not infer behavior beyond the documented boolean setting.

The template option is different from output control. It points to a file whose content should be used as the template for the Git commit body. That means the package can participate in commit-message preparation, not just command execution. The README does not document the file format, placeholder syntax, or whether an invalid template is rejected, so this option should be verified before relying on it for organization-wide message rules.

The comma-separated form is convenient for small configurations, while arrays make ordering explicit. The object form with run can be mixed with options such as silent and colors. A project should use one style consistently. Script names should point to stable package.json commands rather than ad hoc shell strings. The documented mechanism is npm script invocation, so the maintenance burden remains in the scripts themselves. Updating a test command in package.json changes what the hook runs without requiring a separate hook-specific script.

## observing/pre-commit Compared with npm Scripts and CI Checks

The closest alternative is to run npm scripts manually and rely on continuous integration for repository checks. Manual commands are explicit and do not replace a Git hook, while CI can run in a controlled environment after code is pushed. observing/pre-commit is more immediate because it places checks before commit creation, but it cannot guarantee that a developer did not use --no-verify or that a change was pushed through another path.

Another alternative is maintaining a custom Git hook directly. A hand-written hook gives the repository full control over commands, messages, and coexistence with other checks. observing/pre-commit reduces that custom code by reading configuration from package.json and invoking named npm scripts. The trade-off is narrower flexibility and the documented replacement of .git/hooks/pre-commit. The package is more useful for repositories that want a standard npm-script convention and less useful for repositories needing a customized hook chain.

The repository's package.json declares Node >=16.13.0 and dependencies on cross-spawn and which. This gives the package a defined runtime floor in its package metadata, but the README does not document behavior on particular operating systems or compatibility with specific Git versions. CI remains a separate mechanism rather than a feature described by this package.

## Maintenance, Licensing, and Upgrade Boundaries

The repository is not archived, and its last push was on 2026-04-28. That is the available maintenance fact. The README's release history lists versions 1.1.0 and 1.1.1 from 2015-07-31, while repository package.json reports version 2.0.0 and requires Node >=16.13.0. These facts indicate that installation and maintenance claims should be checked against the current package contents rather than inferred from the README's historical examples.

The project is licensed under MIT. The repository contains a LICENSE file and package.json names the MIT license. The README does not provide legal interpretation, warranty terms, or guidance about organization-specific policies, so the license should be reviewed under the project's actual terms before redistribution.

Upgrades may affect the installed hook, supported Node.js versions, configuration parsing, and script execution behavior. The README does not document an upgrade command, a user-facing changelog procedure, or a migration guide beyond the available repository entries. Because installation modifies a file inside .git/hooks, an upgrade should be reviewed as a repository-local change, not merely as a normal JavaScript dependency update.

## Conclusion

Adopt observing/pre-commit when the repository already uses npm scripts and the team accepts a generated Git hook as a development dependency. Do not adopt it when existing hooks must remain untouched or when local enforcement is insufficient for policy requirements. Check the configured script order, the replacement of .git/hooks/pre-commit, and the package version before adding it to a maintained project.

## FAQ

### How do I install observing/pre-commit in a Node.js project?

The README recommends installing it as a development dependency with `npm install --save-dev pre-commit`. The package then runs its install logic through the package installation process.

### How does observing/pre-commit decide which npm scripts to run?

The package reads a `pre-commit` or `precommit` configuration in package.json. It can contain script names as an array, comma-separated string, or a `run` value, and the configured scripts run in the listed order.

### What happens if observing/pre-commit is installed over an existing Git hook?

The README states that installation overrides an existing `.git/hooks/pre-commit` file and backs it up as `pre-commit.old`. The README does not document a restore command.

## Sources

- [Issues](https://github.com/observing/pre-commit/issues)
- [License: MIT](https://github.com/observing/pre-commit/blob/master/LICENSE)
- [observing/pre-commit on GitHub](https://github.com/observing/pre-commit)
- [README](https://github.com/observing/pre-commit/blob/master/README.md)
- [Releases](https://github.com/observing/pre-commit/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/observing-pre-commit
