Running both nodejs and bun apps in turborepo
Tags: programming, typescript, javascript, tutorial
Published: 2023-06-25 23:31:53

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8in2wmm4eotggao7u4fg.png)

So finally today, after a little bit of tinkering about, I figured out how to use a bun-powered app, simultaneously with my other nodejs apps in a turborepo.

And so here I am, writing this article so that someone else who is seeking a solution on the web for this exact kind of problem can benefit from this article. Or at least learn something from it.

So without falling into anymore tangents, let's get down to how I put it together.

Quick overview of the tech involved:

- Turborepo
- Pnpm as the package manager
- Bun
  - HonoJS
- NodeJS
  - Fastify
  - NextJS
- other...

I'll setup a fresh turborepo with the following command

```bash
npx create-turbo@latest
# where : dual-runtimes-turborepo
# package manager : pnpm
```

At the root, we get the current setup

```text
ROOT_DIR:

apps
 - apps/docs
 - apps/web
packages
 - packages/eslint-config-custom
 - packages/tsconfig
 - packages/ui
package.json
pnpm-lock.json
pnpm-workspaces.yaml
turbo.json
... other files
```

Run it with `pnpm run dev` to ensure it works properly.

## Some cleanup

1. I prefixed all the local package names with "@local101/", to make sure my package names never conflict with any external npm packages
2. I removed the eslint-config-custom, to simplify the example, and because I don't use it anyways.

## Core config required to make it all work

Open up the root `package.json` and add the following to it

```json
{
  "name": "dual-runtimes-monorepo",
  "private": true,
  "workspaces": [
    // example app/package, for the example setup,
    // And don't copy/paste comments into JSON
    "apps/aserver",
    "packages/logic"
  ],
  "scripts": {
    "build": "turbo run build",
    "dev": "turbo run dev",
    "lint": "turbo run lint",
    "format": "prettier --write \"**/*.{ts,tsx,md}\""
  },
  "devDependencies": {
    "@turbo/gen": "^1.9.7",
    "eslint": "^7.32.0",
    "prettier": "^2.5.1",
    "turbo": "latest"
  },
  "packageManager": "pnpm@7.15.0",
  "volta": {
    "node": "20.3.1"
  }
}
```

Here I added a couple of entries. Ignoring the `volta` config(which is a [Toolchain manager](https://volta.sh/)), the `workspaces` part is the key component required for bun to function. Here you specify the path to the packages and apps which you require for bun to pickup.

This is a little bit of downside for `yarm` and `pnpm` users like me, as bun follows the `npm` spec, and I'm using `pnpm` workspaces to manage for example. I just had to do their respective config, which is just a handful of more lines of code.

Important Note: This may not be required BUT if you run into a bun linking error, I have a helper script (`link-packages-to-bun.sh`) in the root of the monorepo to make it easier to register your packages to bun's repository.

```bash
#!/bin/bash

# iterate over "packages" directory, cd into each package and run "bun link" for each package and then cd out of the path
for package in packages/*; do
 echo "[...] Linking $package to bun"
 # $package is "packages/pkgdir"
 cd $package
 # get the "pkgdir" part from the string
 package_name=$(echo $package | cut -d'/' -f2)
 # ensure that this matches the "name" in each package.json in your local packages.
 # this only works if your package name matches the dir name ex. "ui" for dir "ui" etc.
 bun link "@local101/$package_name"
 cd ../..
 echo "[+] Done linking $package to bun"
done

```

So before doing `pnpm i`(don't run until the next section is done), run `./link-packages-to-bun.sh` to link packages

For now, let's move onto setting up our `aserver` app

## Bun app setup - Hono

Lately, I've been checking out different bun frameworks, the latest one being hono. So I just chose it for this example.

Now to setup the app, I did the following:

```bash
rm -rf apps/docs packages/eslint-config-custom
# ^ optional command, I did it to reduce the focus scope

cd apps

npm create hono@latest aserver
# select bun and wait for it to complete

cd ..
```

Then I replaced the index.ts of our new app with the following

```ts
// apps/aserver/src/index.ts

import { uselessAddFunctionForTheSakeOfExample } from "@local101/logic";
import { Hono } from "hono";

const hono = new Hono({});

hono.get("/", async (c) => {
  const ans = uselessAddFunctionForTheSakeOfExample(2, 2);
  return c.json({
    message: `Hey, did you know that 2 + 2 = ${ans}. I know right?`,
  });
});
hono.get("/ping", async (c) => c.json({ message: "pong" }));

export default {
  port: 9001,
  fetch: hono.fetch,
};
```

And now finally to ensure our bun dependencies are properly installed, modify the `package.json` of the newly setup app as follows:

```json
{
  "name": "@local101/aserver",
  "version": "0.0.0",
  "private": true,
  "description": "Well, it's a... server",
  "scripts": {
    "postinstall": "bun install",
    "dev": "bun run --hot src/index.ts",
    "start": "bun run src/index.ts"
  },
  "dependencies": {
    "@local101/logic": "workspace:*",
    "hono": "^3.2.6"
  },
  "devDependencies": {
    "bun-types": "^0.6.2"
  }
}
```

The `postinstall` and `start` scripts are the only main requirements, but I put in a `@local101/logic` package for demonstration purposes.

And with that the core setup is complete!

## Test running it all

Now from the root of the monorepo, run:

```bash
pnpm i
# you should see your bun's post install script running here

pnpm run dev
```

And you should get a:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iv2hrbrmk7iqwhfss4jr.png)

Now testing out our bun application, if you followed this tutorial, you should get:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q7u9rfucgu9m38nwjk9q.png)

Now try running `pnpm build` and then `pnpm start`(if setup in the root `turbo.json`+`package.json`), it should all should work as expected. And so that concludes it all!

I hope you got something out of this article... if not then... go do something meaningful... like touch some grass.

Anyways, [Click Here](https://github.com/mahmadrehan/running-both-node-and-bun-apps-in-turborepo) for the link to view the source code of the monorepo I used as the example in this article.

If you face any issues, then let me know and I'll try to help out.

I'll leave with a final note: If you're going to use bleeding edge technology, then bleed responsibly.