# How to Set Up Open‑SEO Locally: Complete Installation Guide

> Easily set up Open-SEO locally. Clone the repo, install dependencies, configure auth, run migrations, and start the dev server with pnpm dev:agents. Your complete installation guide.

- Repository: [Every App/open-seo](https://github.com/every-app/open-seo)
- Tags: how-to-guide
- Published: 2026-08-02

---

**Set up Open‑SEO locally by cloning the repository, installing dependencies with Corepack/pnpm, configuring environment variables with `AUTH_MODE=local_noauth`, running database migrations, and starting the dev server with `pnpm dev:agents`.**

Open‑SEO is a full‑stack, server‑first SEO analytics application built with **TanStack Server Functions**, **SQLite (D1)** or optional **PostgreSQL**, and a **Vite**‑powered React frontend. This guide walks you through every step to get Open‑SEO running on your machine, whether you prefer native Node.js, Docker, or Cloudflare Workers deployment.

## Prerequisites

Before you begin, ensure you have:

- **Node.js 20+** with **Corepack** enabled (bundled with recent Node versions)
- A **DataForSEO API key** (base‑64‑encoded `login:password` string)
- Git for cloning the repository

You can obtain DataForSEO credentials from [DataForSEO's website](https://dataforseo.com/).

## Step 1: Clone and Install Dependencies

Open‑SEO uses **pnpm** as its package manager, pinned to a specific version in [`package.json`](https://github.com/every-app/open-seo/blob/main/package.json). Corepack automatically handles this version.

```bash
git clone https://github.com/every-app/open-seo.git
cd open-seo
corepack enable
pnpm install --frozen-lockfile

```

The `--frozen-lockfile` flag ensures exact dependency versions from [`pnpm-lock.yaml`](https://github.com/every-app/open-seo/blob/main/pnpm-lock.yaml) are installed, matching the project's tested configuration.

## Step 2: Configure Environment Variables

Copy the example environment file and create `.env.local`:

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

```

### Encode Your DataForSEO Credentials

Open‑SEO requires a base‑64‑encoded string containing your DataForSEO login and password:

```bash
printf '%s' 'YOUR_LOGIN:YOUR_PASSWORD' | base64

```

Paste the output into `.env.local` as `DATAFORSEO_API_KEY`:

```bash

# .env.local

DATAFORSEO_API_KEY=your_base64_encoded_string_here

```

### Set Authentication Mode

For local development, use `local_noauth` mode. This skips JWT validation and injects the admin user `admin@localhost` automatically:

```bash
echo "AUTH_MODE=local_noauth" >> .env.local

```

Other authentication modes available in the codebase include:

- **`cloudflare_access`** – Validates Cloudflare Access JWTs (production default)
- **`hosted`** – Better Auth email/password flow (requires additional secrets)

These modes are implemented in [`src/server/auth.ts`](https://github.com/every-app/open-seo/blob/main/src/server/auth.ts) and control how trust boundaries are enforced.

## Step 3: Initialize the Database

Run migrations once to create the SQLite schema:

```bash
pnpm run db:migrate:local

```

This executes the migration files located in the server directory and prepares your local D1‑compatible database for first use.

## Step 4: Start the Development Server

Open‑SEO supports two dev server commands in [`package.json`](https://github.com/every-app/open-seo/blob/main/package.json):

| Command | Behavior | Best For |
|---------|----------|----------|
| `pnpm run dev` | Plain Vite preview | Quick checks |
| `pnpm dev:agents` | Vite with fixed log file (`.logs/dev-server.log`) | Debugging and development |

The recommended approach creates the log directory first:

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

```

The application serves through **Portless**, providing a stable hostname at `http://open-seo.localhost:1355` without port conflicts.

## Alternative: Docker Setup

For containerized development, Open‑SEO includes a Docker Compose configuration that automatically sets `AUTH_MODE=local_noauth`:

```bash
cp .env.example .env

# Edit .env to add your base64-encoded DATAFORSEO_API_KEY

docker compose up -d

```

Access the containerized app at `http://localhost:3001` (or your configured `PORT`).

## Alternative: Cloudflare Workers Deployment

To deploy on Cloudflare's edge infrastructure instead of running locally:

```bash
pnpm alchemy login --configure    # Ensure access:write scope

pnpm alchemy cloudflare bootstrap
cp .env.selfhost.example .env.selfhost   # Fill required fields

pnpm deploy:selfhost --yes

```

This boots Open‑SEO as a Cloudflare Workers service with Cloudflare Access integration. See [`web/content/docs/self-hosting/cloudflare.md`](https://github.com/every-app/open-seo/blob/main/web/content/docs/self-hosting/cloudflare.md) for full configuration options.

## Key Files and Their Roles

Understanding the project structure helps when extending or debugging:

- **[`package.json`](https://github.com/every-app/open-seo/blob/main/package.json)** – Defines pnpm version, scripts (`dev`, `dev:agents`, `db:migrate:local`), and core dependencies including TanStack and Zod
- **`src/server/`** – Contains TanStack Server Functions, database clients, and authentication logic with Zod validation at trust boundaries
- **`src/web/`** – React + Vite frontend that communicates with server functions
- **`.env.example`** – Reference for all required environment variables
- **[`docs/LOCAL_DEVELOPMENT.md`](https://github.com/every-app/open-seo/blob/main/docs/LOCAL_DEVELOPMENT.md)** – Official step‑by‑step local setup documentation

## Summary

- **Open‑SEO** requires Node.js 20+, Corepack, and a DataForSEO API key for local setup
- Use **`AUTH_MODE=local_noauth`** in `.env.local` to skip authentication during development
- Run **`pnpm run db:migrate:local`** once before first startup
- Start with **`pnpm dev:agents`** for the best debugging experience with structured logging
- Docker and Cloudflare Workers alternatives are available for container or edge deployment

## Frequently Asked Questions

### What is the default database for Open‑SEO?

Open‑SEO uses **SQLite (D1)** by default for local development, with optional **PostgreSQL** support for production deployments. The database client code resides in `src/server/` and migrations run via the `db:migrate:local` script.

### Why does my DataForSEO key need to be base64‑encoded?

The `DATAFORSEO_API_KEY` environment variable expects a base‑64‑encoded string containing `login:password` because the DataForSEO API uses HTTP Basic Authentication. This encoding keeps credentials in a single transport‑safe string that the server decodes when making external API requests.

### Can I run Open‑SEO without any authentication at all?

Yes, set **`AUTH_MODE=local_noauth`** in your environment file. This mode bypasses all JWT validation and automatically injects `admin@localhost` as the authenticated user. Never use this mode in production—it exists solely for streamlined local development.

### What is Portless and why use port 1355?

**Portless** provides stable, branch‑scoped hostnames for local development without requiring static port assignments. Open‑SEO defaults to `http://open-seo.localhost:1355`, but this hostname remains consistent even if the underlying port changes, eliminating conflicts with other local services.