Skip to main content

Local Development

This guide helps you quickly set up a local Elftia development environment and start coding.

Prerequisites

Node.js

The project requires Node.js v24 (see .nvmrc in the project root). We recommend using nvm or fnm to manage versions:

nvm install
nvm use

Native Build Tools

The project depends on native Node.js modules such as better-sqlite3, which require a C/C++ compilation environment:

PlatformRequired ToolsInstallation
WindowsVisual Studio Build Tools 2022npm install -g windows-build-tools or install from the VS website
macOSXcode Command Line Toolsxcode-select --install
Linuxbuild-essential, python3sudo apt install build-essential python3 (Debian/Ubuntu)

Other Dependencies

  • Git >= 2.30
  • ripgrep (rg) — automatically downloaded by the postinstall script, or install manually

Project Initialization

# 1. Clone the repository
git clone <repo-url> elftia
cd elftia

# 2. Install dependencies
npm install

The postinstall script run by npm install will automatically:

  • Recompile native modules (better-sqlite3, node-pty, etc.) to match the current Electron version
  • Download the platform-specific ripgrep binary
# 3. Create the environment variable file
cp .env.example .env

Edit .env as needed to fill in API keys and other configuration.


Starting Development Mode

npm run dev

This starts electron-vite dev, watching for code changes across three targets simultaneously:

TargetDirectoryHot Reload
Main Processpackages/desktop/app/main/Restarts main process
Preload Scriptpackages/desktop/app/preload/Restarts main process
Rendererpackages/renderer/src/Vite HMR (port 5375)
tip

If you encounter native module errors on first startup, try running npm run rebuild to recompile them.


All Development Commands

CommandDescription
npm run devStart Electron + Vite dev mode (main + preload + renderer)
npm run dev:webStart Renderer only (web mode, no Electron)
npm run dev:serverStart Fastify web server (optional)
npm run buildBuild all packages (renderer + desktop)
npm run build:rendererBuild frontend only (Vite production mode)
npm run build:desktopBuild Electron main process only (tsup)
npm run build:officialBuild official release (with signing)
npm run build:steamBuild Steam version
npm run lintRun ESLint + TypeScript type checking
npm run lint:eslintRun ESLint only
npm run typecheckRun TypeScript compilation check only
npm run testRun Vitest tests
npm run formatPrettier format all code
npm run format:file <path>Prettier format a single file
npm run verify:buildVerify build artifact size (4 key metrics)
npm run analyze:buildAnalyze bundle composition (chunk statistics)

Debugging

Main Process Debugging

Method 1: --inspect Flag

# Add --inspect to the dev script in package.json
# Or run directly:
electron --inspect=9229 .

Then open chrome://inspect in Chrome and connect to the main process.

Method 2: VS Code

Add the following configuration to .vscode/launch.json:

{
"type": "node",
"request": "attach",
"name": "Attach to Main Process",
"port": 9229,
"skipFiles": ["<node_internals>/**"]
}

Renderer Process Debugging

Press Ctrl+Shift+I (Windows/Linux) or Cmd+Option+I (macOS) to open DevTools.

DevTools supports:

  • React DevTools — auto-loaded after installing the corresponding browser extension
  • Network — monitor IPC calls (they appear as invoke requests)
  • Performance — analyze rendering performance

Logging

Elftia uses Winston for log management.

Environment VariableDescriptionDefault
LOG_LEVELLog level (debug / info / warn / error)info

Log file locations:

PlatformPath
Windows%APPDATA%/elftia/logs/
macOS~/Library/Application Support/elftia/logs/
Linux~/.config/elftia/logs/

Development vs. Production Differences

AspectDevelopment ModeProduction Mode
Frontend servingVite Dev Server (HMR)Static files (file://)
Source mapsEnabledDisabled
MinificationNoneTerser (removes console.log)
Code splittingFull loadReact.lazy per route
CSPRelaxedStrict
DevToolsOpens automaticallyHidden by default (can be enabled in developer mode)
DatabaseDevelopment user data directoryProduction user data directory
Log leveldebuginfo

Worker Threads

Elftia spawns multiple Worker threads in the main process to avoid blocking IPC:

WorkerFileResponsibility
db.workerworkers/db/SQLite read/write operations
fileSearch.workerworkers/fileSearch/File content search (ripgrep)
fileWatcher.workerworkers/fileWatcher/File system change monitoring
mcp.workerworkers/mcp/MCP server communication
diagnostics.workerworkers/diagnostics/System diagnostics collection
project.workerworkers/project/Project directory indexing

In development mode, workers run TypeScript source directly via ts-node; in production mode, workers are compiled into standalone JS files by tsup.


Common Issues

Native Module Compilation Failure

# Clean and reinstall
rm -rf node_modules
npm install

# Or recompile native modules only
npm run rebuild

Port Already in Use

The Vite Dev Server uses port 5375 by default. If it is in use:

# Find the process using the port
lsof -i :5375 # macOS/Linux
netstat -ano | findstr :5375 # Windows

Database Locked

If you see a "database is locked" error, make sure there is no more than one Elftia instance running. In development you can export the database state using the diagnostics API:

window.api.diagnostics.dump()