Local Development

Prerequisites

  • Bun (workspace manager)
  • Node (LTS)
  • Supabase CLI (for local DB)

Setup

bun install
cp .env.example .env.local

Services

  • Web apps via Turbo
  • Workers run independently per package
  • Storybook for UI component documentation

Shared UI (@eko/ui)

The @eko/ui package contains shared React components consumed by web and admin apps.

Adding new components:

cd packages/ui
bunx shadcn@latest add <component-name>

After adding, update imports from @/lib/utils to ../lib/utils and add 'use client' directive.

Tailwind CSS v4 integration: Apps must include the @source directive in their globals.css:

@import "tailwindcss";
@source "../../packages/ui/src";

Required Environment Variables

After copying .env.example, ensure these AI provider keys are configured:

VariableRequiredPurpose
OPENAI_API_KEYYesDefault tier for fact extraction
ANTHROPIC_API_KEYRecommendedMid/high tier for accuracy-critical tasks
GOOGLE_API_KEYYesGemini 2.5 Flash powers the validation pipeline (Phases 3 and 4c)

Note: The validation pipeline requires GOOGLE_API_KEY for cross-model verification and evidence corroboration via Gemini 2.5 Flash.

Queues

Local development uses either local Redis or Upstash dev credentials. Configure via environment variables.

Workers

Workers execute independently via Bun (worker-ingest, worker-facts, worker-validate).

Commands

  • bun run dev — parallel dev (web, admin)
  • bun run test — workspace tests
  • bun run check — format + lint
  • bun storybook — run Storybook at http://localhost:6006
  • bun run build-storybook — build static Storybook

Environment Validation

After adding or changing environment variables:

bun run env:check-example  # Validate .env.example completeness
bun run env:check-local    # Validate .env.local against .env.example
bun run env:check-typos    # Check for common env file typos (.evn, etc.)

These checks run automatically in CI via the pre-push hook.

Pre-commit Hooks

The repo uses Husky for Git hooks and lint-staged for running linters on staged files.

What runs on commit:

  1. Secret scanning (gitleaks) - Blocks commits containing potential secrets
  2. Lint-staged - Runs Biome on staged .ts, .tsx, .js, .jsx, .json, .md files

Installing gitleaks

Secret scanning requires gitleaks to be installed locally:

# macOS
brew install gitleaks

# Linux (via go)
go install github.com/gitleaks/gitleaks/v8@latest

# Or download from releases
# https://github.com/gitleaks/gitleaks/releases

If gitleaks is not installed, the hook will warn but continue (allowing commits without secret scanning).

Handling False Positives

If gitleaks flags a false positive:

  1. Add the pattern to .gitleaks.toml allowlist
  2. Or add gitleaks:allow comment on the line

Bypassing Hooks (Emergency Only)

git commit --no-verify -m "message"

Use sparingly - secrets in git history are permanent and expensive to remediate.

Local DB

supabase start
supabase db reset

Troubleshooting

  • Stale diffs → clear render cache
  • Type errors → ensure workspace tsconfig sync
  • Storybook build fails with "Yallist is not a constructor" → The root package.json has an lru-cache override to fix Babel compatibility. Run rm -rf node_modules bun.lock && bun install if the issue persists.

Dependency Management

All dependencies use explicit semver ranges (e.g., ^1.2.3) rather than latest. This ensures:

  • Reproducible builds across environments
  • Predictable CI behavior
  • Easier security auditing

When adding dependencies, always specify a version range. The lockfile (bun.lock) pins exact versions.


Architecture source of truth: /STACK.md