Introducing Jopi Node Space
Jopi Node Space makes it simple to write libraries for both the browser and the server, with extra functionalities for server-side.
The problem of incompatibility
I regularly encounter a problem when writing a code library that needs to work in the browser, with Node.js, and with Bun.js: small incompatibilities. For example, handling WebWorkers, or simply calling unref
on a timer. There are many little things that force us to write if (isBrowser) {}
if (isNodeJs) {}
if (isBunJs) {}
.
Avoiding these annoying aspects was the first motivation that led me to create the Jopi Node Space library. Thanks to this library, my code is simpler, because it exposes functions that internally handle the differences between these three runtime platforms.
The problem with "import"
The first version of Jopi Logs was made up of three libraries:
- jopi-logs which was the common core.
- jopi-logs-nodejs which added server functionalities.
- jopi-logs-bunjs which adapted the server part for Bun.js.
Why three libraries? Mainly because I can't have this in the jopi-logs library:
import * as fs from "node:fs";
Writing this causes a big problem with the bundler (ViteJS), which tries to include the entire node:fs library in the browser code. And obviously, that doesn't work!
I solved this problem by taking inspiration from what Bun.js and Deno.js do.
The following example shows how to read a file with Bun.js:
const path = "/path/to/package.json";
// 'Bun' exists globally.
const file = Bun.file(path);
const contents = await file.json();
Now here is the same with Node.js:
import { readFile } from 'fs/promises';
const contents = JSON.parse(await readFile(filePath, 'utf8'));
The big difference between the two is the import
: with Bun.js, there is no import to do, so I can mix browser and server code in the same library without compilation problems. I just need to check if I'm on the browser or server side.
Conclusion
So these are the two problems that led to the creation of Jopi Node Space: smoothing out the differences between JavaScript engines, and being able to have a single code library for both browser and server.
Thanks to Jopi Node Space, my code has become more readable and easier to maintain. That's why I'm currently refactoring my existing codebase to rely on Jopi Node Space.
I also found it interesting to add utility features to Jopi Node Space, things that are recurring needs in most of my projects:
- Write in red/blue/green in the console.
- Execute actions when the application exits.
- Manage "hot-reload" (a feature specific to bun.js). See link.