<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ahmad</title>
    <description>The latest articles on DEV Community by Ahmad (@0xahmad).</description>
    <link>https://dev.to/0xahmad</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F649473%2F27d17a26-4cd7-4239-8289-2cb514a3ecd9.jpeg</url>
      <title>DEV Community: Ahmad</title>
      <link>https://dev.to/0xahmad</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/0xahmad"/>
    <language>en</language>
    <item>
      <title>Running both nodejs and bun apps in turborepo</title>
      <dc:creator>Ahmad</dc:creator>
      <pubDate>Sun, 25 Jun 2023 23:31:53 +0000</pubDate>
      <link>https://dev.to/0xahmad/running-both-nodejs-and-bun-apps-in-turborepo-33id</link>
      <guid>https://dev.to/0xahmad/running-both-nodejs-and-bun-apps-in-turborepo-33id</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8in2wmm4eotggao7u4fg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8in2wmm4eotggao7u4fg.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;So without falling into anymore tangents, let's get down to how I put it together.&lt;/p&gt;

&lt;p&gt;Quick overview of the tech involved:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Turborepo&lt;/li&gt;
&lt;li&gt;Pnpm as the package manager&lt;/li&gt;
&lt;li&gt;Bun

&lt;ul&gt;
&lt;li&gt;HonoJS&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;NodeJS

&lt;ul&gt;
&lt;li&gt;Fastify&lt;/li&gt;
&lt;li&gt;NextJS&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;other...&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;I'll setup a fresh turborepo with the following command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-turbo@latest
&lt;span class="c"&gt;# where : dual-runtimes-turborepo&lt;/span&gt;
&lt;span class="c"&gt;# package manager : pnpm&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the root, we get the current setup&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run it with &lt;code&gt;pnpm run dev&lt;/code&gt; to ensure it works properly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some cleanup
&lt;/h2&gt;

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

&lt;h2&gt;
  
  
  Core config required to make it all work
&lt;/h2&gt;

