# ENSNode Development and Contributions

:::note
This guide covers running ENSNode locally for development and contributions.
:::

### Prerequisites

- [Git](https://git-scm.com/)
- [Postgres 17](https://www.postgresql.org/) with the [`pg_trgm`](https://www.postgresql.org/docs/current/pgtrgm.html) extension available for installation (ships with stock Postgres contrib; ENSIndexer runs `CREATE EXTENSION IF NOT EXISTS pg_trgm` at startup to back partial-name search indexes)
- [Node.js](https://nodejs.org/)
  - It's recommended you install Node.js through [nvm](https://github.com/nvm-sh/nvm) or [asdf](https://asdf-vm.com/).
  - see `.nvmrc` and `.tool-versions` for the specific version of Node.js
- [pnpm](https://pnpm.io/)
  - Run `npm install -g pnpm` or see [other installation options](https://pnpm.io/installation).

### Prepare Workspace

Clone this repository:

```bash
git clone git@github.com:namehash/ensnode.git
cd ensnode
```

### Install Dependencies

```bash
pnpm install
```

## Running ENSNode

:::note
ENSNode is a suite of services, and some depend on others. Refer to the `docker/docker-compose.yml` in the docker directory for a full spec on the relationship between services.

[View docker-compose.yml on GitHub](https://github.com/namehash/ensnode/blob/main/docker/docker-compose.yml)
:::

### 1. Running ENSDb

Ensure ENSDb is running in the background, providing its connection details to ENSIndexer via `ENSDB_URL`.

### 2. Running ENSRainbow

```bash
# from monorepo root
pnpm run -F @ensnode/ensrainbow serve

# or from apps/ensrainbow
pnpm run serve
```

### 3. Running ENSIndexer

:::caution
ENSIndexer's `.env.local` should be placed at `apps/ensindexer/.env.local`, _not_ at the monorepo root.
:::

:::note[Running ENSIndexer in Development]
Follow instructions in the [ENSIndexer Contribution Guide](/docs/services/ensindexer/contributing) to set up your local environment.
:::

```bash
# from monorepo root
pnpm run -F ensindexer dev

# or from apps/ensindexer
pnpm run dev
```

### 4. Running ENSApi

:::caution
ENSApi's `.env.local` should be placed at `apps/ensapi/.env.local`, _not_ at the monorepo root.
:::

```bash
# from monorepo root
pnpm run -F ensapi dev

# or from apps/ensapi
pnpm run dev
```

### 5. Running ENSAdmin

:::caution
ENSAdmins's `.env.local` should be placed at `apps/ensadmin/.env.local`, _not_ at the monorepo root.
:::

```bash
cd apps/ensadmin
cp .env.local.example .env.local
```

```bash
# from monorepo root
pnpm run -F ensadmin dev

# or from apps/ensadmin
pnpm run dev
```

## Using Docker Compose

You can use Docker Compose to set up the ENSNode suite, along with its dependencies.

:::note[Docker in Development]
Re-building Docker containers is slow and inefficient, and doesn't lend itself to rapid development. The first half of this guide showed how to run ENSNode on your host machine, for faster iteration and maximum control. The Docker Compose spec is helpful for describing the suite of services and running them in a structured way, which we'll discuss below.
:::

### Prerequisites

Before you can use Docker Compose, ensure you have the following installed on your machine:

- [Docker](https://www.docker.com/get-started)
- [Docker Compose](https://docs.docker.com/compose/install/)

### Building the Docker Images

Before running `docker compose` the images must be built with the latest changes: see the [Building Docker Images](/docs/reference/contributing/building) guide.

If you make changes in the application code and wish to run those updates, you must build the relevant Docker container again.

### Running the Applications

For local development, use the devnet stack — no environment setup required:

```bash
docker compose -f docker/docker-compose.devnet.yml up -d
```

For mainnet/sepolia, first configure your environment:

```bash
cp docker/envs/.env.docker.example docker/envs/.env.docker.local
```

Edit `docker/envs/.env.docker.local` to set `NAMESPACE`, `PLUGINS`, and your RPC endpoints, then run:

```bash
docker compose -f docker/docker-compose.yml up -d
```

- **ENSIndexer**: Available at [http://localhost:42069](http://localhost:42069)
- **ENSApi**: Available at [http://localhost:4334](http://localhost:4334)
- **ENSRainbow**: Available at [http://localhost:3223](http://localhost:3223)
- **ENSAdmin**: Available at [http://localhost:4173](http://localhost:4173)
- **PostgreSQL**: Available on port `5432`

For all available commands and configuration options, see the [Deploying with Docker](/docs/self-host/docker) guide and [`docker/README.md`](https://github.com/namehash/ensnode/blob/main/docker/README.md).

### Stopping the Applications

To stop the running applications, you can press `Ctrl + C` in the terminal where Docker Compose is running. To remove the containers and networks:

```bash
docker compose -f docker/docker-compose.yml down
```

:::caution[Postgres Volume]
`docker compose down` will _not_ delete the Postgres data volume, as it is a **named** volume. To fully delete it and start from scratch, use `docker compose -f docker/docker-compose.yml down -v`.
:::