I was getting frequent OOM crashes, so I asked Claude to create a Cursor Rule that would reduce oom crashes. I then asked it to document the solution. I’m sharing it below. It refences some of my own specific processes, but it should be generalizable to you situation.
**# Out-of-Memory (OOM) Prevention Guide**
This document outlines strategies to prevent Out-of-Memory errors when developing with Cursor AI and multiple Vite/React frontend projects.
**## Problem Overview**
OOM errors commonly occur when:
\- Multiple Vite dev servers run simultaneously
\- Circular dependencies cause infinite module resolution loops
\- Orphaned Node.js processes accumulate over time
\- Hot Module Replacement (HMR) gets stuck in reload cycles
**## Prevention Strategies**
**### 1. Memory Limits for Vite Dev Servers**
All frontend \`package.json\` files have been configured with increased Node.js memory limits:
\`\`\`json
{
"scripts": {
"dev": "set NODE_OPTIONS=--max-old-space-size=4096 && vite"
}
}
\`\`\`
This increases the V8 heap size from the default \~1.5GB to 4GB, giving Vite more headroom for large projects.
**\*\*Affected projects:\*\***
\- admin-web
\- marketing-web
\- credentialing-web
\- customer-service-web
**### 2. Run Only One Frontend at a Time**
Unless explicitly needed for integration testing, run only one frontend dev server at a time.
**\*\*Check what's already running:\*\***
\`\`\`powershell
netstat -ano | findstr "LISTENING" | findstr "5178\\|5170\\|5174\\|5176\\|5179\\|5182\\|5183"
\`\`\`
**\*\*Port assignments:\*\***
| Port | Frontend |
|------|----------|
\[omitted\]
**### 3. Monitor and Kill Orphaned Processes**
Node.js processes can become orphaned when dev servers crash or Cursor restarts unexpectedly.
**\*\*View all Node.js processes with memory usage:\*\***
\`\`\`powershell
Get-Process node -ErrorAction SilentlyContinue | Select-Object Id, ProcessName, @{N='Memory(MB)';E={\[math\]::Round($\_.WorkingSet64/1MB,2)}}, CPU
\`\`\`
**\*\*Kill processes using excessive memory (>500MB):\*\***
\`\`\`powershell
Get-Process node -ErrorAction SilentlyContinue | Where-Object { $\_.WorkingSet64 -gt 500MB } | Stop-Process -Force
\`\`\`
**\*\*Kill ALL Node.js processes (nuclear option):\*\***
\`\`\`powershell
Get-Process node -ErrorAction SilentlyContinue | Stop-Process -Force
\`\`\`
**### 4. Avoid Circular Dependencies**
Circular dependencies are the #1 cause of OOM errors during development. They cause Vite's HMR to enter infinite loops.
**\*\*Rules to follow:\*\***
1\. **\*\*Never import between page components and layout components bidirectionally\*\***
- Bad: \`Layout.tsx\` imports from \`Settings.tsx\`, and \`Settings.tsx\` imports from \`Layout.tsx\`
2\. **\*\*Extract shared functions to utility files\*\***
- Good: Both components import from \`src/utils/sharedFunction.ts\`
3\. **\*\*Keep imports flowing in one direction\*\***
\`\`\`
utils/ → components/ → pages/ → App.tsx
\`\`\`
**\*\*Example of breaking a circular dependency:\*\***
Before (circular):
\`\`\`typescript
// Layout.tsx
import { isDevMode } from '../pages/Settings';
// Settings.tsx
import { TABS } from '../components/Layout';
\`\`\`
After (fixed):
\`\`\`typescript
// utils/devMode.ts
export function isDevMode() { ... }
// utils/constants.ts
export const TABS = \[ ... \];
// Layout.tsx
import { isDevMode } from '../utils/devMode';
import { TABS } from '../utils/constants';
// Settings.tsx
import { TABS } from '../utils/constants';
\`\`\`
**### 5. Cursor-Specific Best Practices**
When using Cursor AI agents:
1\. **\*\*Before starting a dev server\*\***, agents should check for existing processes
2\. **\*\*Use** \`block_until_ms: 0\`**\*\*** for dev servers to run them in background
3\. **\*\*Don't read entire large files\*\*** - use offset/limit parameters
4\. **\*\*Restart Cursor\*\*** if it becomes sluggish or unresponsive
**## Recovery Steps**
If an OOM error occurs:
1\. **\*\*Kill all Node processes:\*\***
\`\`\`powershell
Get-Process node -ErrorAction SilentlyContinue | Stop-Process -Force
\`\`\`
2\. **\*\*Wait 5-10 seconds\*\*** for processes to fully terminate
3\. **\*\*Clear Vite cache (optional):\*\***
\`\`\`powershell
Remove-Item -Recurse -Force ".\\node_modules\\.vite" -ErrorAction SilentlyContinue
\`\`\`
4\. **\*\*Restart only the needed dev server:\*\***
\`\`\`powershell
cd admin-web
npm run dev
\`\`\`
5\. **\*\*If Cursor is frozen\*\***, use Task Manager to end the Cursor process and restart the IDE
**## Cursor Rules Integration**
A Cursor rule has been added at \`.cursor/rules/prevent-oom.mdc\` that:
\- Reminds AI agents to check for orphaned processes
\- Warns against circular dependencies
\- Provides recovery commands
This rule is automatically applied to all TypeScript/TSX files in frontend projects.
**## Quick Reference Commands**
\`\`\`powershell
\# Check running dev servers
netstat -ano | findstr "LISTENING" | findstr "517"
\# Check Node.js memory usage
Get-Process node -ErrorAction SilentlyContinue | Select-Object Id, @{N='MB';E={\[math\]::Round($\_.WorkingSet64/1MB)}}
\# Kill all Node processes
Get-Process node -ErrorAction SilentlyContinue | Stop-Process -Force
\# Kill specific process by PID
Stop-Process -Id <PID> -Force
\# Clear Vite cache for a project
Remove-Item -Recurse -Force ".\\node_modules\\.vite"
\`\`\`
**## Monitoring Script**
Save this as \`check-memory.ps1\` for quick diagnostics:
\`\`\`powershell
Write-Host "=== Node.js Processes ===" -ForegroundColor Cyan
Get-Process node -ErrorAction SilentlyContinue |
Select-Object Id, @{N='Memory(MB)';E={\[math\]::Round($\_.WorkingSet64/1MB,2)}}, CPU |
Format-Table -AutoSize
Write-Host "\`n=== Listening Ports (5170-5200) ===" -ForegroundColor Cyan
netstat -ano | findstr "LISTENING" | findstr "517\\|518\\|519\\|520"
Write-Host "\`n=== Total Node Memory ===" -ForegroundColor Cyan
$total = (Get-Process node -ErrorAction SilentlyContinue | Measure-Object WorkingSet64 -Sum).Sum
Write-Host "Total: $(\[math\]::Round($total/1MB,2)) MB"
\`\`\`
\---
*\*Last updated: February 2026\**