ICYMI we recently launched Neon Local.

What is Neon Local?

Neon Local is a proxy service that creates a local interface to your Neon cloud database. By default, it automatically creates a new database branch when your container starts and deletes it when the container stops. Your app connects to a local Postgres endpoint while Neon Local handles routing and authentication to the correct project and branch. This means you don’t have to update connection strings across branches.

Our docs cover how to use Neon Local with both our serverless driver and pg, but one area that might cause some confusion is how to switch between Neon Local in development and your Neon cloud database in production.

In this guide, I’ll show you how to set up your project to work in both development and production environments.

1. Example application

To demonstrate, I’ve built a simple React + Vite + Express app. It has one route (/) that runs SELECT version() and returns the result.

You can find the project here:

2. Setup

Environment variables

You’ll need to configure the following environment variables. They are also listed in the example application's repository README.

VariableDescriptionExample / Value
DATABASE_URLConnection string for database(Set appropriately)
NODE_ENVNode environment modeproduction or development
NEON_API_KEYNeon API authentication keynapi_6ngd23amjggx7...
NEON_PROJECT_IDNeon project identifierrosty-king-89...
PORTServer port8080

If you need help finding up any of these variables, refer to the following resources:

Docker for Mac

This guide uses Docker for Mac. If you don’t have it installed yet, follow this guide:

Docker for Mac

3. Running the app

If you've cloned the repo, and followed the install instructions, run the app with one of the following commands:

  • development:
    docker compose --profile dev --env-file .env.dev up --watch
  • production:
    docker compose --profile prod --env-file .env.prod up --build

Once the app is running, go to http://localhost:8080/ in your browser.

4. Ephemeral branches

If you started the app in development mode, go to the Neon console, and you’ll see a new branch has been created using the main, or production branch as a base.

If you started the app in production mode, the app will connect to the database defined by the DATABASE_URL, and no new branch will be created.

In the next section, we’ll look at the Docker configuration and how the app determines whether to connect to Neon Local or the cloud instance defined by DATABASE_URL.

5. Configuration

Docker Compose

Here’s the docker-compose.yml setup, which defines two services. The first, app, starts the Express server, responsible for data fetching and server-side rendering of the React app. The second, db, configures the Neon Local Docker image.

Additionally, the app service defines two profiles, dev and prod. The db service also defines a dev profile, ensuring that the db service is only used when the app is run in development mode.

How Docker Profiles Work

Docker profiles allow you to group services within your docker-compose.yml file, enabling you to choose which services to start depending on the environment or use case.

  • The app service has both dev and prod profiles. This means the app can be run in either development or production mode.
  • The db service is only included in the dev profile, meaning it will only run when the app is started in development mode.
services:
  app:
    build: .
    ports:
      - '${PORT}:${PORT}'
    volumes:
      - .:/app
      - /app/node_modules
    environment:
      - PORT=${PORT}
      - NODE_ENV=${NODE_ENV}
      - DATABASE_URL=${DATABASE_URL}
      - NEON_API_KEY=${NEON_API_KEY}
      - NEON_PROJECT_ID=${NEON_PROJECT_ID}
    profiles:
      - dev
      - prod

  db:
    image: neondatabase/neon_local:latest
    ports:
      - '5432:5432'
    environment:
      NEON_API_KEY: ${NEON_API_KEY}
      NEON_PROJECT_ID: ${NEON_PROJECT_ID}
      DRIVER: serverless
    profiles:
      - dev

You can view the src of this file in the repository: docker-compose.yml

6. Connecting to the database

Serverless Driver

The database connection is established using our serverless driver. It uses a ternary operation to determine whether to connect to Neon Local or the DATABASE_URL, depending on the mode the application is running in.

import 'dotenv/config';

import { neon, neonConfig } from '@neondatabase/serverless';

if (process.env.NODE_ENV !== 'prod') {
  neonConfig.fetchEndpoint = 'http://db:5432/sql';
}

const connectionString =
  process.env.NODE_ENV === 'prod' ? process.env.DATABASE_URL : 'postgres://neon:npg@db:5432/neondb';

export const sql = neon(connectionString);

You can view the src of this file in the repository: src/db.js:

node-postgres

Alternatively, if you prefer to use pg, here's how the connection is configured. Note that you'll need to add ?sslmode=no-verify to the end of the Neon Local connection string.

import 'dotenv/config';

import pg from 'pg';
const { Pool } = pg;

const connectionString =
  process.env.NODE_ENV === 'prod'
    ? process.env.DATABASE_URL
    : 'postgres://neon:npg@db:5432/neondb?sslmode=no-verify';

export const pool = new Pool({ connectionString });

Additionally, you'll also need to change the DRIVER to postgres in your docker-compose.yml file:

environment:
  NEON_API_KEY: ${NEON_API_KEY}
  NEON_PROJECT_ID: ${NEON_PROJECT_ID}
  DRIVER: serverless
  DRIVER: postgres

Wrapping up

And that’s it. By default, Neon Local handles creating and deleting a branch whenever you start or stop the container. If you want more control, such as setting a parent branch or disabling branch deletion, check out the configuration options in the docs.

Neon Local simplifies the management of temporary database environments, making it easier to work with isolated instances for testing or short-term use. While it’s not a fully "local" database, it streamlines the workflow, especially for CI/CD pipelines where short-lived environments are needed to run tests but don’t need to stick around.

Neon Local is still in its early stages, with several improvements on the way. But for now, it could be exactly what you need to streamline your workflows. Give it a try today and share your feedback with us.