# Development Setup (/docs/developer-guide/development-setup)

## Prerequisites [#prerequisites]

- **Node.js** 24.x
- **pnpm** 10.x+ (required — npm and yarn are not supported)
- **PostgreSQL** 15+ (or use Docker)
- **Docker** (for running the full stack locally)

## Clone and Install [#clone-and-install]

```bash
git clone https://github.com/elmohq/elmo.git
cd elmo
pnpm install
```

## Configure Environment [#configure-environment]

Copy the example environment file and fill in your values:

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

At minimum, you need:

| Variable | Description |
|----------|-------------|
| `DATABASE_URL` | PostgreSQL connection string |
| `BETTER_AUTH_SECRET` | Any random string for session encryption |
| `ELMO_ENCRYPTION_KEY` | Key for provider credentials stored in the database — `openssl rand -base64 32` |

Add AI provider API keys if you want to test visibility tracking:

| Variable | Description |
|----------|-------------|
| `OPENAI_API_KEY` | For ChatGPT tracking |
| `ANTHROPIC_API_KEY` | For Claude tracking |

## Database Setup [#database-setup]

Run Drizzle migrations to create the schema:

```bash
pnpm --filter @workspace/lib exec drizzle-kit migrate
```

## Mention Judge [#mention-judge]

The worker judges mentions and sentiment with [Jev](/docs/developer-guide/configuration#mention-judging), so it needs `TYPESAFE_API_KEY`, or `OPENROUTER_API_KEY` to call Jev through OpenRouter. For UI work without a key, set it to `stub`: answers get placeholder judgements and nothing is sent anywhere.

## Start Development Servers [#start-development-servers]

Run all development servers in parallel:

```bash
pnpm dev
```

This starts:
- **Web app** at `http://localhost:3000`
- **Worker** process for background jobs

Or run only the web app:

```bash
pnpm --filter @workspace/web dev
```

## Development with Docker [#development-with-docker]

For a setup closer to production, use the CLI in dev mode:

```bash
# Build from local source instead of pulling images
elmo init --dev

# Rebuild after code changes
elmo compose build
elmo compose up -d
```

The Docker build uses a multi-stage `docker/Dockerfile` with separate targets for `web` and `worker`.

## Component Stories [#component-stories]

Beai uses Storybook for component development in isolation:

```bash
pnpm --filter @workspace/web storybook
```

Stories live in `apps/web/src/stories/` and cover the app sidebar, prompt charts, and other components across deployment modes.
