VectorSelf-hosted webhooks for Node.js and TypeScript: Standard Webhooks signatures, retries, a delivery log and SSRF protection, in your own PostgreSQL.
pnpm add @sweberdev/vectorSooner or later every SaaS product has to send webhooks to its customers. Doing it properly means signing every request, retrying for hours with backoff when a receiver is down, keeping a log your support team can read, refusing URLs that point into your own network and rotating secrets without downtime. Hosted services such as Svix or Hookdeck do this for you, from several hundred dollars a month, and every event and customer URL passes through their infrastructure.
Vector is the same building block as a library. It signs with the Standard Webhooks format that Svix uses, so receivers can verify with any Standard Webhooks or Svix library, retries eight times over about 27 hours, logs every message, delivery and attempt, and keeps all of it in your own PostgreSQL. It has no dependencies and runs on Node.js, Bun, Deno and in serverless functions.
Vector Pro adds an embeddable portal for your customers, a typed event catalog and operations tooling. It is not on sale yet: join the waitlist to hear when it is.
Example
A short exampleCopy it into your project.
lib/webhooks.ts
import { createVector } from "@sweberdev/vector"
import { createPostgresStore } from "@sweberdev/vector/postgres"
export const vector = createVector({
store: createPostgresStore({ query: (text, params) => pool.query(text, params) }),
})
await vector.endpoints.create({
tenant: "acme",
url: "https://example.com/webhooks",
eventTypes: ["invoice.*"],
})
await vector.send({ tenant: "acme", eventType: "invoice.paid", payload: { invoiceId: "inv_123" } })
vector.start() // delivers, retries for ~27 hours, logs every attemptFeatures
What you getFree under MIT, with Pro on top.
Free, MIT
- Standard Webhooks signatures: HMAC-SHA256 in webhook-id, webhook-timestamp and webhook-signature, verifiable with the Standard Webhooks and Svix libraries
- verify() and verifyRequest() for the receiving side, with replay protection and several secrets during a rotation
- Endpoints per tenant with event type filters (invoice.*), custom headers and their own secret
- Eight attempts over about 27 hours with exponential backoff, jitter, Retry-After and timeouts; dead endpoints are disabled automatically, also on 410 Gone
- Delivery log of every message, delivery and attempt with status code and response; retry a delivery or resend a message with one call
- SSRF protection: no localhost, private networks or cloud metadata, checked when an endpoint is created and again before every attempt
- Secret rotation with a grace period, idempotency keys and test events
- In-memory and PostgreSQL stores (pg, postgres.js, Neon, Supabase, PGlite), safe with several workers, or your own store
- Long-running worker, or process() from a cron job with deliverNow for serverless
- vector CLI: generate secrets, sign, verify, send test events and receive webhooks locally
- No dependencies; runs on Node.js, Bun, Deno and edge runtimes
Pro
- Embeddable customer portal: a tenant-scoped REST handler and React components for endpoints, secrets, the message log, retries and test events
- Typed event catalog with Standard Schema validation, generated Markdown docs, AsyncAPI 3 and TypeScript types, with a CLI
- Operations: alerts to Slack, email or a webhook, bulk recovery after outages, health reports, Prometheus metrics and data retention
Compare
Free and ProSide by side.
| Feature | Free | Pro |
|---|---|---|
| Signing, verification, retries and delivery log | Included | Included |
| SSRF protection, secret rotation, idempotency | Included | Included |
| Memory and PostgreSQL stores, CLI | Included | Included |
| Customer portal (API and React components) | Not included | Included |
| Typed event catalog, docs, AsyncAPI and types | Not included | Included |
| Alerts, bulk recovery, metrics and retention | Not included | Included |
| Licence | MIT | Per person |
| Support | GitHub issues | Agency and Lifetime |
Pro
Pro packagesAdd-ons on top of the core.
@weber-development/vector-portalAn embeddable webhook portal for your customers: a REST handler scoped to one tenant and React components for endpoints, secrets, the message log, retries and test events.
@weber-development/vector-catalogA typed event catalog: validates payloads with any Standard Schema library before sending and generates Markdown docs, an AsyncAPI 3 file and TypeScript types for receivers.
@weber-development/vector-opsOperations tooling: alerts to Slack, email or a webhook, bulk recovery after an outage, a health report, Prometheus metrics and data retention.
Pricing
PricingPrices are in CHF.
Vector Pro: coming soon
The Pro packages are not on sale yet. Join the waitlist and you get a note when they are.
Freelancer
For one person working on client projects.
CHF 290
per year
2 months free
- 1 person
- No support entitlement
Agency
RecommendedFor teams of up to ten named people, one price.
CHF 890
per year
2 months free
- Up to 10 people
- Support included
Lifetime
Pay once for up to ten people and keep updates and repository access.
CHF 2'990
one-time
- Up to 10 people
- Support included
11 people or more: get in touch
- Pay yearly and get two months free: CHF 290 instead of CHF 348 for Freelancer, CHF 890 instead of CHF 1068 for Agency.
- After cancelling, every version you already received keeps working. Only updates and repository access end.
- No licence key, no phone-home. The Pro packages never contact a server to check your licence.
- Agency and Lifetime cover up to ten named people for one price: you choose the number of seats at checkout and assign them in Polar. Your clients and their websites need no licence of their own.
- Checkout, invoices and VAT are handled by Polar as merchant of record.
FAQ
QuestionsShort answers.
Is Vector a hosted service?
No. Vector is a library that runs inside your own application and keeps its data in your own database. There is no account, no API key and nothing that phones home; events and your customers' URLs never leave your infrastructure.
Can my customers verify the webhooks with Svix or Standard Webhooks libraries?
Yes. Vector signs exactly as the Standard Webhooks specification describes, which is the format Svix uses, so receivers can use the standardwebhooks or svix packages in any language. Vector's own verify() also accepts svix-* headers, and with envelope: false the payload is sent as the whole body, as Svix does.
What about ordering and duplicates?
Webhooks are delivered at least once and not in a guaranteed order, with Vector as with any other sender: a retry can arrive after a later event. Every retry of a message carries the same webhook-id, so receivers should store the ids they have processed and skip repeats, and compare timestamps or versions in the payload where order matters. On the sending side, idempotency keys keep a message from being created twice.
Which databases are supported?
An in-memory store for tests and prototypes and a PostgreSQL store that works with pg, postgres.js, Neon, Supabase and PGlite and is safe with several workers. For any other database you implement the VectorStore interface, about fifteen small methods.
Does it work on serverless platforms?
Yes. Instead of the long-running worker you call process() from a cron job, for example a Vercel cron route every minute, and send with deliverNow: true so the first attempt does not wait for the next run. Retries are picked up by the following cron runs.