&lt;p&gt;Open up the root &lt;code&gt;package.json&lt;/code&gt; and add the following to it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dual-runtimes-monorepo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"private"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"workspaces"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;example&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;app/package&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;example&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;And&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;don't&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;copy/paste&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;comments&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;into&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;JSON&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"apps/aserver"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"packages/logic"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"turbo run build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"turbo run dev"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"lint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"turbo run lint"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"format"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"prettier --write &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;**/*.{ts,tsx,md}&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"devDependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@turbo/gen"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^1.9.7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"eslint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^7.32.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"prettier"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^2.5.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"turbo"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"latest"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"packageManager"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pnpm@7.15.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"volta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"20.3.1"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here I added a couple of entries. Ignoring the &lt;code&gt;volta&lt;/code&gt; config(which is a &lt;a href="https://volta.sh/" rel="noopener noreferrer"&gt;Toolchain manager&lt;/a&gt;), the &lt;code&gt;workspaces&lt;/code&gt; 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.&lt;/p&gt;

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

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

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

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So before doing &lt;code&gt;pnpm i&lt;/code&gt;(don't run until the next section is done), run &lt;code&gt;./link-packages-to-bun.sh&lt;/code&gt; to link packages&lt;/p&gt;

&lt;p&gt;For now, let's move onto setting up our &lt;code&gt;aserver&lt;/code&gt; app&lt;/p&gt;

&lt;h2&gt;
  
  
  Bun app setup - Hono
&lt;/h2&gt;

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

&lt;p&gt;Now to setup the app, I did the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; apps/docs packages/eslint-config-custom
&lt;span class="c"&gt;# ^ optional command, I did it to reduce the focus scope&lt;/span&gt;

&lt;span class="nb"&gt;cd &lt;/span&gt;apps

npm create hono@latest aserver
&lt;span class="c"&gt;# select bun and wait for it to complete&lt;/span&gt;

&lt;span class="nb"&gt;cd&lt;/span&gt; ..
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then I replaced the index.ts of our new app with the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// apps/aserver/src/index.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;uselessAddFunctionForTheSakeOfExample&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@local101/logic&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Hono&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hono&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hono&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Hono&lt;/span&gt;&lt;span class="p"&gt;({});&lt;/span&gt;

&lt;span class="nx"&gt;hono&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ans&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;uselessAddFunctionForTheSakeOfExample&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Hey, did you know that 2 + 2 = &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ans&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;. I know right?`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;hono&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/ping&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pong&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;9001&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;hono&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now finally to ensure our bun dependencies are properly installed, modify the &lt;code&gt;package.json&lt;/code&gt; of the newly setup app as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@local101/aserver"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"private"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Well, it's a... server"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"postinstall"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bun install"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bun run --hot src/index.ts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bun run src/index.ts"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@local101/logic"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"workspace:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"hono"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^3.2.6"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"devDependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"bun-types"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^0.6.2"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;postinstall&lt;/code&gt; and &lt;code&gt;start&lt;/code&gt; scripts are the only main requirements, but I put in a &lt;code&gt;@local101/logic&lt;/code&gt; package for demonstration purposes.&lt;/p&gt;

&lt;p&gt;And with that the core setup is complete!&lt;/p&gt;

&lt;h2&gt;
  
  
  Test running it all
&lt;/h2&gt;

&lt;p&gt;Now from the root of the monorepo, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm i
&lt;span class="c"&gt;# you should see your bun's post install script running here&lt;/span&gt;

pnpm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And you should get a:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiv2hrbrmk7iqwhfss4jr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiv2hrbrmk7iqwhfss4jr.png" alt="Image description" width="800" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now testing out our bun application, if you followed this tutorial, you should get:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq7u9rfucgu9m38nwjk9q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq7u9rfucgu9m38nwjk9q.png" alt="Image description" width="487" height="331"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;I hope you got something out of this article... if not then... go do something meaningful... like touch some grass.&lt;/p&gt;

&lt;p&gt;Anyways, &lt;a href="https://github.com/mahmadrehan/running-both-node-and-bun-apps-in-turborepo" rel="noopener noreferrer"&gt;Click Here&lt;/a&gt; for the link to view the source code of the monorepo I used as the example in this article.&lt;/p&gt;

&lt;p&gt;If you face any issues, then let me know and I'll try to help out.&lt;/p&gt;

&lt;p&gt;I'll leave with a final note: If you're going to use bleeding edge technology, then bleed responsibly.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>typescript</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Friction-less dependency management with Python</title>
      <dc:creator>Ahmad</dc:creator>
      <pubDate>Tue, 22 Mar 2022 04:46:18 +0000</pubDate>
      <link>https://dev.to/0xahmad/friction-less-dependency-management-with-python-45gd</link>
      <guid>https://dev.to/0xahmad/friction-less-dependency-management-with-python-45gd</guid>
      <description>&lt;p&gt;Now... hear me out this combination might seem a bit weird to many of you but just have a read through to see if I can convince you that it's actually useful :)&lt;/p&gt;

&lt;p&gt;So I got into an issue with managing dependencies a few weeks ago and thought of writing this quick little article on what I've been using and think is the best way to manage dependencies for your Python projects.&lt;/p&gt;

&lt;p&gt;If you have no idea of what environments are or don't have familiarity with them, then the next section will give you an overview. Else you can just skip ahead&lt;/p&gt;

&lt;h2&gt;
  
  
  Environments and their reason to exist
&lt;/h2&gt;

&lt;p&gt;When working in a project with python, you have to install many packages in order to complete what you are making, but if you are not careful then those packages can pile up in your python installation; which is not necessarily bad but when talking in the context of deploying to production, you will have to generate a requirements file so your code can run there. It's mostly done with a similar command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pip freeze &amp;gt; requirements.txt&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;which dumps all your installed packages in the &lt;code&gt;requirements.txt&lt;/code&gt; file. But if you take a look in that file, it will include not only the packages you installed while working but every single one which you have installed in the past. And it's basically a pain to deal with.&lt;/p&gt;

&lt;p&gt;To solve this, environments are used in Python. Which simply putting it are:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An Isolated container/place for having a separate dependency tree for each project that you are working on.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The benefit of using such a tool is that you don't have to work with all those unnecessary dependencies which can build up overtime if you keep working with python in a single environment, you can already imagine the difficulty in the management.&lt;/p&gt;

&lt;p&gt;Hope that clears up whatever question you had. If you still have question about environments in python &amp;amp; in general, then &lt;a href="https://www.google.com" rel="noopener noreferrer"&gt;Google&lt;/a&gt; and &lt;a href="https://youtube.com" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt; are your best friends :)&lt;/p&gt;

&lt;p&gt;Now with that aside, let's dive into what we actually are here for&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding
&lt;/h2&gt;

&lt;p&gt;Now, both conda &amp;amp; poetry have a very similar reason to exist, to help manage environments. But they both work a bit differently. Now the technique can be used without conda completely, but the reason I include it is because of conda's capability to allow you to use whichever python's version you want to in an environment. And it's done with a simple command like:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;conda create -n envname python=3.10&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;With this I can have like 100 environments, each with a different python version and it's own set of dependencies. And my system installed python can stay clean and simple like a fresh installation.&lt;/p&gt;

&lt;p&gt;Now, conda is in of itself is good enough for a lot of people as it has it's own package manager and quite a few handy tools (inclined more towards Data Scientists), but the reason I wrote this article is because I use python a lot in development, and I want to keep my production environment as minimal as possible and it's simply not possible to have separate &lt;code&gt;dev &amp;amp; prod&lt;/code&gt; dependency sets ( like in NodeJS for example, if you've worked with it ) with a simple &lt;code&gt;requirements.txt&lt;/code&gt; without some nifty hacks&lt;/p&gt;

&lt;p&gt;Which is where poetry comes in. Poetry is responsible for managing the packages. It's somewhat new (v1.1 as of writing this article) and is being updated relatively frequently. Poetry has a really cool management system which is quite similar to NodeJS, where you can manage normal and dev. dependencies separately.&lt;/p&gt;

&lt;p&gt;The upside of this is when you let's say: package your application with poetry for use in a production environment; it won't matter even if you had like a 1000 packages installed with &lt;code&gt;pip&lt;/code&gt; in your conda environment, you'll only be passing ahead the packages that are marked in the &lt;code&gt;pyproject.toml&lt;/code&gt; file manged by poetry, which already reduced most of the pain with having a clean final requirements file. On top of that you can also exclude out the kinds of dependencies like &lt;em&gt;linters&lt;/em&gt; and &lt;em&gt;formatters&lt;/em&gt; (black I'm looking at you) which are not used in a production environment. And that's basically the gist of it, if you're sold on the idea and want to give it a try then keep reading on other wise this is all the wisdom I wanted to share for today and hopefully you got something out of that ~&lt;/p&gt;

&lt;h3&gt;
  
  
  A Quick Setup
&lt;/h3&gt;

&lt;p&gt;If you haven't already setup conda and poetry, then for conda you should first go and install it from &lt;a href="https://www.anaconda.com/products/individual" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After downloading, if on &lt;em&gt;Windows&lt;/em&gt; just run the executable, if on mac it's pretty similar but as for you linux chads out there, you should know what you're doing, but either it's just 2 commands to set it up after the install:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;chmod +x &amp;lt;your anaconda installation filename here&amp;gt;.sh&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/bin/bash &amp;lt;your anaconda installation filename here&amp;gt;.sh&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;and just follow their steps and it'll set it up for you.&lt;/p&gt;

&lt;p&gt;Now restart/open your terminal and typing in &lt;code&gt;conda&lt;/code&gt; will show a similar output&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;usage: conda [-h] [-V] command ...

conda is a tool for managing and deploying applications, environments and packages.

Options:

positional arguments:
  command

... more output
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;by default conda puts you in a &lt;code&gt;base&lt;/code&gt; environment which you can optionally disable it if you don't like it by typing in:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;conda config --set auto_activate_base false&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now setup an environment with the command&lt;/p&gt;

&lt;p&gt;&lt;code&gt;conda create -n my_awesome_project python=3.10&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then activate it with &lt;code&gt;conda activate my_awesome_project&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now there are many ways to setup poetry, but the quickest way is to just run&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pip install poetry&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And just like that you're ready to start working on whatever you're wanting to with minimal hassle :^]&lt;/p&gt;

&lt;p&gt;For a simple &lt;code&gt;FastAPI&lt;/code&gt; server setup, create a folder and run &lt;code&gt;poetry init&lt;/code&gt; and follow the prompt. It'll generate the &lt;code&gt;pyproject.toml&lt;/code&gt; file. Now type in&lt;/p&gt;

&lt;p&gt;&lt;code&gt;poetry add fastapi&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;following right after with everyone's faviourite formatter black&lt;/p&gt;

&lt;p&gt;&lt;code&gt;poetry add black -D&lt;/code&gt; ~ you can skip this if you want to, I'm just showing how you're gonna separate your prod/dev dependencies. and you'll endup with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;tool&lt;/span&gt;.&lt;span class="n"&gt;poetry&lt;/span&gt;]
&lt;span class="n"&gt;name&lt;/span&gt; = &lt;span class="s2"&gt;"my awesome project"&lt;/span&gt;
&lt;span class="n"&gt;version&lt;/span&gt; = &lt;span class="s2"&gt;"0.1.0"&lt;/span&gt;
&lt;span class="n"&gt;description&lt;/span&gt; = &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="n"&gt;authors&lt;/span&gt; = [&lt;span class="s2"&gt;"username &amp;lt;email@abc.xyz&amp;gt;"&lt;/span&gt;]

[&lt;span class="n"&gt;tool&lt;/span&gt;.&lt;span class="n"&gt;poetry&lt;/span&gt;.&lt;span class="n"&gt;dependencies&lt;/span&gt;]
&lt;span class="n"&gt;python&lt;/span&gt; = &lt;span class="s2"&gt;"^3.10"&lt;/span&gt;
&lt;span class="n"&gt;fastapi&lt;/span&gt; = &lt;span class="s2"&gt;"^0.75.0"&lt;/span&gt;
&lt;span class="n"&gt;uvicorn&lt;/span&gt; = &lt;span class="s2"&gt;"^0.17.6"&lt;/span&gt;

[&lt;span class="n"&gt;tool&lt;/span&gt;.&lt;span class="n"&gt;poetry&lt;/span&gt;.&lt;span class="n"&gt;dev&lt;/span&gt;-&lt;span class="n"&gt;dependencies&lt;/span&gt;]
&lt;span class="n"&gt;black&lt;/span&gt; = &lt;span class="s2"&gt;"^22.1.0"&lt;/span&gt;

[&lt;span class="n"&gt;build&lt;/span&gt;-&lt;span class="n"&gt;system&lt;/span&gt;]
&lt;span class="n"&gt;requires&lt;/span&gt; = [&lt;span class="s2"&gt;"poetry-core&amp;gt;=1.0.0"&lt;/span&gt;]
&lt;span class="n"&gt;build&lt;/span&gt;-&lt;span class="n"&gt;backend&lt;/span&gt; = &lt;span class="s2"&gt;"poetry.core.masonry.api"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you're pretty much set and ready to go 👍&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;So, hopefully that convinced you that why this setup is useful over the environment management setups.&lt;/p&gt;

&lt;p&gt;Hope you got something out of reading the article, and if so then do leave some feedback as this is my first article and I'm not really used to doing this :^]&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
