Isomorphic.js Utilities
Isomorphic.js is a utility library providing a consistent API for platform-specific JavaScript features, with a strong focus on cryptographic operations like `randomBytes`, `encrypt`, and `decrypt`. It also offers environment detection utilities such as `isBrowser` and `isNode`. Currently at version `0.2.5`, the package receives infrequent, maintenance-oriented updates, primarily for dependency bumps. Its key differentiator is abstracting away the complexities of disparate browser and Node.js environments, offering polyfills where native APIs are unavailable, thereby enabling truly isomorphic code execution without explicit runtime checks for common tasks, particularly in security-sensitive areas. It relies on `yjs` for some environment detection logic, simplifying cross-platform development.
Common errors
-
TypeError: Cannot read properties of undefined (reading 'isBrowser') or TypeError: Cannot read properties of null (reading 'isBrowser')
cause The internal `yjs` dependency, which provides environment detection functions like `isBrowser` and `isNode`, failed to load or initialize correctly.fixEnsure `yjs` is correctly installed as a direct dependency (`npm install yjs` or `yarn add yjs`). Check for any module resolution issues if you're using a custom build setup. -
Error: require() of ES Module CJS_MODULE from CommonJS module JS_FILE not supported. Did you mean to import CJS_MODULE?
cause Attempting to `require()` an ESM-only package or a package that has explicit `exports` that prevent CJS `require` paths, particularly relevant after v0.2.0 and v0.2.3.fixSwitch to ESM import syntax: `import { functionName } from 'isomorphic.js';`. Ensure your project is configured for ESM (e.g., `"type": "module"` in `package.json` or using `.mjs` files). -
TypeError: isomorphic.randomBytes is not a function
cause Incorrectly importing the `randomBytes` function, possibly through a default import or a CommonJS `require` that doesn't destructure correctly.fixUse a named ESM import: `import { randomBytes } from 'isomorphic.js';` or for CommonJS: `const { randomBytes } = require('isomorphic.js');`.
Warnings
- breaking Version 0.2.0 introduced 'conditional exports' via `package.json` `exports` field. This can cause issues with older build tools or Node.js versions that do not fully support this feature, potentially leading to import resolution errors.
- breaking Version 0.2.3 further refined module resolution by adding the `module` field and additional `exports` configurations. While improving ESM compatibility, this could alter resolution paths for some CJS consumers, especially when coupled with specific bundler configurations.
- gotcha The library has a direct runtime dependency on `yjs`. If `yjs` is not correctly installed or resolvable in your environment, `isomorphic.js` will fail to load or execute correctly, particularly for environment detection features like `isBrowser` and `isNode`.
- gotcha The `encrypt` and `decrypt` functions, while provided for isomorphic crypto, are highly simplified in their public API. For production use, you must implement robust key management, secure random IV generation, and potentially authenticated encryption modes (e.g., AES-GCM) beyond what these functions might directly abstract. The example provided uses a dummy key.
Install
-
npm install isomorphic.js -
yarn add isomorphic.js -
pnpm add isomorphic.js
Imports
- randomBytes
const randomBytes = require('isomorphic.js').randomBytes;import { randomBytes } from 'isomorphic.js'; - isBrowser
import isomorphic from 'isomorphic.js'; const isBrowser = isomorphic.isBrowser;
import { isBrowser, isNode } from 'isomorphic.js'; - encrypt
const { encrypt } = require('isomorphic.js/lib');import { encrypt, decrypt } from 'isomorphic.js';
Quickstart
import { isBrowser, isNode, randomBytes, encrypt, decrypt } from 'isomorphic.js';
async function runIsomorphicExample() {
if (isBrowser) {
console.log('Running in a browser environment.');
} else if (isNode) {
console.log('Running in a Node.js environment.');
} else {
console.log('Running in an unknown environment.');
}
// Generate 16 random bytes
const randomBuffer = randomBytes(16);
console.log('Generated random bytes:', randomBuffer.toString('hex'));
// Example of cryptographic operations (using a dummy key for demonstration)
const key = await decrypt(Buffer.from('dummy-key-for-test', 'utf-8'), Buffer.from('')); // Key must be derived or generated securely
const dataToEncrypt = Buffer.from('Hello, Isomorphic World!');
try {
// Note: `encrypt` and `decrypt` require proper key management and IVs for real-world use.
// This example is simplified and might not run without a valid crypto key setup.
const encryptedData = await encrypt(dataToEncrypt, key);
console.log('Encrypted data (truncated):', encryptedData.toString('hex').substring(0, 30) + '...');
const decryptedData = await decrypt(encryptedData, key);
console.log('Decrypted data:', decryptedData.toString());
} catch (error) {
console.warn('Could not perform encryption/decryption. Ensure a valid crypto key and IV setup:', error.message);
}
}
runIsomorphicExample().catch(console.error);