Drop it in. Try it without sending. Back out cleanly if it isn't for you.
CommitCourier is designed to be added to an existing application in a small way, to let you confirm its behavior before any real delivery starts, and to be removed — without dragging your business schema with it — if it turns out not to fit. You don't have to trust it up front; you have to be able to evaluate it safely.
Add it to the Node.js / TypeScript app and PostgreSQL you already run — as a small, contained change.
Observe mode confirms production-equivalent behavior without making any outbound HTTP call.
The dedicated tables, dispatcher and enqueue calls are easy to remove to return to your original setup.
Webhooks are an important path between your core systems and outside services. Being cautious about dropping an unproven library straight into that path is the right instinct. CommitCourier's goal isn't to win your full trust on day one — it's to keep the adoption decision small, safe, and reversible.
Adopting the library shouldn't be a one-way migration you can't undo. Each step is small and the previous one is still recoverable.
Add it in a small, contained change
↓
Observe — confirm behavior without sending
↓
Enable active delivery once you're convinced
↓
If it isn't a fit, remove just the dedicated partsYou don't build a new delivery platform from scratch; you add CommitCourier to the application and PostgreSQL you already run. It works alongside the code that emits webhooks rather than replacing your whole event architecture.
Observe mode runs the same code path as real processing but makes no outbound HTTP call — events are recorded with the observed status instead of being sent. It's a staged-rollout step for verifying a production-equivalent path safely, not a toy dry-run.
Production-equivalent business logic ↓ enqueue in the same transaction ↓ Event recorded as "observed" ↓ No outbound HTTP is sent
// Evaluate safely: run the real code path, record what WOULD be sent — send nothing.
const relay = await createRelay({
store,
mode: "observe", // enqueue still rides your transaction; rows land as "observed"
});
// No outbound HTTP. Switch to the default (active) mode once you're convinced.Reversibility is a first-class scenario, not an afterthought. The change you make at adoption is also the change you undo — so it's clear where to back out.
Stop the dispatcher ↓ Remove the enqueue calls ↓ Drop CommitCourier's tables ↓ Remove the config and package
Rather than claiming it's "secure," CommitCourier makes the safe setting the default and requires an explicit decision to loosen it. These are the representative measures — not a promise of perfect security.
HMAC-SHA256 over id.timestamp.body, with the timestamp signed. Verification accepts multiple secrets so a receiver works across a key rotation.
Private, loopback, link-local and cloud-metadata targets are blocked — validated against the DNS-resolved IP, which is pinned at connect time (DNS-rebinding aware).
A built-in AES-256-GCM cipher, or your own adapter for KMS / Vault. Without a cipher, startup prints an explicit plaintext warning.
HTTP timeout, payload-size limit, retry / backoff caps and a replay safety cap — all set to safe defaults.
Signing secrets are not written into the delivery ledger, and stored response bodies are length-limited.
Unsafe-but-valid settings require an explicit acknowledgement — they are never applied silently.
Reliability isn't the number of features that work on the happy path — it's what happens when something fails. Failures are treated as a normal operational flow: recorded, retried, recoverable.
It rides your business transaction. If the outbox row can't be written, your transaction fails too — you never emit a webhook for a change that didn't commit.
An async delivery failure never flows back into your business path. It is recorded, not thrown at your request.
Retryable failures back off and retry; a final failure lands in the dead-letter queue rather than vanishing.
in-flight rows are reclaimed via a visibility timeout, so a worker crash mid-delivery doesn't strand events.
Inspect the full delivery ledger, replay the DLQ, or cancel a pending row.
Delivery is at-least-once — not exactly-once. Every event carries an idempotency-key so the receiver can dedup.
Opt-in: after a threshold of consecutive failures a registered endpoint auto-disables so a dead receiver stops draining retries; re-enabling it resets the budget.
Rather than asserting "it's well tested," the project publishes what it checks. These run continuously in public CI — beyond a coverage number, they exercise failures, concurrency, and the post-publish package surface.
The aim isn't a test count or a coverage figure — it's showing how many kinds of failure and boundary conditions are exercised. You can read the CI runs, the test suite and the security policy yourself.
That's exactly why there's Observe mode, a removable footprint, safe defaults, and a published test and security model. The aim is to make up for the track record it doesn't yet have with design, verification, and transparency — trust through evidence now, and through evidence and adoption over time.
CommitCourier does not make every webhook failure disappear. Being clear about the boundary of responsibility is part of being safe.
CommitCourier is pre-release. Real adoption feedback, design reviews, security findings, and contributions to docs or adapters are all welcome. A point you got stuck on, a missing feature, an unclear explanation, or a small question — any of it can be shared on GitHub. For security issues, please use the private channel in SECURITY.md rather than a public issue.
Open the issue in public ↓ Write down the reasoning ↓ Work the fix ↓ Add tests ↓ Close it with the outcome recorded
Don't take it on trust. Add it small, observe it without sending, and enable it once you're convinced — then back out the dedicated parts if it isn't a fit.
Learn the webhook problem ↓ Review CommitCourier's design ↓ Watch the live demo ↓ Try it in Observe mode (nothing sent) ↓ Read the integration code ↓ GitHub / npm