Documentation Index
Fetch the complete documentation index at: https://docs.claude-mem.ai/llms.txt
Use this file to discover all available pages before exploring further.
Historical Migration DocumentationThis document describes the PM2 to Bun migration that occurred in v7.1.0 (December 2025). If you’re installing claude-mem for the first time, this migration has already been completed and you can use the current Bun-based system documented in the main guides.This documentation is preserved for users upgrading from versions older than v7.1.0.
PM2 to Bun Migration: Complete Technical Documentation
Version: 7.1.0 Date: December 2025 Migration Type: Process Management (PM2 → Bun) + Database Driver (better-sqlite3 → bun:sqlite)Executive Summary
Claude-mem version 7.1.0 introduces two major architectural migrations:- Process Management: PM2 → Custom Bun-based ProcessManager
- Database Driver: better-sqlite3 npm package → bun:sqlite runtime module
Key Benefits
- Simplified Dependencies: Removes PM2 and better-sqlite3 npm packages
- Improved Cross-Platform Support: Better Windows compatibility
- Faster Installation: No native module compilation required
- Built-in Runtime: Leverages Bun’s built-in process management and SQLite
- Reduced Complexity: Custom ProcessManager is simpler than PM2 integration
Migration Impact
- Data Preservation: User data, settings, and database remain unchanged
- Automatic Cleanup: Old PM2 processes automatically terminated (all platforms)
- No User Action Required: Migration happens automatically on first hook trigger
- Backward Compatible: SQLite database format unchanged (only driver changed)
Architecture Comparison
Old System (PM2-based)
Process Management (PM2)
Process Management (PM2)
Component: PM2 (Process Manager 2)Pain Points:
- Package:
pm2npm dependency - Process Name:
claude-mem-worker - Management: External PM2 daemon manages lifecycle
- Discovery:
pm2 list,pm2 describecommands - Auto-restart: PM2 automatically restarts on crash
- Logs:
~/.pm2/logs/claude-mem-worker-*.log - PID File:
~/.pm2/pids/claude-mem-worker.pid
- Additional npm dependency required
- PM2 daemon must be running
- Potential conflicts with other PM2 processes
- Windows compatibility issues
- Complex configuration for simple use case
Database Driver (better-sqlite3)
Database Driver (better-sqlite3)
Component: better-sqlite3
- Package:
better-sqlite3npm package (native module) - Installation: Requires native compilation (node-gyp)
- Windows: Requires Visual Studio build tools + Python
- Import:
import Database from 'better-sqlite3'
- Node.js development headers
- C++ compiler (gcc/clang on Mac/Linux, MSVC on Windows)
- Python (for node-gyp)
- Windows: Visual Studio Build Tools
New System (Bun-based)
Process Management (Custom ProcessManager)
Process Management (Custom ProcessManager)
Component: Custom ProcessManager (Core Mechanisms:
src/services/process/ProcessManager.ts)- Package: Built-in Bun APIs (no external dependency)
- Process Spawn:
Bun.spawn()with detached mode - Management: Direct process control via PID file
- Discovery: PID file + process existence check + HTTP health check
- Auto-restart: Hook-triggered restart on failure detection
- Logs:
~/.claude-mem/logs/worker-YYYY-MM-DD.log - PID File:
~/.claude-mem/.worker.pid - Port File:
~/.claude-mem/.worker.port(new)
-
PID File Management:
- File:
~/.claude-mem/.worker.pid - Content: Process ID (e.g., “35557”)
- Validation: Process existence via
kill(pid, 0)signal
- File:
-
Port File Management:
- File:
~/.claude-mem/.worker.port - Content: Two lines (port number, PID)
- Purpose: Track port binding and validate PID match
- File:
-
Health Checking:
- Layer 1: PID file exists?
- Layer 2: Process alive? (
kill(pid, 0)) - Layer 3: HTTP health check (
GET /health) - All three must pass for “healthy” status
- No external dependencies
- Simpler codebase (direct control)
- Better error handling and validation
- Platform-agnostic (Bun handles platform differences)
Database Driver (bun:sqlite)
Database Driver (bun:sqlite)
Component: bun:sqlite
- Package: Built into Bun runtime (no npm package)
- Installation: None required (comes with Bun ≥1.0)
- Platform: Works anywhere Bun works
- Import:
import { Database } from 'bun:sqlite' - API: Similar to better-sqlite3 (synchronous)
- Bun ≥1.0 (automatically installed if missing)
- No native compilation required
- No platform-specific build tools needed
- SQLite database format: Unchanged
- Database file:
~/.claude-mem/claude-mem.db(same location) - Query syntax: Identical (both use SQLite SQL)
Migration Mechanics
One-Time PM2 Cleanup
The migration system uses a marker-based approach to perform PM2 cleanup exactly once. Implementation:src/shared/worker-utils.ts:73-86
Migration Trigger Points
Worker Status Check
ensureWorkerRunning() checks if ~/.claude-mem/.worker.pid exists (it doesn’t for first run after update)Marker File
Location:~/.claude-mem/.pm2-migrated
Content: ISO 8601 timestamp
- One-time migration flag
- Prevents repeated PM2 cleanup on every start
- Persists across restarts and reboots
- Created: First hook trigger after update to 7.1.0+ (all platforms)
- Updated: Never
- Deleted: Never (user could manually delete to force re-migration)
User Experience Timeline
First Session After Update
This is the critical migration moment. The process takes approximately 2-5 seconds.
- Hook fires (SessionStart most common)
- Worker status check: No PID file → worker not running
- Migration check: No marker file → run PM2 cleanup
- PM2 cleanup:
pm2 delete claude-mem-worker(old worker terminated) - Marker creation:
~/.claude-mem/.pm2-migratedwith timestamp - New worker start: Bun process spawned, PID/port files created
- Verification: Process check + HTTP health check
- Hook completes: Claude Code session starts normally
- Slight delay on first startup (PM2 cleanup + new worker spawn)
- No error messages (cleanup failures silently handled)
- Worker appears running via
npm run worker:status - Old PM2 worker no longer in
pm2 list
Subsequent Sessions
After migration completes, every hook trigger follows the fast path:- PID file exists? YES
- Process alive? YES
- HTTP health check? SUCCESS
- Result: Worker already running, done (~50ms)
Platform-Specific Behavior
Platform Comparison
| Feature | macOS | Linux | Windows |
|---|---|---|---|
| PM2 Cleanup | Attempted | Attempted | Attempted |
| Marker File | Created | Created | Created |
| Process Signals | POSIX (native) | POSIX (native) | Bun abstraction |
| Bun Support | Full | Full | Full |
| PID File | Yes | Yes | Yes |
| Port File | Yes | Yes | Yes |
| Health Check | HTTP | HTTP | HTTP |
| Migration Delay | ~2-5s first time | ~2-5s first time | ~2-5s first time |
Platform Notes
- macOS
- Linux
- Windows
- POSIX signal handling works natively
- Bun fully supported
- No platform-specific workarounds needed
Observable Changes
Command Changes
| Old (PM2) | New (Bun) | Notes |
|---|---|---|
pm2 list | npm run worker:status | Shows worker status |
pm2 start <script> | npm run worker:start | Start worker |
pm2 stop claude-mem-worker | npm run worker:stop | Stop worker |
pm2 restart claude-mem-worker | npm run worker:restart | Restart worker |
pm2 delete claude-mem-worker | npm run worker:stop | Remove worker |
pm2 logs claude-mem-worker | npm run worker:logs | View logs |
pm2 describe claude-mem-worker | npm run worker:status | Detailed status |
pm2 monit | No equivalent | PM2-specific monitoring |
File Location Changes
Logs:User-Visible Changes
Before Update:Orphaned Files
After migration, these PM2 files may remain (safe to delete):File System State
State Directory Structure
Before Migration (PM2 system):Edge Cases and Troubleshooting
Scenario 1: Migration Fails (PM2 Still Running)
Symptoms:pm2 liststill showsclaude-mem-worker- Port conflict errors in logs
- Worker fails to start
Scenario 2: Stale PID File (Process Dead)
Symptoms:npm run worker:statusshows “not running”.worker.pidfile exists- Process ID doesn’t exist
Scenario 3: Port Already in Use
Error:EADDRINUSE: address already in use
Resolution:
Common Error Messages
| Error | Cause | Resolution |
|---|---|---|
EADDRINUSE | Port already in use | lsof -i :37777 then kill conflicting process |
No such process | Stale PID file | Automatic cleanup on next hook trigger |
pm2: command not found | PM2 not installed | None needed (error is caught and ignored) |
Invalid port X | Port validation failed | Update CLAUDE_MEM_WORKER_PORT in settings |
Developer Notes
Testing the Migration
Architecture Decisions
Why Custom ProcessManager Instead of PM2?- Simplicity: Direct control, no external daemon
- Dependencies: Remove npm dependency
- Cross-platform: Bun handles platform differences
- Bundle Size: Reduce plugin package size
- Control: Fine-grained error handling and validation
- Performance: Avoid unnecessary process spawning
- Idempotency: Migration runs exactly once
- Debugging: Timestamp shows when migration occurred
- Simplicity: Clear migration state
- Quality Migration: Clean up orphaned processes
- Consistency: Same behavior across all platforms
- Safety: Error handling already in place (try/catch)
- No Downside: If PM2 not installed, error is caught and ignored
Summary
The migration from PM2 to Bun-based ProcessManager is a one-time, automatic, transparent transition that:- Removes external dependencies (PM2, better-sqlite3)
- Simplifies architecture (direct process control)
- Improves cross-platform support (especially Windows)
- Preserves user data (database, settings, logs unchanged)
- Requires no user action (automatic on first hook trigger)

