Skip to main content
Introducing packages.sweber.dev
All packages
BetaMIT + Pro

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/vector

Sooner 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 attempt

Features

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.

FeatureFreePro
Signing, verification, retries and delivery logIncludedIncluded
SSRF protection, secret rotation, idempotencyIncludedIncluded
Memory and PostgreSQL stores, CLIIncludedIncluded
Customer portal (API and React components)Not includedIncluded
Typed event catalog, docs, AsyncAPI and typesNot includedIncluded
Alerts, bulk recovery, metrics and retentionNot includedIncluded
LicenceMITPer person
SupportGitHub issuesAgency and Lifetime

Pro

Pro packagesAdd-ons on top of the core.

  • @weber-development/vector-portal

    An 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-catalog

    A 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-ops

    Operations 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
Join waitlist

Agency

Recommended

For teams of up to ten named people, one price.

CHF 890

per year

2 months free

  • Up to 10 people
  • Support included
Join waitlist

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
Join waitlist

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.
Read the licence terms

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.