Skip to content

Replace pm2 with homegrown process manager daemon#2712

Open
fredrikekelund wants to merge 12 commits intostu-1301-replace-pm2-axon-with-homegrownfrom
stu-1349-replace-pm2-with-homegrown
Open

Replace pm2 with homegrown process manager daemon#2712
fredrikekelund wants to merge 12 commits intostu-1301-replace-pm2-axon-with-homegrownfrom
stu-1349-replace-pm2-with-homegrown

Conversation

@fredrikekelund
Copy link
Contributor

@fredrikekelund fredrikekelund commented Mar 5, 2026

Related issues

How AI was used in this PR

Codex wrote most of the code in this PR, starting from a detailed list of requirements I shared (based on our experience with pm2). I iterated on this over multiple days, both with Codex and by hand. I've touched all major files in the PR. process-manager-ipc.ts is a standout example – I made many manual edits there. I've reviewed all the code. The code I've spent the least time editing or reviewing is the tests.

Proposed Changes

Tip

I'm happy to pair for a review of this PR. I know it's a big one. Also, please note that this PR builds upon the changes in #2690. That PR should be reviewed first.

See STU-1349 for the "why" of removing pm2. This PR implements the following:

  • A process-manager-daemon.ts that manages child processes. This involves forking them, tracking them in-memory, forwarding child IPC messages as typed daemon events, and writing stdout/stderr to PM2-compatible log files under ~/.studio/pm2/logs. This file is the PM2 replacement.
  • daemon-client.ts replaces pm2-manager.ts. It talks to the daemon over a control socket for request/response commands and an events socket for receiving messages from child processes and process events (online/exit, etc.).

The architecture largely follows PM2's example, and process-manager-daemon.ts implements the same functionality. A few notes to get reviewers started:

  • Starting/stopping processes are relatively easy to understand from the code.
  • IPC is a little trickier, but the gist is that daemon-client exports a sendMessageToProcess function that uses the process manager "control socket" to send a message with a processId target. When process-manager-daemon.ts receives the message, it uses the standard Node.js IPC mechanism to forward it to the child process. Child processes cannot respond directly to these messages, but they can emit events through Node.js standard IPC, which process-manager-daemon.ts picks up and broadcasts on the "events socket". daemonBus listens on the events socket, and the subscribeSiteEvents function picks up the process-message and process-event events, which are ultimately picked up by _events.ts.

Testing Instructions

  1. Run npm start
  2. Ensure that starting and stopping sites works as expected
  3. Try creating a new site, too
  4. While Studio is still running, run node apps/cli/dist/cli/main.js site start --skip-browser --path PATH_TO_SITE in your terminal
  5. Ensure that the site is immediately marked as started in Studio

Pre-merge Checklist

  • Have you checked for TypeScript, React or other console errors?

@fredrikekelund fredrikekelund requested review from a team and bcotrim March 5, 2026 15:32
@fredrikekelund fredrikekelund self-assigned this Mar 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant