{"id":49373463,"url":"https://github.com/better-notify/better-notify","last_synced_at":"2026-05-22T15:07:45.295Z","repository":{"id":354292257,"uuid":"1220728224","full_name":"better-notify/better-notify","owner":"better-notify","description":"Type-safe notification infrastructure for Node.js","archived":false,"fork":false,"pushed_at":"2026-05-06T09:19:04.000Z","size":1621,"stargazers_count":7,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-06T09:43:19.134Z","etag":null,"topics":["better-notify","cloudflare","nodejs","notifications","notify","orpc","resend","trpc","typescript"],"latest_commit_sha":null,"homepage":"https://better-notify.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/better-notify.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-25T08:50:56.000Z","updated_at":"2026-05-06T07:23:22.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/better-notify/better-notify","commit_stats":null,"previous_names":["better-notify/better-notify"],"tags_count":40,"template":false,"template_full_name":null,"purl":"pkg:github/better-notify/better-notify","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/better-notify%2Fbetter-notify","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/better-notify%2Fbetter-notify/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/better-notify%2Fbetter-notify/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/better-notify%2Fbetter-notify/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/better-notify","download_url":"https://codeload.github.com/better-notify/better-notify/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/better-notify%2Fbetter-notify/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32797265,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-08T08:22:46.396Z","status":"ssl_error","status_checked_at":"2026-05-08T08:22:45.650Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["better-notify","cloudflare","nodejs","notifications","notify","orpc","resend","trpc","typescript"],"created_at":"2026-04-28T01:04:38.460Z","updated_at":"2026-05-22T15:07:45.289Z","avatar_url":"https://github.com/better-notify.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cpicture\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"libs/ui/src/assets/logo-stacked-white.svg\"\u003e\n    \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"libs/ui/src/assets/logo-stacked.svg\"\u003e\n    \u003cimg alt=\"Better-Notify\" src=\"libs/ui/src/assets/logo-stacked.svg\" width=\"268\"\u003e\n  \u003c/picture\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003eEnd-to-end typed notification infrastructure for Node.js and Bun.\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.npmjs.com/package/@betternotify/core\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/@betternotify/core?label=npm\u0026color=3a5a8c\" alt=\"npm version\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/better-notify/better-notify/blob/main/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/github/license/better-notify/better-notify?color=3a5a8c\" alt=\"license\"\u003e\u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/node/v/@betternotify/core?color=3a5a8c\" alt=\"node version\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://better-notify.com\"\u003eWebsite\u003c/a\u003e ·\n  \u003ca href=\"https://better-notify.com/docs\"\u003eDocs\u003c/a\u003e ·\n  \u003ca href=\"https://better-notify.com/blog\"\u003eBlog\u003c/a\u003e ·\n  \u003ca href=\"https://better-notify.com/docs/changelog\"\u003eChangelog\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cbr\u003e\n\n## Why Better-Notify?\n\n- **Typed end-to-end** — one catalog type drives the client, queue worker, and webhook router. Schema and template can't silently drift.\n- **Multi-channel** — email, SMS, push, Slack, Discord, Telegram, and more from the same pipeline. Define once, send anywhere.\n- **Zero lock-in** — swap transports (SMTP, Resend, Mailchimp, Cloudflare Email) without touching business logic. Standard Schema means no hard Zod dependency either.\n- **Batteries included** — middleware (rate-limit, idempotency, tracing, dry-run), hooks, plugins, and a logger built into core.\n\n## Quick start\n\n```sh\nnpm install @betternotify/core @betternotify/email zod\n```\n\n```ts\nimport { createNotify, createClient } from '@betternotify/core';\nimport { emailChannel, mockTransport } from '@betternotify/email';\nimport { z } from 'zod';\n\nconst email = emailChannel({ defaults: { from: 'hello@example.com' } });\nconst rpc = createNotify({ channels: { email } });\n\nconst catalog = rpc.catalog({\n  welcome: rpc\n    .email()\n    .input(z.object({ name: z.string() }))\n    .subject(({ input }) =\u003e `Welcome, ${input.name}`)\n    .template({ render: async ({ input }) =\u003e ({ html: `\u003ch1\u003eHi ${input.name}\u003c/h1\u003e` }) }),\n});\n\nconst mail = createClient({\n  catalog,\n  transportsByChannel: { email: mockTransport() },\n});\n\nawait mail.welcome.send({ to: 'john@example.com', input: { name: 'John' } });\n```\n\n## Packages\n\n| Channel                                                                          | Transport                                                                                        | Template                                                                               |\n| -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------- |\n| [`@betternotify/email`](https://www.npmjs.com/package/@betternotify/email)       | [`@betternotify/smtp`](https://www.npmjs.com/package/@betternotify/smtp)                         | [`@betternotify/react-email`](https://www.npmjs.com/package/@betternotify/react-email) |\n| [`@betternotify/sms`](https://www.npmjs.com/package/@betternotify/sms)           | [`@betternotify/resend`](https://www.npmjs.com/package/@betternotify/resend)                     | [`@betternotify/mjml`](https://www.npmjs.com/package/@betternotify/mjml)               |\n| [`@betternotify/push`](https://www.npmjs.com/package/@betternotify/push)         | [`@betternotify/mailchimp`](https://www.npmjs.com/package/@betternotify/mailchimp)               | [`@betternotify/handlebars`](https://www.npmjs.com/package/@betternotify/handlebars)   |\n| [`@betternotify/webpush`](https://www.npmjs.com/package/@betternotify/webpush)   | [`@betternotify/cloudflare-email`](https://www.npmjs.com/package/@betternotify/cloudflare-email) |                                                                                        |\n| [`@betternotify/slack`](https://www.npmjs.com/package/@betternotify/slack)       | [`@betternotify/twilio`](https://www.npmjs.com/package/@betternotify/twilio)                     |                                                                                        |\n| [`@betternotify/discord`](https://www.npmjs.com/package/@betternotify/discord)   | [`@betternotify/autosend`](https://www.npmjs.com/package/@betternotify/autosend)                 |                                                                                        |\n| [`@betternotify/telegram`](https://www.npmjs.com/package/@betternotify/telegram) | [`@betternotify/onesignal`](https://www.npmjs.com/package/@betternotify/onesignal)               |                                                                                        |\n| [`@betternotify/whatsapp`](https://www.npmjs.com/package/@betternotify/whatsapp) | [`@betternotify/selligent`](https://www.npmjs.com/package/@betternotify/selligent)               |                                                                                        |\n| [`@betternotify/github`](https://www.npmjs.com/package/@betternotify/github)     |                                                                                                  |                                                                                        |\n| [`@betternotify/zapier`](https://www.npmjs.com/package/@betternotify/zapier)     |                                                                                                  |                                                                                        |\n\nCore: [`@betternotify/core`](https://www.npmjs.com/package/@betternotify/core) · Integrations: [`@betternotify/mcp`](https://www.npmjs.com/package/@betternotify/mcp)\n\nScaffolding: [`create-better-notify`](https://www.npmjs.com/package/create-better-notify)\n\n```sh\nnpx create-better-notify@latest\n```\n\n---\n\n## Star History\n\n\u003ca href=\"https://www.star-history.com/?repos=better-notify%2Fbetter-notify\u0026type=date\u0026legend=top-left\"\u003e\n \u003cpicture\u003e\n   \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://api.star-history.com/chart?repos=better-notify/better-notify\u0026type=date\u0026theme=dark\u0026legend=top-left\" /\u003e\n   \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://api.star-history.com/chart?repos=better-notify/better-notify\u0026type=date\u0026legend=top-left\" /\u003e\n   \u003cimg alt=\"Star History Chart\" src=\"https://api.star-history.com/chart?repos=better-notify/better-notify\u0026type=date\u0026legend=top-left\" /\u003e\n \u003c/picture\u003e\n\u003c/a\u003e\n\n---\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/better-notify/better-notify\"\u003eGitHub\u003c/a\u003e ·\n  \u003ca href=\"https://x.com/better_notify\"\u003eX\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003eCreated by \u003ca href=\"https://github.com/thereis\"\u003eLucas Reis\u003c/a\u003e · \u003ca href=\"https://x.com/lucasreis\"\u003eX\u003c/a\u003e\u003c/p\u003e\n\n\u003cp align=\"center\"\u003eMIT License\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbetter-notify%2Fbetter-notify","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbetter-notify%2Fbetter-notify","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbetter-notify%2Fbetter-notify/lists"}