# NestJS Framework Quickstart Guide (/framework/quickstart/nestjs)

Get started with Novu Framework in a NestJS application

import DeployApp from '@/snippets/quickstart/deploy.mdx';
import NextStepsStep from '@/snippets/quickstart/next-steps.mdx';
import { PackagesStep } from '@/snippets/quickstart/packages.tsx';
import { SecretStep } from '@/snippets/quickstart/secret.tsx';
import { StudioStep } from '@/snippets/quickstart/studio.tsx';
import { TestStep } from '@/snippets/quickstart/test.tsx';
import { WorkflowStep } from '@/snippets/quickstart/workflow.tsx';

In this guide, we will add a Novu [Bridge Endpoint](/framework/endpoint) to a NestJS application and send our first test workflow.

<Steps>
  <Step>
    ### Set up your local environment

    <StudioStep />
  </Step>

  <Step>
    ### Install packages

    <PackagesStep />
  </Step>

  <Step title="Add the NovuModule to your application">
    The `NovuModule` is a NestJS module that registers the Novu Endpoint in your application.

    The following example does not support NestJS dependency injection. If you need to `@Injectable` dependencies in your workflow definition, see [Advanced Usage](#advanced-usage-dependency-injection).

    ```typescript src/app.module.ts
    import { Module } from '@nestjs/common';
    import { NovuModule } from '@novu/framework/nest';
    import { testWorkflow } from './novu/workflows';

    @Module({
        imports: [
            NovuModule.register({
                apiPath: '/api/novu',
                workflows: [testWorkflow],
            }),
        ],
    })
    export class AppModule {}
    ```
  </Step>

  <Step>
    ### Configure your secret key

    <SecretStep />
  </Step>

  <Step>
    ### Create your workflow definition

    Add a `novu` folder in your `src` folder as such `src/novu/workflows.ts` that will contain your workflow definitions.

    <WorkflowStep />
  </Step>

  <Step>
    ### Start your application

    Start your NestJS application with the Novu Endpoint configured.

    If your NestJS application is running on other than `4000` port, restart the `npx novu dev` command with the port:

    ```tsx
    npx novu@latest dev --port <YOUR_NESTJS_APPLICATION_PORT>
    ```
  </Step>

  <Step>
    ### Test your endpoint

    <TestStep framework="NestJS" />
  </Step>

  <Step>
    ### Deploy your application

    <DeployApp />
  </Step>
</Steps>

<NextStepsStep />

## Advanced Usage (Dependency Injection)

If you need to inject dependencies into your workflow definition, you can use the `registerAsync` method.

Add the `NovuModule` using the `registerAsync` method to your `AppModule`.

```typescript src/app.module.ts
import { Module } from '@nestjs/common';
import { NovuModule } from '@novu/framework/nest';
import { NotificationService } from './notification.service';
import { UserService } from './user.service';

@Module({
  imports: [
    NovuModule.registerAsync({
      imports: [AppModule],
      useFactory: (notificationService: NotificationService) => ({
        apiPath: '/api/novu',
        workflows: [notificationService.welcomeWorkflow()],
      }),
      inject: [NotificationService],
    }),
  ],
  providers: [NotificationService, UserService],
  exports: [NotificationService],
})
export class AppModule {}
```

For example, you might need to inject a service that fetches the user's name from a database. This is useful when you need to fetch data in realtime during the execution of your workflow.

An example `UserService` is available below with hardcoded values, but in a real-world application you might use a database or an external API to fetch the user's name.

```typescript src/user.service.ts
import { Injectable } from '@nestjs/common';

@Injectable()
export class UserService {
  getUser(id: string) {
    return {
      name: 'John Doe',
      email: `john.doe.${id}@example.com`,
    };
  }
}
```

Finally, configure your `NotificationService` to use the injected `UserService`.

```typescript src/notification.service.ts
import { Injectable } from '@nestjs/common';
import { workflow } from '@novu/framework';
import { z } from 'zod';
import { UserService } from './user.service';

@Injectable()
export class NotificationService {
  constructor(private readonly userService: UserService) {}

  public welcomeWorkflow() {
    return workflow(
      'welcome-email',
      async ({ step, payload }) => {
        await step.email('send-email', async () => {
          const user = this.userService.getUser(payload.userId);

          return {
            subject: `Hello, ${user.name}`,
            body: `We are glad you are here!`,
          };
        });
      },
      {
        payloadSchema: z.object({
          userId: z.string(),
        }),
      }
    );
  }
}
```

A full example NestJS application demonstrating dependency injection is available [here](https://github.com/novuhq/novu/tree/next/playground/nestjs).
