Comparison
How a library inside your stack differs from a hosted notification service.
Novu, Knock, and OneSignal are notification services. better-push is a library inside your application. The important choice is not a checklist of push APIs; it is where subscriber identity, preferences, content, endpoints, and operations live.
| better-push | Novu / Knock / OneSignal | Build it yourself | |
|---|---|---|---|
| User and device source of truth | your Postgres | synced to a vendor | whatever you design |
| Endpoint and session | mounted in your app | vendor API and SDK | yours |
| Notification content | your database and provider | vendor service and provider | yours |
| Push and in-app feed | included | included | build both |
| Email, SMS, Slack | no | commonly included | build or integrate |
| Campaign and template UI | no | hosted product | build it |
| Non-engineer dashboard | no hosted dashboard | yes | build and operate it |
| Databases | Postgres only | vendor-managed | your choice |
| Operations and on-call | you | shared with vendor | you |
| Hosting fee | infrastructure you run | usage or contract pricing | infrastructure and engineering |
The subscriber-sync problem
A hosted service needs a second representation of your users. Your application must create subscribers, update profile fields, rotate device tokens, reconcile preferences, and delete data in both systems. That can be a good trade when a marketing or support team needs a hosted workflow product.
better-push removes that category of integration. session() returns the user
already authenticated by your app, bp_device.user_id uses the same id, and a
send queries that user's devices and preferences in the same database. There is
no subscriber API to keep synchronized because there is no second subscriber
store.
When a hosted service is the better fit
Choose a service when non-engineers need campaigns, visual workflows, templating, analytics, or channels such as email and SMS; when vendor support and an external team on call are worth the data boundary; or when Postgres and Node do not fit the application.
When better-push is the better fit
Choose better-push when push and an in-app feed belong inside a TypeScript app, subscriber data should not be synchronized elsewhere, notification history needs to join directly to application data, and your team is prepared to run the database, worker, provider credentials, and operational response.
When to build it yourself
Build from scratch when the provider or workflow model is fundamentally different, another database is mandatory, or owning every protocol detail is a product requirement. The cost includes token lifecycle, retries, idempotency, preferences, cross-user query safety, provider receipts, observability, admin authorization, and years of edge cases—not only the first successful push.