> ## Documentation Index
> Fetch the complete documentation index at: https://helix-isolate-failing-index-entities.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Local development

> Run a local instance and iterate on dynamic JSON queries

<div className="flex flex-wrap gap-2"><Badge color="blue" size="sm">Guide</Badge></div>

Local development runs the prebuilt `ghcr.io/helixdb/helixdb:v0.0.9` container and exposes the standalone server at `POST /v2/query`. By default, storage is in-memory. Use `--disk` when you want persistent local data backed by a CLI-managed SeaweedFS volume.

## Prerequisites

* **Docker** or **Podman** on `PATH`.
* The Helix CLI:
  * macOS and Linux: `curl -sSL "https://install.helix-db.com" | bash`.
  * Windows PowerShell: `irm https://raw.githubusercontent.com/HelixDB/helix-db/main/crates/cli/install.ps1 | iex`.

## Initial setup

For an agent-assisted first app, [`helix chef`](/cli/command-reference/chef) can run this setup end-to-end: it installs Helix skills and the docs MCP, initializes `~/my-first-helix-project`, starts `dev`, seeds starter data, and launches your coding agent to build the app.

```bash theme={null}
helix chef
```

Use the manual flow below when you want to scaffold and run each step yourself.

<Steps>
  <Step title="Scaffold a project">
    ```bash theme={null}
    mkdir my-helix-app
    cd my-helix-app
    helix init local
    ```

    `helix init local` creates `helix.toml`, `.helix/`, `AGENTS.md`,
    `examples/request.json`, and `.gitignore` entries for local state. Bare
    `helix init` asks whether to set up a local or Cloud project.
  </Step>

  <Step title="Start the local runtime">
    ```bash theme={null}
    helix start dev
    ```

    Starts a background container named `helix-my-helix-app-dev` on port `6969`. The CLI waits for `GET /healthz` to report ready before returning.

    For attached log streaming use `helix start dev --foreground` and stop with Ctrl-C.

    For persistent local storage use `helix start dev --disk`, or initialize the project with `helix init local --disk` to make disk mode the default for that instance.
  </Step>

  <Step title="Send the example query">
    ```bash theme={null}
    helix query dev --file examples/request.json
    ```

    The example counts `User` nodes. Try `--json` to print compact JSON only, or
    `--warm` to populate the standalone process caches while returning the normal
    response.
  </Step>
</Steps>

<Warning>
  Default local storage is in-memory. `helix stop` or `helix restart` wipes in-memory data — keep your seed data in JSON request files so you can replay it, or use `--disk` for persistent local storage.
</Warning>

## Persistent local storage

```bash theme={null}
# One-off disk mode for this run
helix start dev --disk

# Persist disk mode in helix.toml for a new local instance
helix add local --name persistent --disk
helix start persistent
```

Disk mode starts a SeaweedFS S3 sidecar, creates the `helix-db` bucket, and stores data in a Helix-managed Docker/Podman volume named `helix-<project>-<instance>-seaweedfs-data`. `helix stop` removes the containers but keeps the volume. `helix prune <instance>` removes the volume and deletes the persisted local data.

Disk mode and S3 storage also get a `helix-<project>-<instance>-cache` volume for the server's disk cache, with a 64 MiB budget in disk mode and 1 GiB for an S3 bucket. `helix stop` keeps it and `helix prune <instance>` removes it.

## Migrate MinIO disk data

Earlier CLI releases ran disk mode on MinIO. MinIO has withdrawn its community container images, so disk mode now uses SeaweedFS, which cannot read MinIO's on-disk format. When the old `helix-<project>-<instance>-minio-data` volume exists, `helix start` removes the old MinIO sidecar, leaves that volume untouched, starts the instance on a new SeaweedFS volume, and prints a warning. `helix stop` keeps both volumes. `helix prune <instance>` deletes both, including anything written to the new volume since the upgrade.

Copying the old data needs a MinIO server image that is still cached on your machine. Earlier CLI releases pulled `quay.io/minio/minio@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e`; `docker image ls --digests quay.io/minio/minio` shows whether it is still cached. Copy the objects into the new volume before Helix writes there. If you already started the instance with the new CLI, the new volume holds a database that began empty at the upgrade. The `docker volume rm` line below deletes it along with anything written to it since then, so export that data first if you need it. Use `podman` in place of `docker` if your project uses Podman.

