Local Development
Running Vega locally means starting a FastAPI backend, a React frontend, and optionally a scan worker process — all on your machine. The default configuration stores all data in JSON files under data/, so you don't need a database or AWS account to get started.
Before you begin
You'll need:
- Python 3.12+ for the backend
- Node.js 18+ for the frontend
- Git with submodule support (the scan engine is a submodule)
- Docker if you want local scans to run the Codex container
Clone the repo and initialize the scan engine submodule:
git clone <repo-url>
cd vega-backend
git submodule update --init --recursive
Submodule required
The v16/ directory is a git submodule. If you skip git submodule update, the backend will fail to import v16.adapter and scans will not work.
Step 1 — Start the backend
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
uvicorn app.main:app --reload --reload-dir app
The API starts on http://localhost:8000. All routes are under /v1, so the health endpoint is at http://localhost:8000/v1/healthz.
--reload --reload-dir app watches the app/ directory and automatically restarts the server when you change Python files.
Step 2 — Start the frontend
In a second terminal:
cd frontend
npm install
npm run dev
The Vite dev server starts on http://localhost:5173. It automatically proxies /v1/* requests to the backend on port 8000, so the frontend and backend talk to each other without any extra configuration.
Step 3 — Log in
Open http://localhost:5173 in a browser. The default dev credentials are:
| Field | Value |
|---|---|
debug@example.com |
|
| Password | vega-debug-password |
To test login from the command line:
curl -s http://localhost:8000/v1/auth/login \
-H 'content-type: application/json' \
-d '{"email":"debug@example.com","password":"vega-debug-password"}'
The response includes an access_token you can use in subsequent requests with -H "Authorization: Bearer <token>".
Debug auth is local-only
These credentials only work when VEGA_AUTH_PROVIDER=custom (the default). In AWS, Cognito handles authentication and these credentials are disabled.
Step 4 (optional) — Run the scan worker
By default, VEGA_SCAN_EXECUTION_MODE=thread, which means the API process runs scans directly inside the request. This is the simplest setup.
For a more realistic setup that mirrors production, set VEGA_SCAN_EXECUTION_MODE=external for the API and run the worker in a third terminal:
VEGA_SCAN_EXECUTION_MODE=external uvicorn app.main:app --reload --reload-dir app
# In another terminal
python scripts/run-scan-worker.py
In this mode, the API queues scan jobs and the worker claims and executes them. See Scan Lifecycle for details on what "claiming" means.
Running tests
pytest
For faster feedback while working on a subsystem, run focused tests:
pytest tests/test_projects_flow.py # project and repository workflows
pytest tests/test_v16_adapter.py # scan engine adapter
pytest tests/test_scan_persistence.py # scan state and findings storage
pytest tests/test_hardening.py # quotas and limits
What lives in data/
When running with the default JSON persistence (VEGA_PERSISTENCE_BACKEND=json), all state is stored under data/:
data/
├── users.json
├── projects.json
├── repositories/
├── scans/
├── findings/
├── git/ ← cloned git repos
├── uploads/ ← uploaded zip archives
├── snapshots/ ← extracted source ready for scanning
└── artifacts/ ← scan output files
To start fresh, stop the processes and delete the data/ directory. The backend will recreate it.