For this week, I have been reading unbuild source code and found few packages that I have never seen before or used. I wanted to share some interesting packages that are used in these OSS projects so we can learn a thing or two ;)
Jiti is a package built by authors at Unjs. Unjs provides JS tools, libraries and has about 63 npm packages and 421m downloads per month. Sheesh, that’s a lot.
Jiti repository has this description “Runtime TypeScript and ESM support for Node.js”. Okay, what does this mean? To understand more about this tool, I looked at the features it offers:
Seamless TypeScript and ESM syntax support for Node.js
Seamless interoperability between ESM and CommonJS
Asynchronous API to replace import()
Synchronous API to replace require() (deprecated)
Super slim and zero dependency
Custom resolve aliases
Smart syntax detection to avoid extra transforms
Node.js native require.cache integration
Filesystem transpile with hard disk caches
ESM Loader support
JSX support (opt-in)
Sure enough, it has features that I do not understand yet, the one feature that rings a bell for me is the Seamless interoperability between ESM and CommonJS because I have seen this in dynamic imports in OSS projects where a file is defined using CommonJS (module.exports) required in an file using ESM syntax (export default) but still not sure if what I saw back then has any resemblance to what Jiti offers. I am interested to learn more about this package, may be in the future.
But let’s review Jiti’s usage in Open Source projects such as Docusaurus and Unbuild
import jiti from 'jiti';/*jiti is able to load ESM, CJS, JSON, TS modules */export async function loadFreshModule(modulePath: string): Promise<unknown> { try { if (typeof modulePath !== 'string') { throw new Error( logger.interpolate`Invalid module path of type name=${modulePath}`, ); } const load = jiti(__filename, { // Transpilation cache, can be safely enabled cache: true, // Bypass Node.js runtime require cache // Same as "import-fresh" package we used previously requireCache: false, // Only take into consideration the default export // For now we don't need named exports // This also helps normalize return value for both CJS/ESM/TS modules interopDefault: true, // debug: true, }); return load(modulePath);
Let’s get the hint from the comments — “jiti is able to load ESM, CJS, JSON, TS modules”, this would be the interoperability feature. jiti is imported and directly called as a function with some parameters for additional configuration and it has comments explaining what the configuration is for.
// Transpilation cache, can be safely enabledcache: true,// Bypass Node.js runtime require cache// Same as "import-fresh" package we used previouslyrequireCache: false,// Only take into consideration the default export// For now we don't need named exports// This also helps normalize return value for both CJS/ESM/TS modulesinteropDefault: true,// debug: true,
Docusaurus v3 changes its internal config loading library from import-fresh to jiti. It is responsible for loading files such as docusaurus.config.js or sidebars.js, and Docusaurus plugins.
:::info How to upgrade
In theory, you have nothing to do, and your existing config files should keep working as before.
However, this is a major dependency swap and subtle behavior changes could occur.
Hey, my name is Ramu Narasinga. I study large open-source projects and create content about their codebase architecture and best practices, sharing it through articles, videos.