```bash theme={null}
helix stop dev
base=helix-my-app-dev  # the Container value printed by `helix start dev`
minio_image=quay.io/minio/minio@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e
seaweedfs_image=ghcr.io/chrislusf/seaweedfs:4.47@sha256:ce9e796f1fe6f06968f4c04bdaf8f678dad9c8acdfef3d244133d71bfa6bf882
aws_cli=public.ecr.aws/aws-cli/aws-cli:2.37.4@sha256:fdd8d1fcbea9c371678dee5a40df8b178c7a781b4586605756ee28114c97ead6

docker volume rm "$base-seaweedfs-data"  # only if the new CLI started it; deletes post-upgrade writes
docker network create helix-migrate
docker run -d --name helix-migrate-minio --network helix-migrate \
  -e MINIO_ROOT_USER=minioadmin -e MINIO_ROOT_PASSWORD=minioadmin \
  -v "$base-minio-data:/data" "$minio_image" server /data
docker run -d --name helix-migrate-seaweedfs --network helix-migrate \
  -e AWS_ACCESS_KEY_ID=helix -e AWS_SECRET_ACCESS_KEY=helix-local-secret \
  -v "$base-seaweedfs-data:/data" "$seaweedfs_image" \
  mini -dir=/data -bucket=helix-db -master.telemetry=false
sleep 10

docker run --rm --network helix-migrate -v helix-migrate-export:/export \
  -e AWS_ACCESS_KEY_ID=minioadmin -e AWS_SECRET_ACCESS_KEY=minioadmin \
  -e AWS_DEFAULT_REGION=us-east-1 "$aws_cli" \
  --endpoint-url http://helix-migrate-minio:9000 s3 sync s3://helix-db /export
docker run --rm --network helix-migrate -v helix-migrate-export:/export \
  -e AWS_ACCESS_KEY_ID=helix -e AWS_SECRET_ACCESS_KEY=helix-local-secret \
  -e AWS_DEFAULT_REGION=us-east-1 "$aws_cli" \
  --endpoint-url http://helix-migrate-seaweedfs:8333 s3 sync /export s3://helix-db

docker rm -f helix-migrate-minio helix-migrate-seaweedfs
docker network rm helix-migrate
docker volume rm helix-migrate-export
helix start dev
```

After checking the data, run `docker volume rm "$base-minio-data"` to delete the old volume and stop the warning. Do not use `helix prune` for this step: it deletes the new volume too.

## Iteration loop

```bash theme={null}
# Edit a request file (or write a new one)
$EDITOR examples/request.json

# Send the request
helix query dev --file examples/request.json

# Tail container logs in another shell
helix logs dev --follow

# Stop and restart from a clean state
helix restart dev
```

`helix restart` fails if the container has been removed; run `helix start` to create it again.

## Multiple local instances

```bash theme={null}
# Add a second local instance on a different port
helix add local --name staging --port 9090

# Run them independently
helix start dev
helix start staging

# See what's running
helix status
```

Each instance is isolated by container name and host port. Disk-mode instances also get their own SeaweedFS container, network, and volume, and disk-mode and S3 instances their own disk-cache volume.

## Inspecting logs

```bash theme={null}
helix logs dev               # one-shot dump from docker/podman logs
helix logs dev --follow      # stream
```

`--start`, `--end`, and `--json` are Helix Cloud-only and rejected for local instances.

## Cleaning up

| Goal | Command |
| - | - |
| Stop one instance | `helix stop <instance>` |
| Restart one instance | `helix restart <instance>` |
| Remove containers, workspace state, and Helix-managed volumes for one instance | `helix prune <instance>` |
| Remove everything Helix-owned, for every local instance | `helix prune --all` (`--yes` in non-TTY) |
| Permanently delete an instance from `helix.toml` | `helix delete <instance>` (`--yes` in non-TTY) |

[`helix prune`](/cli/command-reference/prune) only touches Helix-managed containers (`helix-<project>-<instance>`, disk-mode SeaweedFS sidecars, and MinIO sidecars left by older releases), networks, volumes, and the per-instance `.helix/<instance>` directory. It never runs a broad `docker/podman system prune`.

## Authoring dynamic queries

A request JSON file must contain:

* `request_type`: lowercase `"read"` or `"write"`.
* `query_name` (optional): top-level operational name for logs and query diagnostics. Missing or
  `null` falls back to `__dynamic__`.
* `query`: exactly one `read` or `write` batch with `entries[]` and `returns[]`.
* `parameters` and `parameter_types` (optional): named values and their declared types.

Each entry contains one nested operation-tree `root`; source operations appear at the
innermost input. See [`helix query`](/cli/command-reference/query) for the request shape.

## Next steps

<CardGroup cols={2}>
  <Card title="Helix Cloud workflow" icon="cloud" href="/cli/workflows/helix_cloud">
    Authenticate, link a project, and query a remote cluster
  </Card>

  <Card title="CLI Command Reference" icon="terminal" href="/cli/command-reference">
    Every command, subcommand, and flag
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.