# How to Set Up the Local Development Environment for OpenSEO

> Quickly set up your local development environment for OpenSEO. Follow our guide to install Nodejs, pnpm, dependencies, D1 database, configure env, and launch the server. Start building with OpenSEO today.

- Repository: [Every App/open-seo](https://github.com/every-app/open-seo)
- Tags: getting-started
- Published: 2026-08-07

---

**To set up the local development environment for OpenSEO, install Node.js 20+, enable Corepack to use pnpm 10.30.1, install dependencies with `pnpm install --frozen-lockfile`, bootstrap the D1 database with `pnpm run db:migrate:local`, configure your `.env.local` file with DataForSEO credentials, and start the server with `pnpm dev:agents`.**

OpenSEO is a modern, full-stack SEO application built with TypeScript, Vite, and Cloudflare Workers. Its architecture separates the React frontend (managed by TanStack Router) from backend logic that executes in a Workers environment, accessing data via **D1 (SQLite)** by default with an optional **Postgres** backend. This guide covers the exact steps documented in [`docs/LOCAL_DEVELOPMENT.md`](https://github.com/every-app/open-seo/blob/main/docs/LOCAL_DEVELOPMENT.md) to configure your local machine for development.

## Prerequisites

Before cloning the repository, ensure your system meets the baseline requirements defined in the every-app/open-seo source code.

- **Node.js 20 or higher** – Required for modern JavaScript features and Corepack support.
- **Corepack** – Bundled with Node.js 24+ but available in Node 20+; used to enforce the exact package manager version.
- **DataForSEO API key** – A base64-encoded string of your `login:password` credentials required for SEO data retrieval.

## Install Dependencies and Bootstrap the Database

OpenSEO uses **pnpm 10.30.1** strictly. The [`package.json`](https://github.com/every-app/open-seo/blob/main/package.json) explicitly declares this version to ensure lockfile integrity across environments.

Enable Corepack and install dependencies:

```bash
corepack enable
pnpm install --frozen-lockfile

```

After installation, initialize the local D1 database. This step applies migrations via Wrangler and only needs to run once per fresh clone:

```bash
pnpm run db:migrate:local

```

This command executes `wrangler d1 migrations` against your local SQLite instance, creating the schema defined in `src/db/`.

## Configure Environment Variables

Copy the example environment file and customize it for trusted local development:

```bash
cp .env.example .env.local

```

Edit `.env.local` to include two critical variables:

1. **DATAFORSEO_API_KEY** – Generate this by base64-encoding your DataForSEO credentials:
   ```bash
   export DATAFORSEO_API_KEY=$(printf '%s' 'login:password' | base64)
   echo "DATAFORSEO_API_KEY=$DATAFORSEO_API_KEY" >> .env.local
   ```

2. **AUTH_MODE** – Set to `local_noauth` to bypass authentication in local development:
   ```bash
   echo "AUTH_MODE=local_noauth" >> .env.local
   ```

The `wrangler.jsonc` file references these variables when binding the Cloudflare Workers environment.

## Start the Development Server

You have two options for running the local server, both defined in [`package.json`](https://github.com/every-app/open-seo/blob/main/package.json):

- **`pnpm run dev`** – Starts a plain Vite development server.
- **`pnpm dev:agents`** – **Recommended.** Runs Vite through **portless**, which exposes the application at `http://open-seo.localhost:1355` and captures structured logs to `.logs/dev-server.log` for debugging.

Use the portless method for the full local experience:

```bash
mkdir -p .logs && touch .logs/dev-server.log
pnpm dev:agents

```

The application will be available at `http://open-seo.localhost:1355` with hot module replacement enabled.

## Optional: Configure the Postgres Backend

While D1 is the default for local development, you can test against Postgres by following [`docs/LOCAL_POSTGRES.md`](https://github.com/every-app/open-seo/blob/main/docs/LOCAL_POSTGRES.md).

Start a Docker container on port 5433:

```bash
docker run --name openseo-postgres -e POSTGRES_USER=openseo \
  -e POSTGRES_PASSWORD=openseo -e POSTGRES_DB=openseo \
  -p 5433:5432 -d postgres:16

```

Apply the schema migrations:

```bash
POSTGRES_DATABASE_URL=postgres://openseo:openseo@localhost:5433/openseo \
  pnpm db:migrate:pg

```

Finally, switch the application to use Postgres:

```bash
echo "DATABASE_PROVIDER=postgres" >> .env.local
pnpm dev

```

## Summary

- **Install Node.js 20+** and enable Corepack to manage the exact pnpm version (10.30.1) declared in [`package.json`](https://github.com/every-app/open-seo/blob/main/package.json).
- **Initialize the database** once per clone using `pnpm run db:migrate:local` for D1, or configure Docker Postgres and run `pnpm db:migrate:pg` for the alternative backend.
- **Configure `.env.local`** with `DATAFORSEO_API_KEY` (base64-encoded) and `AUTH_MODE=local_noauth` to enable local operation.
- **Start the server** with `pnpm dev:agents` for portless local domain support and logging, or use `pnpm run dev` for standard Vite.
- **Reference [`docs/LOCAL_DEVELOPMENT.md`](https://github.com/every-app/open-seo/blob/main/docs/LOCAL_DEVELOPMENT.md)** and [`docs/LOCAL_POSTGRES.md`](https://github.com/every-app/open-seo/blob/main/docs/LOCAL_POSTGRES.md) for troubleshooting and advanced configuration.

## Frequently Asked Questions

### What Node.js version is required to run OpenSEO locally?

OpenSEO requires **Node.js 20 or higher**. This version ensures compatibility with Corepack, which manages the strict pnpm 10.30.1 dependency, and supports the modern TypeScript features used throughout the codebase.

### Why must I use pnpm 10.30.1 specifically?

The [`package.json`](https://github.com/every-app/open-seo/blob/main/package.json) in the every-app/open-seo repository explicitly pins `pnpm@10.30.1` to guarantee deterministic dependency resolution. Using a different version may corrupt the lockfile or introduce incompatible package behavior. Corepack enforces this version automatically when enabled.

### What is the difference between `pnpm dev` and `pnpm dev:agents`?

**`pnpm run dev`** starts a standard Vite development server on a local port. **`pnpm dev:agents`** runs Vite through the **portless** tool, which binds the application to `http://open-seo.localhost:1355` and pipes logs to `.logs/dev-server.log`. The portless method is recommended for local development as it mimics production routing patterns and provides better debugging output.

### Can I switch from D1 to Postgres after initial setup?

Yes. You can migrate from the default D1 (SQLite) backend to Postgres at any time by starting a Postgres container (exposed on port 5433), running `pnpm db:migrate:pg` to apply schema migrations, and setting `DATABASE_PROVIDER=postgres` in your `.env.local` file. The `src/db/` layer supports both dialects, though you cannot run both simultaneously in the same instance.