Skip to main content

Someone wanted to learn this too, so Grasp built them a personal learning path.

You can keep exploring this one or create your own

Deploying Tanstack Start to Serverless

Hello! Welcome back to our course on transforming your React applications with Tanstack Start.

In our last lesson, we took a deep dive into the production build process. We learned how to generate the client and server bundles, manage environment variables using Vite's mode system, and correctly preview the SSR application locally.

Today, we'll take the next logical step: deploying our application to the web. Our learning outcome is to deploy a Tanstack Start application to a serverless Node.js platform, using Vercel as our example. We will cover the architectural concepts behind platforms like Vercel, configure our project for deployment, and walk through the process of getting it live.

1. The "Why": Understanding Vercel and Serverless Deployment

Before we deploy, it's important to understand the environment we're deploying to. Vercel is a popular platform for modern web applications that abstracts away much of the complexity of traditional server management. It achieves this through concepts like "Serverless Functions" and the "Edge Network."

For a high-level perspective on why these concepts are so impactful, especially regarding performance, let's turn to a well-known voice in the web development community.

That's It, I'm Done With Serverless*

In this video, 'That's It, I'm Done With Serverless*', Theo from t3.gg breaks down the key differences between traditional serverless functions and Edge functions, which are central to Vercel's infrastructure.

Please watch the following two segments: Understanding Edge Runtime vs. Edge Location (00:22 - 02:04): Focus on the distinction between running code in a specific region (like AWS Lambda) versus using a distributed Edge runtime that minimizes cold starts. Performance Comparison: Serverless vs. Edge (12:30 - 15:21): Pay close attention to the visual breakdown of a request lifecycle. This illustrates how eliminating cold starts and database connection overhead dramatically reduces response times.

As the video illustrates, Vercel's architecture offers two primary advantages for an SSR application:

  1. Scalability: Serverless Functions automatically scale with traffic. You don't need to provision or manage servers.
  2. Performance: By using Edge Functions, Vercel can execute your server-side code in a lightweight environment with near-zero cold starts, located geographically close to your users. This significantly reduces latency and improves the Time to First Byte (TTFB).

However, as the video also hints, Edge runtimes are not identical to Node.js and have some limitations (e.g., no access to the file system or native Node.js APIs). Vercel intelligently handles this by allowing you to run functions on either the Edge Runtime or a standard Node.js serverless runtime. For our Tanstack Start app, we'll need a way to tell Vercel how to build and run our server code.

2. The "How": Preparing for Vercel with Nitro

Tanstack Start is a framework-agnostic tool. To make it compatible with a specific hosting platform like Vercel, we use an adapter. The recommended tool for this is Nitro.

Nitro is a build-time utility that takes your generic application code and transforms it into an output format optimized for your target deployment environment. For Vercel, it will package our server code into the Vercel Functions format.

The official Vercel documentation provides a clear guide for this setup.

TanStack Start on Vercel

This official guide, 'TanStack Start on Vercel', details the necessary steps to configure a Tanstack Start project for deployment on Vercel.

Please read the 'Nitro Configuration' section. You don't need to read the 'More resources' part. Focus on the two steps: installing nitro and updating your vite.config.ts file.

Let's summarize the process:

  1. Install Nitro: Add Nitro to your project's development dependencies.

    pnpm add -D nitro
    # or npm install --save-dev nitro
    # or yarn add --dev nitro
    
  2. Configure Vite: Import nitro in your vite.config.ts and add it to the plugins array.

    // vite.config.ts
    import { defineConfig } from 'vite'
    import viteReact from '@vitejs/plugin-react'
    import { tanstackStart } from '@tanstack/react-start/plugin/vite'
    import { nitro } from 'nitro/vite'
    
    export default defineConfig({
      plugins: [
        tanstackStart(),
        nitro(), // Add nitro here
        viteReact(),
      ],
    })
    

With this configuration, when you run pnpm build, the Nitro plugin will automatically hook into the process. It will inspect your code and generate a .vercel/output directory, which contains the serverless functions and static assets structured exactly as Vercel expects.

3. Deploying to Vercel

