Changing the database How to switch from Neon to something else.
By default, next-forge uses Neon as its database provider. However, you can easily switch to another provider like PlanetScale , Prisma Postgres , Supabase , or any other PostgreSQL/MySQL provider.
Here's a step-by-step guide to switch from Neon to PlanetScale:
Create a new database on PlanetScale and get your connection string. It will look something like this:
mysql://<username>:<password>@<region>.aws.connect.psdb.cloud/<database>
Update your environment variables to use the new PlanetScale connection string:
DATABASE_URL = "postgresql://<username>:<password>@<region>.aws.neon.tech/<database>"
DATABASE_URL = "mysql://<username>:<password>@<region>.aws.connect.psdb.cloud/<database>"
DATABASE_URL = "postgresql://<username>:<password>@<region>.aws.neon.tech/<database>"
DATABASE_URL = "mysql://<username>:<password>@<region>.aws.connect.psdb.cloud/<database>"
Etcetera.
Swap out the required dependencies in @repo/database
:
npm pnpm yarn bun
npm uninstall @neondatabase/serverless @prisma/adapter-neon ws @types/ws
npm install @planetscale/database @prisma/adapter-planetscale
Update the database connection code:
packages/database/index.ts import 'server-only' ;
import { Pool, neonConfig } from '@neondatabase/serverless' ;
import { PrismaNeon } from '@prisma/adapter-neon' ;
import ws from 'ws' ;
import { Client, connect } from '@planetscale/database' ;
import { PrismaPlanetScale } from '@prisma/adapter-planetscale' ;
import { PrismaClient } from '@prisma/client' ;
const databaseUrl = process.env. DATABASE_URL ;
neonConfig.webSocketConstructor = ws;
if ( ! databaseUrl) {
throw new Error ( 'Missing DATABASE_URL environment variable.' );
}
declare global {
var cachedPrisma : PrismaClient | undefined ;
}
const pool = new Pool ({ connectionString: databaseUrl });
const adapter = new PrismaNeon (pool);
const client = connect ({ url: databaseUrl });
const adapter = new PrismaPlanetScale (client);
export const database = new PrismaClient ({ adapter });
Update your Prisma schema to use the new database provider:
packages/database/prisma/schema.prisma // This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
provider = "prisma-client-js"
previewFeatures = [ "driverAdapters" ]
}
datasource db {
provider = "postgresql"
provider = "mysql"
url = env ( "DATABASE_URL" )
relationMode = "prisma"
}
// This is a stub model.
// Delete it and add your own Prisma models.
model Page {
id Int @id @default ( autoincrement ())
email String @unique
name String ?
}
Add a dev
script to your package.json
:
packages/database/package.json {
"scripts" : {
"dev" : "pscale connect [database_name] [branch_name] --port 3309"
}
}
Prisma Postgres is a serverless database with zero cold starts and a generous free tier. You can learn more about its architecture that enables this here .
Create a new Prisma Postgres instance via the Prisma Data Platform and get your connection string. It will look something like this:
prisma+postgres://accelerate.prisma-data.net/?api_key=ey....
Update your environment variables to use the new Prisma Postgres connection string:
DATABASE_URL = "postgresql://<username>:<password>@<region>.aws.neon.tech/<database>"
DATABASE_URL = "prisma+postgres://accelerate.prisma-data.net/?api_key=ey...."
Swap out the required dependencies in @repo/database
:
npm pnpm yarn bun
npm uninstall @neondatabase/serverless @prisma/adapter-neon ws @types/ws
npm install @prisma/extension-accelerate
Update the database connection code:
packages/database/index.ts import 'server-only' ;
import { Pool, neonConfig } from '@neondatabase/serverless' ;
import { PrismaNeon } from '@prisma/adapter-neon' ;
import ws from 'ws' ;
import { withAccelerate } from '@prisma/extension-accelerate' ;
import { PrismaClient } from '@prisma/client' ;
const databaseUrl = process.env. DATABASE_URL ;
neonConfig.webSocketConstructor = ws;
if ( ! databaseUrl) {
throw new Error ( 'Missing DATABASE_URL environment variable.' );
}
declare global {
var cachedPrisma : PrismaClient | undefined ;
}
const pool = new Pool ({ connectionString: databaseUrl });
const adapter = new PrismaNeon (pool);
export const database = new PrismaClient (). $extends ( withAccelerate ());
Your project is now configured to use your Prisma Postgres instance for migrations and queries.
Explore caching and real-time database events with Prisma Postgres
Note that thanks to the first-class integration of other Prisma products, Prisma Postgres comes with additional features out-of-the-box that you may find useful:
Caching
To cache a query with Prisma Client, you can add the swr
and ttl
options to any given query, for example:
const pages = await prisma.page. findMany ({
swr: 60 , // 60 seconds
ttl: 60 // 60 seconds
})
Learn more in the Accelerate documentation .
Real-time database events
To stream database change events from your database, you first need to install the Pulse extension:
npm pnpm yarn bun
npm install @prisma/extension-pulse
Next, you need to add your Pulse API key as an environment variable:
Note : You can find your Pulse API key in your Prisma Postgres connection string, it's the value of the api_key
argument and starts with ey...
. Alternatively, you can find the API key in your Prisma Postgres Dashboard .
packages/database/index.ts import 'server-only' ;
import { withPulse } from '@prisma/extension-pulse' ;
import { withAccelerate } from '@prisma/extension-accelerate' ;
import { PrismaClient } from '@prisma/client' ;
const databaseUrl = process.env. DATABASE_URL ;
const pulseApiKey = process.env. PULSE_API_KEY ;
if ( ! databaseUrl) {
throw new Error ( 'Missing DATABASE_URL environment variable.' );
}
if ( ! pulseApiKey) {
throw new Error ( 'Missing PULSE_API_KEY environment variable.' );
}
declare global {
var cachedPrisma : PrismaClient | undefined ;
}
export const database = new PrismaClient ()
. $extends ( withAccelerate ())
. $extends ( withPulse ({ apiKey: pulseApiKey })) ;
You can now stream any change events from your database using the following code:
const stream = await prisma.page. stream ();
console. log ( `Waiting for an event on the \` Page \` table ... ` );
for await ( const event of stream) {
console. log ( 'Received an event:' , event);
}
Learn more in the Pulse documentation .