We migrated the code running the superchargejs.com website from CommonJS to ESM. We used ts-node
in combination with SWC to run the CommonJS TypeScript code. But ts-node
isn’t working with TypeScript and ESM (there’s an open issue).
Now that ts-node
isn’t working, we need to use a different tool. Bun is a new JavaScript runtime with built-in TypeScript support. The Supercharge website code is small, a good fit to test a new runtime like Bun.
We’re deploying the project using PM2 and this tutorial shows you how to configure PM2 to start the process using the Bun runtime.
PM2 Series Overview
- Utility Overview & Installation
- Series Round-Up
- Using Bun to Start Your App
- Use TSX to Start Your App
PM2 Configuration to Run Your App with Bun
PM2 is a daemon process manager that keeps your application running continuously. You can configure the way PM2 should run your application using flags on the command line or a configuration file. We recommend the configuration file to surface the way you start your app.
PM2 uses Node.js as the default interpreter for the script that you want to start. You can change to a different interpreter
, like Bun, Ruby, Python, and any other if needed.
Here’s a sample PM2 configuration file using Bun to run your application:
module.exports = {
name: 'superchargejs.com',
script: 'server.ts',
interpreter: 'bun',
}
If your system user doesn’t have the global bun
command available in your terminal, you can define a path to Bun’s installation and PM2 will resolve that for you:
module.exports = {
name: 'superchargejs.com',
script: 'server.ts',
interpreter: '~/.bun/bin/bun',
// or use an absolute path
// interpreter: '/home/marcus/.bun/bin/bun'
}
PM2 Cluster Mode is not Supported With Bun
Running apps in PM2 cluster mode is connected to Node.js as the interpreter. PM2 uses Node.js’ cluster module to scale your clustered application. Using a different interpreter than Node.js forces your app to start in PM2 fork
mode.
If you would add the exec_mode: 'cluster'
and instances: 2
options in the Bun PM2 configuration file, it would still start as a single instance in fork mode:
module.exports = {
name: 'superchargejs.com',
script: 'server.ts',
interpreter: 'bun',
/**
* cluster mode is not working when using a custom "interpreter"
* @see https://github.com/Unitech/pm2/issues/1575
*/
exec_mode: 'cluster',
instances: 2,
}
Starting your configuration file with PM2 results in a single, forked process:
launch@supercharge-001-fra1:~$ pm2 ls
┌─────┬──────────────────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐
│ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │
├─────┼──────────────────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤
│ 1 │ superchargejs.com │ default │ N/A │ fork │ 12345 │ 1m │ 1 │ online │ 0% │ 80.2mb │ marcus │ disabled │
└─────┴──────────────────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘
Enjoy running your Bun applications with PM2!