The most common and recommended way to deploy on Vercel is through Git integration. This creates a seamless Continuous Integration and Continuous Deployment (CI/CD) pipeline.

Here is the step-by-step workflow:

  1. Push to Git: Ensure your project, including the vite.config.ts changes, is pushed to a GitHub, GitLab, or Bitbucket repository.

  2. Create a Vercel Project:

    • Sign up or log in to your Vercel account.
    • On your dashboard, click "Add New... -> Project".
    • Select your Git repository. Vercel will analyze it.
  3. Configure the Project:

    • Vercel will likely detect you are using Vite and select the "Vite" Framework Preset. This is correct.
    • The build settings should be automatically configured. Verify they are:
      • Build Command: vite build or pnpm build
      • Output Directory: This is the key part. Because we are using Nitro, Vercel will automatically detect and use the .vercel/output directory. You don't need to change this setting.
      • Install Command: pnpm install (or your package manager's equivalent).
  4. Add Environment Variables:

    • In the project settings, navigate to the "Environment Variables" section.
    • This is where you must add any secrets your application needs, such as DATABASE_URL or third-party API keys.
    • Remember the security principle from our last lesson: any variable needed on the server but not on the client should not have the VITE_ prefix. Add them here, and they will be securely available via process.env in your server-side code (loaders, server functions).
  5. Deploy:

    • Click the "Deploy" button.
    • Vercel will pull your code, install dependencies, run the build command, and deploy the output. You can monitor the entire process in the build logs.

Once the deployment is complete, Vercel will provide you with a URL where your Tanstack Start application is now live. Any subsequent pushes to your main branch will automatically trigger a new deployment.

4. Alternative: Deploying with the Bun Runtime

Your goal includes mastering bunjs, and Vercel supports it as a runtime for serverless functions. This can offer performance benefits over Node.js. Switching your deployment from Node.js to Bun is straightforward.

The official Bun documentation explains the necessary configuration for Vercel.

Use TanStack Start with Bun

This guide, 'Use TanStack Start with Bun', provides specific instructions for deploying a Nitro-powered application to Vercel using the Bun runtime.

Focus on the 'Hosting' section, specifically the part about deploying to Vercel. Pay close attention to the note that you should not use the bun Nitro preset and the two ways to specify the Bun runtime for Vercel.

To switch your Vercel deployment to Bun, you have two options:

Option 1 (Recommended): Edit vercel.json
Create a vercel.json file in the root of your project with the following content:

{
  "functions": {
    "**": {
      "runtime": "edge"
    }
  },
  "build": {
    "env": {
      "VERCEL_DEPRECATED_BUILD_LAMBDA_RUNTIME": "bun1.x"
    }
  }
}

Note: Vercel's configuration for Bun can change. The above is based on their current best practices for enabling Bun in the build step and using the Edge runtime. Always check the latest Vercel documentation.

Option 2: Configure in vite.config.ts
You can also specify this within your Nitro configuration, as shown in the Bun documentation.

The most important takeaway is the note from the documentation: Do not use the bun Nitro preset when deploying to Vercel. Vercel has its own optimized Bun integration, and specifying the preset can cause conflicts.

Conclusion

In this lesson, we successfully bridged the gap from a local production build to a live, globally-available application.

Key Takeaways:

  • Serverless Platforms like Vercel abstract away server management and provide benefits like automatic scaling and high performance through Edge Functions.
  • Nitro is the essential adapter that transforms a generic Tanstack Start build into a format optimized for a specific host like Vercel.
  • Git-based Deployment is the standard workflow, providing a seamless CI/CD pipeline.
  • Environment Variables must be securely configured in the Vercel project dashboard to protect sensitive data.
  • Runtime Flexibility: Vercel allows you to easily switch between runtimes like Node.js and Bun to optimize your application's performance.

In our next lesson, we will explore an alternative deployment strategy: "Create a production-ready Dockerfile for a Tanstack Start application using the Bun runtime." This will contrast the "serverless" approach with a container-based approach, giving you a broader understanding of modern deployment options.

Can't find a good explanation? Sign up and we'll make it for you

Sign up