# Fast and Simple NestJS App Deployment on Vercel

> This guide is beneficial if you're using [Express](https://expressjs.com/) adapter. For NestJS applications utilizing the [Fastify](https://fastify.dev/) adapter, these links may be helpful:
> 
> * [https://fastify.dev/docs/latest/Guides/Serverless/#vercel](https://fastify.dev/docs/latest/Guides/Serverless/#vercel)
>     
> * [https://github.com/vercel/examples/tree/main/starter/fastify](https://github.com/vercel/examples/tree/main/starter/fastify)
>     

🚀 You can access the complete source code discussed in this article at this GitHub repository: [https://github.com/mahdavipanah/nestjs-on-vercel](https://github.com/mahdavipanah/nestjs-on-vercel)

## Vercel's Support for Express Apps

Vercel offers a convenient feature for deploying your Express app by:

1. Exposing the Express app object in an API.
    
2. Defining a rewrite rule that directs all incoming traffic to this single API.
    

I followed [Vercel’s official guide for deploying Express](https://vercel.com/guides/using-express-with-vercel) to deploy NestJS by similarly exposing NestJS’s underlying Express app object.

## Step 1 - create a NestJS app

> Skip this step if you already have a NestJS app set up.

[Install NestJS](https://docs.nestjs.com/first-steps) and create a new app:

```bash
nest new my-app
```

### **Step 2 - Install Necessary NPM Packages**

```bash
npm install express @nestjs/platform-express
npm install -D @types/express
```

## Step 3 - Create `src/AppFactory.ts` file

This file serves as a single module that manages all necessary NestJS app bootstrapping and exports both the NestJS app and its underlying Express app object.

Create a file named `AppFactory.ts` inside the `src` directory in your project’s root:

```typescript
import { ExpressAdapter } from '@nestjs/platform-express';
import { NestFactory } from '@nestjs/core';
import express, { Request, Response } from 'express';
import { Express } from 'express';
import { INestApplication } from '@nestjs/common';
import { AppModule } from './app.module.js';

export class AppFactory {
  static create(): {
    appPromise: Promise<INestApplication<any>>;
    expressApp: Express;
  } {
    const expressApp = express();
    const adapter = new ExpressAdapter(expressApp);
    const appPromise = NestFactory.create(AppModule, adapter);

    appPromise
      .then((app) => {
        // You can add all required app configurations here

        /**
         * Enable cross-origin resource sharing (CORS) to allow resources to be requested from another domain.
         * @see {@link https://docs.nestjs.com/security/cors}
         */
        app.enableCors({
          exposedHeaders: '*',
        });

        app.init();
      })
      .catch((err) => {
        throw err;
      });

    // IMPORTANT This express application-level middleware makes sure the NestJS app is fully initialized
    expressApp.use((req: Request, res: Response, next) => {
      appPromise
        .then(async (app) => {
          await app.init();
          next();
        })
        .catch((err) => next(err));
    });

    return { appPromise, expressApp };
  }
}
```

## **Step 4 - Modify** `src/main.ts` File

By default, NestJS has a `src/main.ts` file that serves as the entry point of the application, including all configuration and bootstrapping. Modify this file to move everything to the `AppFactory.ts` file, keeping only the invocation of the `listen` method:

```typescript
import { AppFactory } from './AppFactory.js';

async function bootstrap() {
  const { appPromise } = AppFactory.create();
  const app = await appPromise;

  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
```

## **Step 5 - Add** `api/index.ts` File

By default, the Vercel runtime builds and serves any function created within the `/api` directory of a project to Vercel ([doc](https://vercel.com/docs/functions/runtimes/node-js)). Since Vercel understands and handles the Express app object, create a function inside this directory that exports the Express app object:

```typescript
/**
 * This file exports Express instance for specifically for the deployment of the app on Vercel.
 */

import { AppFactory } from '../src/AppFactory.js';

export default AppFactory.create().expressApp;
```

## **Step 6 - Add** `vercel.json` File

Create a file named `vercel.json` in the project’s root directory to configure Vercel. Here, define a rewrite rule for Vercel to use the Express app to serve all incoming traffic ([doc](https://vercel.com/docs/projects/project-configuration)).

You can also use a `tsconfig.json` file at the `api` directory to configure the Vercel’s TypeScript compiler. Most options are supported aside from [**"Path Mappings"**](https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping) and [**"Pr**](https://www.typescriptlang.org/docs/handbook/project-references.html)[**oject Reference**](https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping)[**s"**](https://www.typescriptlang.org/docs/handbook/project-references.html).

```typescript
{
  "version": 2,
  "buildCommand": "npm run build",
  "outputDirectory": ".",
  "rewrites": [
    {
      "source": "/(.*)",
      "destination": "/api"
    }
  ]
}
```

## **Step 7 - Create a Project on Vercel**

Congratulations 🎉! We are almost done. Now, create a git repository and push your source code to it. Then, go to your Vercel account, create a new project, and import the git repository. You can also use [this article’s example GitHub repository](https://github.com/mahdavipanah/nestjs-on-vercel).

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1732642786627/ff53c571-d062-486f-9ba0-db195dfb7b93.png align="center")
