I’ve been building a small open-source CLI called Spoke Hooks.
The problem I’m trying to solve is pretty simple:
When a Stripe webhook breaks after a code change, the interesting failures often come from real event payloads — retries, duplicate deliveries, odd payload shapes, or business-specific data — not from the clean test payload you wrote six months ago.
Spoke Hooks lets you keep those events as regression fixtures.
The workflow is:
npm install -D [@spoke](/spoke)-labs/hooks
npx spoke-hooks init
npx spoke-hooks add stripe-event.json
npx spoke-hooks baseline
npx spoke-hooks test
baseline records how your current webhook handler responds.
After changing your code, test replays the same event. If the HTTP status or response body changes, it fails with a non-zero exit code, so it can run in CI.
Right now the scope is intentionally small: Stripe + Node.js + Express, local-only, with no account, hosted backend, dashboard, or cloud storage.
GitHub:
https://github.com/Spoke94/spoke-hooks
npm:
npm install -D [@spoke](/spoke)-labs/hooks
What I’m looking for right now is not feature ideas from people who haven’t used it yet.
I’d like to find 2–3 developers who already maintain a Stripe webhook handler and are willing to try it on a real or realistic project.
If you do, I’d especially like to know:
where the workflow feels awkward,
whether baseline + replay is actually useful,
and what stops you from keeping real webhook events as regression fixtures today.
I’m trying to validate the workflow before building anything bigger.
The workflow is concrete, but the real test is whether developers keep using real-event fixtures after the first setup. Does baseline + replay become part of CI naturally?
Exactly — I think that’s the more important test than whether the first setup works.
I know the baseline + replay workflow works technically in CI, but I don’t have external evidence yet that teams keep maintaining the fixture corpus over time. That’s one of the things I’m trying to validate before expanding the product.
My hypothesis is that it only sticks if adding a new production event is cheap enough that developers treat it like adding a regression test after a bug — not like maintaining another test system.
Have you used any fixture/snapshot-based workflow that actually became part of the team’s CI habit? I’d be interested in what made people keep it up versus abandon it after the first setup.
And if you maintain a Stripe webhook handler yourself, I’d be very interested in having you try the current workflow and tell me whether it feels like something you’d actually leave in CI.
That “leave it in CI” test is exactly the signal I’d be interested in seeing. What’s the best email to reach you on?
Absolutely — you can reach me at spoke9412@gmail.com.
I’d really appreciate it if you try the current version in a real or realistic Stripe/Node project, especially with the idea of leaving spoke-hooks test in CI rather than just running it once.
I’m most interested in where the workflow becomes annoying, what would stop you from keeping it in CI, and whether maintaining the real-event fixtures feels natural over time.
Feel free to email me whenever you get a chance to try it.
Thanks! I’ve just sent it over.
Looking forward to hearing your thoughts whenever you have a chance.
The thing that decides whether a team can adopt this is redaction at the add step. Real Stripe events carry emails, names, addresses and card metadata, so spoke-hooks add is effectively asking developers to commit customer data into git, which is an instant no from anyone who has to pass a security review. Ship a default scrub of known PII fields with an allowlist for the business fields people actually assert on, and this goes from a personal tool to something usable inside a company.
That’s a fair point, and I agree this is a real adoption blocker for teams with security review requirements.
Right now, spoke-hooks add imports the event JSON as-is — there is no built-in redaction step yet. So today the developer is responsible for sanitizing production events before committing them.
A default scrub of known PII fields, with an explicit allowlist for fields the team wants to preserve, sounds much closer to the workflow I’d want for company use as well.
I’m deliberately trying not to add features before I know they unblock real usage, so I’d like to ask one thing: if spoke-hooks add redacted known PII by default and let you keep selected business fields, would that be enough for you to actually try it in a real project?
Also, are there any fields you would definitely want preserved by default for webhook regression testing?
Same problem from the reconciliation side. When you replay real events, do you also keep fixtures for payout., refund., and balance_transaction.* — not just charge.*? Those are the events where a payload shape change can quietly break the books: fee breakdowns shift, disputes land after a payout settles, and suddenly the CSV does not tie out. Curious whether you've seen that in the wild.
That’s a really good point.
Spoke Hooks isn’t limited to charge.* events — the fixture/replay flow works with generic Stripe event payloads, so payout.* and refund.* shaped events can be preserved and replayed as well.
What I haven’t validated yet is the reconciliation-specific failure mode you’re describing. V0 currently compares the webhook handler’s HTTP status and response body, so if the handler still returns the same response but silently produces the wrong ledger/reconciliation state, that would not be caught yet.
I also haven’t personally seen that exact payout/reconciliation breakage in the wild yet, so this is exactly the kind of case I’m trying to learn from.
If you have a sanitized payout/refund example, I’d be very interested to know what output you would actually want to assert on — ledger rows, fee breakdowns, exported reconciliation data, or something else. That would help me understand whether the useful regression boundary is the HTTP response or the downstream accounting effect.