{"id":11145,"library":"jiti","title":"Jiti: TypeScript and ESM Runtime for Node.js","description":"Jiti is a robust utility for Node.js that provides seamless runtime support for both TypeScript and ECMAScript Modules (ESM), along with comprehensive interoperability between ESM and CommonJS. The package is currently at version 2.6.1 and maintains a high release cadence with frequent minor version bumps and patch fixes, indicating active and continuous development. Its key differentiators include a 'zero dependency' footprint, significant performance optimizations (e.g., improved startup times from v2.6.0 onwards), and widespread adoption within prominent projects such as Nuxt, TailwindCSS, ESLint, and Storybook. Jiti offers both an asynchronous (`jiti.import`) and a synchronously (now deprecated `jiti()`) API, alongside a global ESM loader for Node.js versions 20 and above. It simplifies the execution of complex JavaScript ecosystems by handling various module formats and language extensions without requiring explicit build steps.","status":"active","version":"2.6.1","language":"javascript","source_language":"en","source_url":"https://github.com/unjs/jiti","tags":["javascript","typescript"],"install":[{"cmd":"npm install jiti","lang":"bash","label":"npm"},{"cmd":"yarn add jiti","lang":"bash","label":"yarn"},{"cmd":"pnpm add jiti","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"While CommonJS `require` can be used, modern Jiti usage, especially for new projects, prefers ESM `import` with `import.meta.url` for context, aligning with the deprecation of `createJiti(__filename)` in the docs.","wrong":"const { createJiti } = require('jiti');","symbol":"createJiti","correct":"import { createJiti } from 'jiti';"},{"note":"This is a side-effect import used to globally register Jiti's ESM loader hook. It requires Node.js version 20 or higher for full compatibility.","wrong":"require('jiti/register');","symbol":"jiti/register","correct":"import 'jiti/register';"},{"note":"Used for type-checking instances of the Jiti function when working in TypeScript projects.","symbol":"Jiti (type)","correct":"import type { Jiti } from 'jiti';"}],"quickstart":{"code":"import { createJiti } from \"jiti\";\nimport path from \"node:path\";\nimport fs from \"node:fs/promises\";\n\n// Initialize jiti, specifying the current module's URL for resolution context.\n// In a CommonJS environment, use `__filename` instead of `import.meta.url`.\nconst jiti = createJiti(import.meta.url, {\n  debug: process.env.NODE_ENV === 'development',\n  // Cache directory to speed up subsequent loads\n  cacheDir: path.join(process.cwd(), '.jiti-cache'),\n});\n\n// Example of importing a TypeScript file with ESM compatibility\n// For demonstration, we'll create a dummy TS file first.\nasync function runJitiExample() {\n  const dummyTsPath = path.join(__dirname, 'temp-module.ts');\n  const dummyTsContent = 'export const message = \"Hello from Jiti!\"; export default { status: \"OK\" };';\n  await fs.writeFile(dummyTsPath, dummyTsContent);\n\n  try {\n    // Import the module. Jiti handles TypeScript transpilation.\n    // Use a generic type to ensure strong typing for the imported module.\n    const mod = await jiti.import<{ message: string; default: { status: string } }>(dummyTsPath);\n    console.log(\"Named export 'message':\", mod.message);\n\n    // To directly get the default export (common for default-export-only modules)\n    const modDefault = await jiti.import<{ status: string }>(dummyTsPath, { default: true });\n    console.log(\"Default export 'status':\", modDefault.status);\n\n    // Jiti can also resolve paths using ESM resolution logic.\n    const resolvedPath = jiti.esmResolve('./temp-module.ts');\n    console.log(\"Resolved path for temp-module.ts:\", resolvedPath);\n  } catch (error) {\n    console.error(\"Error running Jiti example:\", error);\n  } finally {\n    // Clean up the temporary file.\n    await fs.unlink(dummyTsPath);\n  }\n}\n\nrunJitiExample();","lang":"typescript","description":"Demonstrates how to initialize Jiti for runtime TypeScript and ESM support, dynamically import a module, access both named and default exports, and resolve paths programmatically, including creating and cleaning up a temporary module for a runnable example."},"warnings":[{"fix":"Thoroughly test module imports and exports after upgrading. If issues persist, consider reporting them on the Jiti GitHub repository for investigation.","message":"Jiti versions `>=2.1` introduced an enhanced `interopDefault` mechanism using a new Proxy method. This change, while improving compatibility, might cause subtle behavior differences or issues for existing applications. If you migrated from `1.x` or `2.0.0` to `>=2.1` and encounter unexpected behavior, please review module interop logic.","severity":"breaking","affected_versions":">=2.1"},{"fix":"Refactor synchronous `jiti(id)` calls to `await jiti.import(id)` and ensure your code handles promises appropriately.","message":"The synchronous `jiti()` API (used like `jiti('./path/to/file.ts')`) is considered deprecated. It is recommended to migrate to the asynchronous `jiti.import()` API for new code to better align with modern JavaScript module loading patterns and avoid potential blocking operations.","severity":"deprecated","affected_versions":">=2.0.0"},{"fix":"Ensure your Node.js environment is version 20 or newer when relying on the global ESM loader. For older Node.js versions, use `createJiti` programmatically.","message":"Using `jiti/register` for a global ESM loader hook requires Node.js version 20 or higher for full and stable compatibility.","severity":"gotcha","affected_versions":"<20.0.0"},{"fix":"For new projects, prefer setting up your project as ESM and using `import.meta.url`. If you must use CommonJS, be aware that `__filename` context might receive less future-focused support.","message":"When initializing `createJiti` in a CommonJS context, the documentation marks `createJiti(__filename)` as a 'deprecated' pattern, steering users towards ESM `import { createJiti } from 'jiti'; const jiti = createJiti(import.meta.url);` as the preferred modern approach.","severity":"gotcha","affected_versions":">=2.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"If using Jiti, ensure it's initialized and use `await jiti.import('./path/to/esm-module.mjs')`. Alternatively, enable Jiti's global loader with `node --import jiti/register`.","cause":"Attempting to use Node.js `require()` to load an ES Module (with `.mjs` or `type: module` in `package.json`) without Jiti's interop layer or proper Node.js ESM configuration.","error":"Error [ERR_REQUIRE_ESM]: require() of ES Module ... not supported. Instead change the require of ... to a dynamic import()"},{"fix":"Execute the file using `npx jiti ./your-script.ts` or `node --import jiti/register ./your-script.ts`. If programmatic, ensure `createJiti` is correctly initialized.","cause":"Running a TypeScript or ES Module file directly with `node` without Jiti's runtime transpilation or a configured Node.js ESM environment.","error":"SyntaxError: Cannot use import statement outside a module"},{"fix":"Use `const mod = await jiti.import(id); console.log(mod?.default ?? mod);` or leverage the shorthand `const modDefault = await jiti.import(id, { default: true });` for direct default export access.","cause":"Incorrectly accessing the `default` export of a module. Some modules might not have a `default` export, or the module itself is the default export.","error":"TypeError: module.default is not a function/object (or: undefined is not an object)"}],"ecosystem":"npm"}