@vinitkumargoel/fvr
v0.3.1
Published
Lightweight Node.js process manager
Maintainers
Readme
fvr
FVR is a lightweight, minimal Node.js process manager — a PM2 alternative designed for simplicity and efficiency. Zero bloat, zero complexity. Just process management done right.
✨ Features
- 🚀 Fork & Cluster Modes — Run single instances or scale with Node.js clustering
- 🔄 Auto-Restart — Automatic crash recovery with smart crash loop detection
- 📊 Memory Monitoring — Restart processes when memory thresholds are exceeded
- 👁️ Watch Mode — Auto-restart on file changes (perfect for development)
- 📝 Log Management — Centralized stdout/stderr logs with automatic rotation
- 💻 Simple CLI — Clean, intuitive commands (start, stop, restart, list, logs)
- 🎯 Lightweight — Minimal dependencies, fast startup, low overhead
- ⚙️ Easy Configuration — Single JavaScript config file, no complex setup
📋 Requirements
- Node.js ≥ 16.0.0
- OS: Linux (macOS support for development only)
📦 Installation
Install globally via npm:
npm install -g @vinitkumargoel/fvrOr use with npx (no installation needed):
npx @vinitkumargoel/fvr start🚀 Quick Start
1. Create a config file
Create fvr.config.js in your project root:
module.exports = {
apps: [
{
name: "my-app",
script: "server.js",
exec_mode: "cluster",
instances: 2,
autorestart: true,
watch: false,
env: {
NODE_ENV: "production",
PORT: 3000,
},
},
],
};2. Start your app
fvr start3. Check status
fvr list4. View logs
fvr logs my-app5. Manage your app
fvr restart my-app # Restart
fvr stop my-app # Stop
fvr delete my-app # Remove from FVR⚙️ Configuration
Config File
FVR looks for configuration in the following files (in order):
fvr.config.jsfvr.config.cjs.fvrrc.js
Configuration Options
module.exports = {
apps: [
{
// Required fields
name: "my-app", // Unique app name
script: "server.js", // Entry point script
// Process execution
exec_mode: "cluster", // 'fork' | 'cluster' (default: 'fork')
instances: 2, // Number of instances (cluster mode only)
args: "--port 3000", // Arguments (string or array)
// Auto-restart
autorestart: true, // Auto-restart on crash (default: true)
max_memory_restart: "300M", // Restart on memory limit (e.g., '200M', '1G')
// Development
watch: true, // Watch files and auto-restart (default: false)
// Environment
env: {
// Environment variables
NODE_ENV: "production",
PORT: 3000,
},
},
],
};Configuration Fields Reference
| Field | Type | Required | Default | Description |
| -------------------- | ----------------------- | -------- | -------- | ------------------------------------- |
| name | string | ✅ | — | Unique identifier for the app |
| script | string | ✅ | — | Path to the entry script |
| args | string or array | ❌ | [] | CLI arguments passed to script |
| exec_mode | 'fork' or 'cluster' | ❌ | 'fork' | Execution mode |
| instances | number | ❌ | 1 | Number of workers (cluster mode only) |
| watch | boolean | ❌ | false | Auto-restart on file changes |
| max_memory_restart | string | ❌ | null | Memory limit (e.g., '200M', '1G') |
| autorestart | boolean | ❌ | true | Auto-restart on crash |
| env | object or array | ❌ | {} | Environment variables |
Multiple Environments
You can define multiple environment configurations:
env: [
{ NODE_ENV: "development", PORT: 3000 },
{ NODE_ENV: "production", PORT: 8080 },
];FVR uses the first environment by default.
🎮 CLI Commands
fvr start [name]
Start and daemonize an app.
Options:
--watch- Watch folder for changes--name <name>- App name (for inline start)--cwd <path>- Working directory--instances <n>- Number of instances (cluster mode)--max-memory <limit>- Memory restart limit (e.g., 200M, 1G)--env <key=value>- Environment variables (can be repeated)
# Start from config file
fvr start # Start all apps from fvr.config.js
fvr start fvr.config.js # Start all apps from specific config file
fvr start my-app # Start specific app by name (from config or state)
fvr start --watch # Start all apps with file watching enabled
fvr start my-app --watch # Start specific app with watch mode
# Inline start (PM2-style, without config file)
fvr start npm --name my-app -- start
fvr start npm --name api --cwd /path/to/app -- run dev
fvr start node --name worker -- worker.js
fvr start ./server.js --name web --instances 4
fvr start npm --name frontend --watch -- run dev
fvr start node --name app --max-memory 500M -- app.js
fvr start npm --name service --env PORT=3000 --env NODE_ENV=production -- startfvr stop <name>
Stop a process.
Options:
--watch- Stop watching folder for changes (without stopping the process)
fvr stop my-app # Stop specific app
fvr stop all # Stop all apps
fvr stop my-app --watch # Disable watch mode without stoppingfvr restart <name>
Restart a process.
Options:
--watch- Toggle watching folder for changes
fvr restart my-app # Restart specific app
fvr restart all # Restart all apps
fvr restart my-app --watch # Toggle watch mode for appfvr delete <name>
Stop and delete a process from FVR process list.
Alias: fvr del
fvr delete my-app # Delete specific app
fvr del my-app # Same as above (alias)
fvr delete all # Delete all appsfvr update [name]
Update and reload apps with new configuration from config file.
Alias: fvr reload
fvr update # Update all apps from fvr.config.js
fvr update my-app # Update specific app from config
fvr update fvr.config.js # Update all apps from specific config file
fvr reload my-app # Same as update (alias)fvr list
List all processes.
Alias: fvr ls
fvr list # or: fvr lsExample output:
┌──────────────────┬────┬──────────┬────────┬────────────┬─────────┬────────┬────────────┐
│ App name │ id │ mode │ pid │ status │ restart │ uptime │ memory │
├──────────────────┼────┼──────────┼────────┼────────────┼─────────┼────────┼────────────┤
│ my-app (2/2) │ 0 │ cluster │ 12345 │ online │ 0 │ 2h │ 45 MB │
│ worker │ 1 │ fork │ 12399 │ online │ 3 │ 5h │ 22 MB │
└──────────────────┴────┴──────────┴────────┴────────────┴─────────┴────────┴────────────┘
Module activated
● online: 2fvr logs <name>
Stream logs for an app.
fvr logs my-app # Stream stdout + stderr
fvr logs my-app --lines 100 # Show last 100 lines
fvr logs my-app --err # Show only stderr
fvr logs my-app --out # Show only stdoutLogs are stored at: ~/.fvr/logs/<name>-out.log and ~/.fvr/logs/<name>-err.log
📚 Examples
Inline Start (Without Config File)
You can start apps directly from the command line without creating a config file:
# Start npm scripts
fvr start npm --name my-app -- start
fvr start npm --name api --cwd /path/to/project -- run dev
# Start Node.js scripts
fvr start node --name worker -- worker.js
fvr start ./server.js --name web
# With clustering
fvr start node --name api --instances 4 -- server.js
# With watch mode (for development)
fvr start npm --name dev --watch -- run dev
# With memory limit
fvr start node --name app --max-memory 500M -- app.js
# With environment variables
fvr start npm --name service --env PORT=3000 --env NODE_ENV=production -- start
# Complete example for Next.js
fvr start npm --name web --cwd /path/to/nextjs --instances 2 -- startSimple Fork Mode App
module.exports = {
apps: [
{
name: "api",
script: "server.js",
env: { PORT: 3000 },
},
],
};Cluster Mode with Auto-Restart
module.exports = {
apps: [
{
name: "web-app",
script: "index.js",
exec_mode: "cluster",
instances: 4,
autorestart: true,
max_memory_restart: "500M",
env: {
NODE_ENV: "production",
PORT: 8080,
},
},
],
};Development Mode with Watch
module.exports = {
apps: [
{
name: "dev-server",
script: "app.js",
watch: true,
env: {
NODE_ENV: "development",
DEBUG: "app:*",
},
},
],
};Multiple Apps
module.exports = {
apps: [
{
name: "api",
script: "api/server.js",
exec_mode: "cluster",
instances: 2,
env: { PORT: 3000 },
},
{
name: "worker",
script: "workers/queue.js",
env: { REDIS_URL: "redis://localhost:6379" },
},
{
name: "cron",
script: "tasks/scheduler.js",
autorestart: false,
},
],
};🔧 How It Works
Daemon Architecture
FVR runs a persistent daemon process that:
- Manages all child processes (fork/cluster)
- Monitors memory usage every 5 seconds
- Handles auto-restart with crash loop detection
- Watches files for changes (when enabled)
- Pipes logs to
~/.fvr/logs/
State Persistence
FVR stores process metadata in ~/.fvr/state.json:
- App configurations
- Process IDs (PIDs)
- Restart counts and history
- Current status
IPC Communication
CLI commands communicate with the daemon via Unix domain socket (~/.fvr/daemon.sock).
🆚 FVR vs PM2
| Feature | FVR | PM2 | | -------------------- | ----------------------------------- | --------------------------------------- | | Size | ~65 dependencies | 200+ dependencies | | Complexity | Single config file | Multiple config formats, ecosystem | | Startup Time | Fast (<100ms) | Slower | | Memory Footprint | Minimal (~20MB) | Higher (~50-100MB) | | Features | Core essentials | Kitchen sink (metrics, deploy, modules) | | Learning Curve | Minutes | Hours | | Best For | Production servers, VPS, containers | Large teams, full DevOps pipeline |
Use FVR if you want:
- ✅ Simple, reliable process management
- ✅ Minimal resource overhead
- ✅ Easy configuration
- ✅ No unnecessary features
Use PM2 if you need:
- ❌ Built-in monitoring dashboard
- ❌ Deploy automation
- ❌ Module ecosystem
- ❌ Startup scripts (systemd integration)
📂 Project Structure
~/.fvr/
├── state.json # Process state persistence
├── daemon.sock # IPC socket
└── logs/
├── app-out.log # Stdout logs
└── app-err.log # Stderr logs🐛 Troubleshooting
Daemon not starting?
# Check if daemon is running
ps aux | grep fvr
# Check logs (if any)
ls -la ~/.fvr/App not starting?
- Verify script path exists:
ls -la path/to/script.js - Check config syntax:
node -c fvr.config.js - View logs:
fvr logs <app-name>
Permission issues?
# Ensure FVR home directory has correct permissions
chmod 755 ~/.fvr/🤝 Contributing
Contributions are welcome! Please follow these guidelines:
Development Setup
# Clone the repository
git clone https://github.com/vinitkumargoel/fvr.git
cd fvr
# Install dependencies
npm install
# Link for local development
npm link
# Run tests
npm testCode Style
- Use 2 spaces for indentation
- Follow existing code patterns
- Add comments for complex logic
- Write tests for new features
Submitting Changes
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Commit your changes:
git commit -am 'Add new feature' - Push to the branch:
git push origin feature/my-feature - Submit a pull request
Reporting Issues
When reporting bugs, please include:
- FVR version (
fvr --version) - Node.js version (
node --version) - Operating system
- Steps to reproduce
- Error messages and logs
📄 License
MIT © Vinit Kumar Goel
🙏 Acknowledgments
- Inspired by PM2
- Built with Node.js and ❤️
📞 Support
- Issues: GitHub Issues
- Discussions: GitHub Discussions
Made with ❤️ for developers who value simplicity
