The Learn Next.js tutorial is quite instructive and fun to follow. I just did not want to use a remote database so I tried to use a local one. That’s not as easy as you may think..

That Github issue helped me getting it running locally while still using the @vercel/postgres Node module: vercel/storage#123.

To summarize:

  1. Follow steps 1 to 4 in https://vercel.com/docs/storage/vercel-postgres/local-development. Save the db.ts (step 3) in app/lib/db.ts
  2. The sql function from @vercel/postgres doesn’t pick up the neonConfig. Add a sql implementation in db.ts based on db.connect() which uses the neonConfig:
import {
  neonConfig,
  QueryResult,
  QueryResultRow,
} from '@neondatabase/serverless';
import { db } from '@vercel/postgres';

neonConfig.wsProxy = (host) => `${host}:54330/v1`;
neonConfig.useSecureWebSocket = false;
neonConfig.pipelineTLS = false;
neonConfig.pipelineConnect = false;

type Primitive = string | number | boolean | undefined | null;

const client = await db.connect();

export function sql<O extends QueryResultRow>(
  strings: TemplateStringsArray,
  ...values: Primitive[]
): Promise<QueryResult<O>> {
  return client.sql(strings, ...values);
}
  1. Make sure the same version of @neondatabase/serverless will be used across all packages. Add to package.json:
"overrides": {
  "@neondatabase/serverless": "0.10.4"
}
  1. Remove node_modules and pnpm-lock.json - and re-run pnpm install
  2. Replace imports from @vercel/postgres with @/app/lib/db in both route.ts.
  3. Load our sql implementation in app/lib/data.ts:
// import { sql } from '@vercel/postgres'; 
import { sql } from '@/app/lib/db';

More notes

  • Follow the discussion regarding this solution here: next-learn/issues/829
  • Also make sure you are using next:canary instead of next.latest in your package.json. Otherwise the experimental Partial Prerendering in Chapter 10 of the tutorial will not work.