🚀Announcing Flightcontrol - Optimized Deployment for Fullstack Blitz.js and Next.js 🚀
Back to Documentation Menu

Migrating to Blitz

Topics

Jump to a Topic

Migrating from Next.js

Blitz is built on top of Next.js, so naturally follows Next's priciples and patterns. The difference between Next and Blitz is that Blitz adds all the missing features and functionality that turns Next into a true fullstack framework. That also means that you can migrate to Blitz in a few steps.

1. Install Dependencies

You need to replace next dependency with blitz.

yarn remove next ## npm uninstall next
yarn add blitz ## npm install blitz

We recommend using TypeScript (but it's not a requirement!). If you're not doing it already, you can add TypeScript with following commands:

yarn add typescript ## npm install typescript
yarn tsc init ## npx tsc init

The second command will create a tsconfig.json file with TypeScript configuration. Here's an example tsconfig.json that you can use:

{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "baseUrl": "./",
    "allowJs": true,
    "skipLibCheck": true,
    "strict": false,
    "strictNullChecks": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "noUncheckedIndexedAccess": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
    "tsBuildInfoFile": ".tsbuildinfo"
  },
  "exclude": ["node_modules"],
  "include": ["blitz-env.d.ts", "next-env.d.ts" "**/*.ts", "**/*.tsx"]
}

"allowJs": true option will let you keep your JavaScript files so that you don't have to migrate your application at once.

2. Update Scripts in package.json

Instead of using next to run a command, you can use blitz. There are a few other commands that you can find useful — read about it here.

"scripts": {
  "dev": "blitz dev",
  "build": "blitz build",
  "start": "blitz start"
}

3. Rename the Configuration File

As the third step, you need to rename next.config.js to blitz.config.ts (or if you aren't using TypeScript, to blitz.config.js). To learn more about the configuration, check out the docs.

Optional Next Steps

If you want to start using Blitz's queries and mutations, we recommend creating an app folder and writing your application logic there. You can take a look at the default file structure of newly generated Blitz apps. Below, we'll cover how to setup a database, and Blitz's auth.

Add a Database

By default, Blitz uses Prisma which is a strongly typed database client. If you are new to databases, check out Prisma's Data Guide which covers the very large majority of everything you might want to know.

As the first step, you need to add the required dependecies:

yarn add prisma @prisma/client ## npm install prisma @prisma/client

Once this is done, you can initialize Prisma:

blitz prisma init

You can optionally pass --datasource-provider=sqlite for a quick SQLite database to use in your development enviroment. The default driver is Postgres.

The init command will create a new folder, prisma, with a schema.prisma file where you can define your database models.

For Blitz to work properly, you'll need to rename the prisma folder to db, and add the following to your package.json file:

"prisma": {
  "schema": "db/schema.prisma"
},

Then, you have to create a index.ts (or index.js) file in the db folder. Inside we'll use enhancePrisma function from Blitz to wrap the Prisma's client:

// db/index.ts

import { enhancePrisma } from "blitz"
import { PrismaClient } from "@prisma/client"

const EnhancedPrisma = enhancePrisma(PrismaClient)

export * from "@prisma/client"
export default new EnhancedPrisma()

Check out our Database Overview docs to learn more about the database setup, Prisma, and some useful utilities.

Setup Blitz's Auth

In order to use Blitz's built-in auth, you need to create required database models. Add the following code to your db/schema.prisma file:

model User {
  id             Int      @id @default(autoincrement())
  createdAt      DateTime @default(now())
  updatedAt      DateTime @updatedAt
  name           String?
  email          String   @unique
  hashedPassword String?
  role           String   @default("USER")

  tokens   Token[]
  sessions Session[]
}

model Session {
  id                 Int       @id @default(autoincrement())
  createdAt          DateTime  @default(now())
  updatedAt          DateTime  @updatedAt
  expiresAt          DateTime?
  handle             String    @unique
  hashedSessionToken String?
  antiCSRFToken      String?
  publicData         String?
  privateData        String?

  user   User? @relation(fields: [userId], references: [id])
  userId Int?
}

model Token {
  id          Int      @id @default(autoincrement())
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt
  hashedToken String
  type        String
  expiresAt   DateTime
  sentTo      String

  user   User @relation(fields: [userId], references: [id])
  userId Int

  @@unique([hashedToken, type])
}

Then run blitz prisma migrate dev in your terminal to apply the changes to your database and update Prisma client.

You also need to update your blitz.config.ts file and add sessionMiddleware setup:

// blitz.config.ts
import { BlitzConfig, sessionMiddleware } from "blitz"

const config: BlitzConfig = {
  middleware: [
    sessionMiddleware({
      cookiePrefix: "your-app-name",
    }),
  ],
}

module.exports = config

You can take a look at our examples to see how to implement login, logout, sign up, and more, with Blitz's mutations and sessions.

Follow this documentation to setup authorization.

Further Reading

Incrementally Adopting Blitz

You can adopt Blitz incrementally by starting small and adding more pages over time. This way you can prevent derailing feature work by avoiding a complete rewrite.

Using Subpath

The first strategy is to configure your server or proxy such that everything under a specific subpath points to a Blitz app. For example, your existing website might be at example.com, and you might configure your proxy such that example.com/store serves a Blitz e-commerce store.

Using basePath, you can configure your Blitz application's assets and links to automatically work with your new subpath /store. Since each page in Blitz is its own standalone route, pages like pages/products/index.tsx will route to example.com/store/products in your application.

// blitz.config.ts
import { BlitzConfig } from "blitz"

const config: BlitzConfig = {
  basePath: "/store",
}

module.exports = config

To learn more about basePath, take a look at our documentation.

Using Rewrites

The second strategy is to create a new Blitz app that points to the root URL of your domain. Then, you can use rewrites inside blitz.config.ts to have some subpaths to be proxied to your existing app.

For example, let's say you created a Blitz app to be served from example.com with the following blitz.config.ts. Now, requests for the pages you’ve added to this Blitz app (e.g. /about if you’ve added pages/about.tsx) will be handled by Blitz, and requests for any other route (e.g. /dashboard) will be proxied to proxy.example.com.

// blitz.config.ts
import { BlitzConfig } from "blitz"

const config: BlitzConfig = {
  async rewrites() {
    return {
      // After checking all Blitz pages (including dynamic routes)
      // and static files we proxy any other requests
      fallback: [
        {
          source: "/:path*",
          destination: `https://proxy.example.com/:path*`,
        },
      ],
    }
  },
}

module.exports = config

To learn more about rewrites, take a look at our documentation.


Idea for improving this page? Edit it on GitHub.