framework
Expo
Use Playstack authentication and local-first contracts with Expo SecureStore, SQLite, and React Native lifecycle adapters.
Define typed notifications, resolve recipient preferences, deliver across explicit channels, and retain one provider-independent history of every send.
available
Validate input, declare eligible channels, and render mail or in-app content from one application-owned registry.
available
Persist recipient-scoped notifications and expose headless listing, read, archive, and retention behavior to React clients.
available
Route resolved sends through independent mail, push, in-app, SMS, or webhook slots behind one suppression gate.
available
Correlate provider acceptance, delivery, bounce, complaint, and suppression outcomes without storing message bodies.
framework
Use Playstack authentication and local-first contracts with Expo SecureStore, SQLite, and React Native lifecycle adapters.
integration
An APNs delivery seam with application-owned provider credentials and device selection.
integration
An FCM delivery seam with explicit provider transport and target lifecycle.
integration
A Web Push delivery seam without requiring an application notification inbox.
framework
Headless domain bindings plus optional Chakra application and admin compositions, with server authority kept outside the client.
framework
Compose Playstack server contracts, React bindings, SSR handoff, and route adapters at the Next.js application edge.
framework
Connect portable Playstack capabilities to dependency injection, guards, decorators, request context, workers, and lifecycle hooks.
integration
Dispatch and process typed Playstack jobs through BullMQ with explicit Redis ownership and native queue access.
integration
Dispatch portable Playstack queue jobs through Inngest and serve the generated functions from Next.js, NestJS, or another supported framework.
integration
Deliver rendered messages and SES templates through an application-configured AWS SDK client.
integration
Deliver rendered messages or stored Mailgun templates through an explicit regional provider client.
integration
Deliver rendered Playstack mail or Postmark provider templates through an explicit driver and native client escape hatch.
integration
Deliver transactional mail and synchronize consent-aware audience contacts through explicit Resend adapters.
integration
Deliver rendered messages and dynamic templates through an isolated SendGrid mail client.
integration
Deliver portable rendered email through an application-configured Nodemailer transport.
integration
Persist Playstack capabilities through explicit application-owned Prisma clients, transactions, and managed schema fragments.
A notification definition owns validated input, category, eligible channels, and rendering. Recipient preference narrows those channels. The delivery layer then applies provider-independent suppression and dispatch policy before any send leaves the application.
import { defineNotifications } from '@playstack/notifications'
export const notifications = defineNotifications({
'account.invitation.accepted': {
input: invitationAcceptedSchema,
category: 'transactional',
channels: ['mail', 'inApp'],
digestible: true,
render: {
mail: ({ input }) => renderInvitationAcceptedEmail(input),
inApp: ({ input }) => ({
title: 'Invitation accepted',
body: `${input.memberName} joined ${input.accountName}.`,
href: `/accounts/${input.accountId}/members`,
}),
},
},
})Preferences are checked when a notification is queued and again when its worker runs. An opt-out made between those moments must win. Transactional status may bypass a marketing preference, but it never bypasses invalid destinations, abuse policy, or an explicit stop-all suppression.
await notificationService.enqueue(
'account.invitation.accepted',
input,
{ type: 'user', id: member.id },
operationContext,
)One immutable job is created per recipient and channel. Queue retries remain idempotent, and the operation trace follows the job into delivery feedback.
Mail providers, push services, the in-app inbox, SMS, and outbound webhooks all report different events. Delivery history normalizes those outcomes around the send, masks or encrypts destinations according to application policy, and gives support one place to answer what happened.
Delivery exposes Expo, APNs, FCM and Web Push seams; Devices manages encrypted targets. Applications can send bounded sync hints without installing the notifications inbox. Recipient/enrollment checks, origin-device exclusion, coalescing, retry scheduling and permanent-token invalidation remain explicit application policy.
Provider acceptance is not proof of device execution. Keep content and credentials out of payloads and qualify each provider's response lifecycle and native background behavior.