The <Inbox /> infrastructure for modern products
The notification platform that turns complex multi-channel delivery into a single <Inbox /> component. Built for developers, designed for growth, powered by open source.
Notifications brands count on
Ensuring seamless notifications from business to users, with zero hassle.
The Novu difference
- Premier DXLearn more
Premier DX
Simple integrations with real-time data access and protections power critical notifications.
- 100% flexibleLearn more
100% flexible
Build workflows in the Ul, extend with code, and embed customizable ‹Inbox /> components.
- Open source backedLearn more
Open source backed
Community driven and commercially-backed notifications innovation that never locks you in.
Novu <Inbox />

Add In-App Notifications with the most customizable <Inbox/>
Enable in-app notifications in your app or website with a pre-built and customizable components, available in popular frameworks.
SEE IT LIVEComplete control and flexibility
Optionally extend Novu with the Novu Framework for all the power of home-grown notifications infrastructure with complete flexibility to implement any workflow imaginable.
1import { workflow, CronExpression } from '@novu/framework';
2import { z } from 'zod';
3import { render } from '@react-email/components';
4
5const weeklyComments = workflow(alias) workflow( id: string, execute: Execute<...>, options?: WorkflowOptions<...>,): Workflow<...>Define a notification workflow.('weekly-comments', async (event(parameter) event: { payload: { userName: string; ... }; step: Step; subscriber: { firstName: string; ... };}The event that triggered the workflow.) => {
6 await event.step.inApp(method) email: ChannelStep<{ body: string }, { seen: boolean; ... }>Send an email.('inbox-notification', async () => ({
7 subject: `**${event.payloadpayload: { userName: string; comment: string;};The data passed during the trigger, typesare generated from `payloadSchema`.userName}** commented in project`,
8 body: event.payload.comment,
9 }));
10
11 const digest = await event.step.digest('digest-comments', (controls) => ({
12 cron: controls.schedule
13 }), { controlSchema: z.object({ schedule: z.nativeEnum(CronExpression) }) });
14
15 await event.step.email('digest-email', async (controls) => ({
16 subject: controls.subject,
17 body: render(<WeeklyDigestEmail {...controls(parameter) controls: { subject: string; openAiModel: "gpt-3.5-turbo" | "gpt-4o"; aiPrompt: string;}The controls for the workflow step.} events={digest.events} />)
18 }), {
19 skip(property) skip: (controls: Controls) => booleanSkip the step. If true is returned, the step will be skipped.: () => !digest.events.length,
20 controlSchema: z.object({
21 subject: z.string().default('Hi {{subscriber.firstName}} - Acme Comments'),
22 openAiModel: z.enum(['gpt-3.5-turbo', 'gpt-4o']).default('gpt-4o'),
23 aiPrompt: z.string().default('Produce a concise comment digest'),
24 })
25 });
26}, { payloadSchema: z.object({ userName: z.string(), comment: z.string() }) });
27
28await weeklyComments.trigger(property) trigger: (event: { payload: { userName: string; comment: string; }; to: Recipients; actor?: Actor | undefined; tenant?: Tenant | undefined;}) => Promise<...>Trigger a notification workflow.({
29 payload: { userName: 'John Doe', comment: 'Are you free to give me a call?' },
30 to: '[email protected]'
31});

Don't just take our word for it...
Explore what developers and non-technical users say about why they're fans of our open-source notifications framework
You're five minutes away from your first Novu-powered notification
Create a free account, send your first notification, all before your coffee gets cold... no credit card required.