Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Captainhook Laravel Package

mpociot/captainhook

CaptainHook makes it easy to add webhooks to your Laravel application: map Eloquent model events such as created, updated, and deleted to outgoing HTTP requests, so external services are notified automatically whenever your data changes.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

First, resolve what we are actually evaluating. The supplied material is internally contradictory. The repository (mpociot/captainhook, 2016, 334 stars) and the prior assessment describe a Git hook manager — versioned PHP config mapping pre-commit/commit-msg/pre-push to shell commands, installed into .git/hooks. The description.md describes an entirely different product: outbound webhook delivery (Eloquent subscriptions, queued JSON POSTs, delivery logs). These have different owners, different risk profiles, and different value. One hour reading composer.json, src/, and the README in the actual repo settles it. Do not scope, estimate, or socialize this package until that is done.

Architecture fit

  • Git-hooks variant: sits in the developer-tooling layer, not the runtime. Zero production footprint, no data model, no network surface. Its only architectural claim is moving hook definitions out of unversioned .git/hooks and into versioned config — consistency, not capability.
  • Outbound-webhook variant: sits on Laravel's event dispatcher + queue + Eloquent. It is a thin reference implementation of the "model event → queued job → HTTP POST" pattern, not a webhook platform. Everything a platform needs (signing, retries, dead-lettering, filtering, self-service endpoints) is out of scope.
  • In both readings, this is a pattern and a prototype, not an architectural commitment.

Integration feasibility

  • Git-hooks: low. composer require, publish config, install the generated scripts, verify by cat .git/hooks/pre-commit. Half a day to first working guardrail. Verify the actual Artisan verb in source — documentation is from 2016 and inconsistent.
  • Outbound-webhooks: publish config and migrations, attach the trait to a model, register a URL, deliver through a real queue driver (database/redis, never sync), and observe against a request bin. Days for a working pilot — if Composer resolves.

