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:
| Platform | Required Tools | Installation |
|---|---|---|
| Windows | Visual Studio Build Tools 2022 | npm install -g windows-build-tools or install from the VS website |
| macOS | Xcode Command Line Tools | xcode-select --install |
| Linux | build-essential, python3 | sudo apt install build-essential python3 (Debian/Ubuntu) |
Other Dependencies
- Git >= 2.30
- ripgrep (rg) — automatically downloaded by the
postinstallscript, 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
ripgrepbinary
# 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:
| Target | Directory | Hot Reload |
|---|---|---|
| Main Process | packages/desktop/app/main/ | Restarts main process |
| Preload Script | packages/desktop/app/preload/ | Restarts main process |
| Renderer | packages/renderer/src/ | Vite HMR (port 5375) |
If you encounter native module errors on first startup, try running npm run rebuild to recompile them.
All Development Commands
| Command | Description |
|---|---|
npm run dev | Start Electron + Vite dev mode (main + preload + renderer) |
npm run dev:web | Start Renderer only (web mode, no Electron) |
npm run dev:server | Start Fastify web server (optional) |
npm run build | Build all packages (renderer + desktop) |
npm run build:renderer | Build frontend only (Vite production mode) |
npm run build:desktop | Build Electron main process only (tsup) |
npm run build:official | Build official release (with signing) |
npm run build:steam | Build Steam version |
npm run lint | Run ESLint + TypeScript type checking |
npm run lint:eslint | Run ESLint only |
npm run typecheck | Run TypeScript compilation check only |
npm run test | Run Vitest tests |
npm run format | Prettier format all code |
npm run format:file <path> | Prettier format a single file |
npm run verify:build | Verify build artifact size (4 key metrics) |
npm run analyze:build | Analyze 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
invokerequests) - Performance — analyze rendering performance
Logging
Elftia uses Winston for log management.
| Environment Variable | Description | Default |
|---|---|---|
LOG_LEVEL | Log level (debug / info / warn / error) | info |
Log file locations:
| Platform | Path |
|---|---|
| Windows | %APPDATA%/elftia/logs/ |
| macOS | ~/Library/Application Support/elftia/logs/ |
| Linux | ~/.config/elftia/logs/ |
Development vs. Production Differences
| Aspect | Development Mode | Production Mode |
|---|---|---|
| Frontend serving | Vite Dev Server (HMR) | Static files (file://) |
| Source maps | Enabled | Disabled |
| Minification | None | Terser (removes console.log) |
| Code splitting | Full load | React.lazy per route |
| CSP | Relaxed | Strict |
| DevTools | Opens automatically | Hidden by default (can be enabled in developer mode) |
| Database | Development user data directory | Production user data directory |
| Log level | debug | info |
Worker Threads
Elftia spawns multiple Worker threads in the main process to avoid blocking IPC:
| Worker | File | Responsibility |
|---|---|---|
db.worker | workers/db/ | SQLite read/write operations |
fileSearch.worker | workers/fileSearch/ | File content search (ripgrep) |
fileWatcher.worker | workers/fileWatcher/ | File system change monitoring |
mcp.worker | workers/mcp/ | MCP server communication |
diagnostics.worker | workers/diagnostics/ | System diagnostics collection |
project.worker | workers/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()