Skip to content

fix: only run husky in a git checkout so npm consumers don't break#1764

Merged
oliverlaz merged 1 commit into
masterfrom
fix/husky-postinstall-npm-consumers
Jun 5, 2026
Merged

fix: only run husky in a git checkout so npm consumers don't break#1764
oliverlaz merged 1 commit into
masterfrom
fix/husky-postinstall-npm-consumers

Conversation

@oliverlaz
Copy link
Copy Markdown
Member

Problem

postinstall ran husky unconditionally. npm executes a dependency's postinstall for every consumer, but husky is a devDependency and isn't installed in a consumer's tree, so npm install stream-chat failed:

npm error code 127
npm error sh: husky: command not found

Closes #1763.

Why husky has to stay in postinstall

Yarn Berry (this repo's package manager) runs the root workspace's postinstall on yarn install but not its prepare. So moving husky to prepare would silently stop installing contributors' git hooks. husky must stay in postinstall; the fix is to stop running it for consumers.

Fix

  • postinstall now invokes a dev-only scripts/install-husky.mjs only when it is present — and that file is intentionally not added to package.json#files, so consumers never receive it and the guard short-circuits to a no-op.
  • The invocation runs via node (not a shell || true) so it's cross-platform — npm runs consumer postinstalls through cmd.exe on Windows, where ||/true aren't valid.
  • scripts/install-husky.mjs runs husky only inside a git checkout, and lets genuine husky setup errors surface (not swallowed) so contributors learn if hook installation actually fails.
  • prepare: yarn run build is unchanged (npm git-ref installs still build a package).

Testing

Verified end-to-end with a packed tarball (yarn pack) installed into a throwaway consumer, and a fresh git clone + yarn install:

Scenario Result
npm install <tarball> (consumer) exit 0 · husky never executed · package imports
fresh git clone + yarn install (contributor) core.hooksPath=.husky/_ · hooks installed
control: old postinstall: husky reproduces code 127 / husky: command not found
simulated husky setup error surfaces (exit 1) instead of being swallowed

yarn lint clean.

`postinstall` ran `husky` unconditionally. npm executes a dependency's
`postinstall` for every consumer, but `husky` is a devDependency and isn't
installed in a consumer's tree, so `npm install stream-chat` failed with
`code 127 / husky: command not found`.

Yarn Berry runs the root workspace's `postinstall` (not `prepare`) on
`yarn install`, so husky setup must stay in `postinstall` for contributors.
Instead of executing husky unconditionally, postinstall now invokes a dev-only
`scripts/install-husky.mjs` only when it is present — and that file is
intentionally not in `package.json#files`, so consumers never receive it and the
guard short-circuits to a no-op. The invocation uses `node` rather than a shell
guard so it is cross-platform (npm runs consumer postinstall via cmd.exe on
Windows, where `||`/`true` are invalid). The script runs husky only inside a git
checkout and lets genuine setup errors surface rather than swallowing them.

`prepare: yarn run build` is unchanged (npm git-ref installs still build).

Closes #1763
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 5, 2026

Size Change: 0 B

Total Size: 407 kB

ℹ️ View Unchanged
Filename Size
dist/cjs/index.browser.js 135 kB
dist/cjs/index.node.js 137 kB
dist/esm/index.mjs 135 kB

compressed-size-action

@oliverlaz oliverlaz merged commit 88dbdb6 into master Jun 5, 2026
7 checks passed
@oliverlaz oliverlaz deleted the fix/husky-postinstall-npm-consumers branch June 5, 2026 09:53
github-actions Bot pushed a commit that referenced this pull request Jun 5, 2026
## [9.45.1](v9.45.0...v9.45.1) (2026-06-05)

### Bug Fixes

* only run husky in a git checkout so npm consumers don't break ([#1764](#1764)) ([88dbdb6](88dbdb6))
@stream-ci-bot
Copy link
Copy Markdown

🎉 This PR is included in version 9.45.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

oliverlaz added a commit to GetStream/stream-chat-react that referenced this pull request Jun 5, 2026
…3211)

### 🎯 Goal

`postinstall` ran `husky` unconditionally. npm executes a dependency's
`postinstall` for every consumer, but `husky` is a `devDependency` and
isn't installed in a consumer's tree, so `npm install stream-chat-react`
failed:

```
npm error code 127
npm error sh: husky: command not found
```

This ports the same fix already merged for the JS SDK in
[GetStream/stream-chat-js#1764](GetStream/stream-chat-js#1764)
— `stream-chat-react` had the identical `"postinstall": "husky"`.

### 🛠 Implementation details

**Why husky has to stay in `postinstall`:** Yarn Berry (this repo's
package manager) runs the **root workspace's `postinstall`** on `yarn
install` but **not** its `prepare`. Moving husky to `prepare` would
silently stop installing contributors' git hooks. husky must stay in
`postinstall`; the fix is to stop *running* it for consumers.

- `postinstall` now invokes a dev-only `scripts/install-husky.mjs`
**only when it is present** — and that file is intentionally **not** in
`package.json#files` (which publishes only `dist`, `package.json`,
`README.md`, `AI.md`), so consumers never receive it and the guard
short-circuits to a no-op.
- The invocation runs via `node` (not a shell `|| true`) so it's
cross-platform — npm runs consumer postinstalls through `cmd.exe` on
Windows, where `||`/`true` aren't valid.
- `scripts/install-husky.mjs` runs husky only inside a git checkout, and
lets genuine husky setup errors **surface** (not swallowed) so
contributors learn if hook installation actually fails.

> Note: unlike the JS SDK PR (which left `prepare: yarn run build`
untouched), this repo uses `prepack: yarn build` and has no `prepare`
script, so nothing there needed changing — the husky fix is independent
of it.

**Verified locally:**

| Scenario | Result |
| --- | --- |
| Consumer (no `scripts/install-husky.mjs`) | exit 0 · husky never
executed |
| Contributor (`.git` + script present) | `core.hooksPath=.husky/_` ·
hooks installed · exit 0 |

`yarn prettier` and `yarn eslint` clean on both changed files.

### 🎨 UI Changes

None — build/install tooling only.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Improved post-install script configuration to make Git hook
initialization more reliable and conditional based on repository
presence.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

postinstall: "husky" in v9.45.0 breaks npm install for consumers

3 participants