Technical risk

  • Abandonment is the headline risk. Last release December 2016, zero Packagist dependents, no upstream triage, no security patching. Treat it as ~200 lines of inherited code, not a dependency.
  • Version drift is a probable blocker. Expect illuminate/* constraints, Guzzle/HTTP client drift, and event-dispatcher/container incompatibilities on Laravel 8+/PHP 8. Budget a rewrite, not an upgrade — and do not burn a day on --ignore-platform-reqs to avoid that conclusion.
  • Delivery guarantees are absent in the webhook reading. No retries with backoff, no dead-lettering, no auto-disable on repeated failure, no idempotency key, no rate limiting, no payload signing. That is beta-grade, not SLA-grade.
  • Security surface differs by reading. Git hooks: audit how command strings are constructed before anything user-influenced can reach the config. Webhooks: unsigned payloads mean spoofing; customer-supplied URLs mean SSRF (block link-local/private ranges); secrets live in committed config unless pulled from env.
  • Direction check: the webhook reading is outbound-only. If the requirement is receiving third-party webhooks, this package is irrelevant to the problem.

Key questions to answer before committing

  1. Which package is it — Git hooks or outbound webhooks? (Blocks everything else.)
  2. What Laravel/PHP version is the target? Does Composer actually resolve, or are we forking on day one?
  3. Is delivery contractual (SLA, audit, replay) or best-effort/beta?
  4. Who supplies subscriber URLs — trusted first-party/design partners, or customers?
  5. Outbound, inbound, or both?
  6. Is the customer-facing event taxonomy (created only, vs. updated/deleted/domain events) already decided? This is permanent API surface and the expensive thing to get wrong.
  7. Do we need a self-service endpoint UI? It is usually the bulk of the engineering, not the delivery code.

Integration Approach

Stack fit

  • Git-hooks: orthogonal to the application — no production coupling, no deploy implications, safe to trial on one team. It fits any PHP repo in practice, even though the package is Laravel-wired.
  • Outbound-webhooks: a natural fit for a Laravel shop already using events and queues. Keep it behind a feature flag and an internal adapter interface so the delivery mechanism is swappable when reliability requirements arrive.

Migration path — vendor it, do not depend on it Given the December 2016 release and zero dependents, the correct integration is copy, not require. Move the code into app/ or a private package you control, pin it, and accept you will patch it. An abandoned transitive dependency in composer.json becomes a tax on every future framework upgrade, and that negotiation is where it will eventually be ripped out under duress. If it must stay a Composer dependency for the spike, isolate it to a throwaway branch.

Compatibility

  • Assume the package targets the Laravel 5.x / PHP 5.6–7.x era. Validate the constraint set in composer.json before writing a ticket.
  • For the webhook reading, explicitly test the HTTP client and queue payload serialization — both are the usual drift points across major Laravel versions.
  • Windows teams: shell hooks with CRLF endings fail with bad interpreter. Resolve before rollout; it is the most common "the hook doesn't work" report.

Sequencing

  1. Resolve identity (1 hour, blocking). Read source, not docs.
  2. Time-boxed spike — one engineer-week, hard stop, behind a flag. Success criteria written down before it starts.
  3. If Git-hooks: pre-commit runs fast lint/style on staged files only (sub-5s) → validate the failure path actually blocks a commit → add commit-msg regex validation → add pre-push full suite → mirror all of it in CI → automate install in composer.json post-install and add to the onboarding checklist.
  4. If outbound-webhooks: delivery log first (without it you cannot debug a customer ticket) → event taxonomy decision → signature + retries with backoff + dead-lettering → per-endpoint filtering and rate limits → self-service endpoint UI last, because it is the largest chunk and only justified by adoption data.
  5. Rewrite decision gate: if the spike shows Composer conflicts or missing guarantees the business needs, stop and build in-house using the source as an architecture reference — it is a readable template and a legitimate input to an internal estimate.

Decision framing for stakeholders: ship the thin version to design partners, instrument registration rate / event-type mix / delivery success rate, and let that data order the roadmap: prove demand → invest in delivery guarantees → invest in developer self-service.

Operational Impact

Maintenance

  • Ownership transfers to us on day one. No upstream fixes, no security patches, no issue triage. Budget ongoing small-but-real maintenance rather than zero.
  • The Git-hooks reading is genuinely low-maintenance: config file, occasional path fixes, reinstall on new clones.
  • The webhook reading carries a standing obligation — every Laravel upgrade is a compatibility event we own.

Support

  • Git-hooks: support load is onboarding, not production. The recurring tickets are "my hook doesn't fire" (cwd, line endings, install not run) and "the hook was bypassed." A sanctioned, documented skip path (--no-verify, or an env var the config reads) is better than developers disabling hooks permanently and silently.
  • Outbound-webhooks: support load is customer-facing and will exist whether or not the tooling does. "We didn't receive the event" is unanswerable without a per-delivery log with request, response, status, and timestamp. Build the log before promising anything externally, and plan for manual replay as a support workflow — not a feature, a necessity.

Scaling

  • Git-hooks: scales with repo size and test-suite duration. A 30-second pre-commit guarantees --no-verify within a week, and a disabled hook is worse than no hook because the team believes it is running. Scope tools to staged files; push the expensive gate to pre-push.
  • Outbound-webhooks: scales with subscriber count × event volume × retry attempts. Slow endpoints hold queue workers — enforce timeouts. Fan-out multiplies on retries and can produce thundering-herd behavior with no jitter or backoff. Per-subscriber rate limits are eventually required, and this package has none.

Failure modes to design against

  • Silent success. A command that prints errors but exits 0 never blocks the commit; a delivery with no log looks identical to one that never happened. Both failures are invisible by default. Test the failure path explicitly in both readings.
  • Bypass. Hooks are skippable by --no-verify, IDE integrations, and rebase merges. CI must be authoritative; hooks are fast feedback only. Keep the commands identical in both places so a CI failure reproduces locally.
  • Path and working-directory assumptions. Relative paths like vendor/bin/pint fail silently if the cwd is .git/hooks rather than the repo root. Use git rev-parse --show-toplevel or verify $PWD.
  • Queue backlog / event loss. No dead-lettering means permanent, unrecorded loss under load or endpoint outages.
  • Security debt. SSRF via customer URLs, spoofable unsigned payloads, secrets committed in config. Confirm each control exists before any external commitment; assume it does not.
  • Upgrade cliff. The package resolving today does not mean it resolves on the next major Laravel. Vendoring converts this from a surprise into a scheduled task.

Ramp-up

  • An engineer fluent in Laravel events and queues needs an hour with the source and roughly a day to a working prototype. The source is short enough to read end to end — do that rather than trusting the 2016 README.
  • Team-wide ramp-up is process, not training: an onboarding checklist item that verifies hooks after a fresh clone (clone into a temp directory and commit without manual setup), and a CI job that produces the same result.
  • Set expectations explicitly: this buys speed to a validated decision, not durability. Anything customer-facing with an SLA attached is a follow-on build, and the pilot's job is to tell us how big that build needs to be.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource