Meteor Node Stubs
meteor-node-stubs provides browser-compatible stub implementations for Node.js built-in modules (e.g., `path`, `buffer`, `process`, `crypto`). It enables NPM packages, even those initially for Node.js, to run within Meteor client-side applications by transparently redirecting imports to these browser-friendly stubs, requiring no manual configuration. The current stable version is 1.2.27, with releases tied to the broader Meteor ecosystem's update cycle for security and compatibility, including Meteor 3.x. Its key differentiator is automatic integration with Meteor's build process, minimizing client bundle bloat by only including necessary stubs.
Common errors
-
Uncaught Error: Cannot find module 'path' (or 'os', 'util', etc.)
cause A Node.js built-in module is imported on the client, but `meteor-node-stubs` is missing, an outdated version, or the Meteor build system isn't correctly processing the stub.fixEnsure `meteor-node-stubs` is installed (`meteor npm install --save meteor-node-stubs`) and updated to the latest compatible version (`meteor npm update meteor-node-stubs`). For older Meteor versions, check the Meteor Guide for specific installation instructions. -
Uncaught ReferenceError: process is not defined
cause The global `process` object, normally provided by Node.js or `meteor-node-stubs` in the browser, is not available, indicating a failure in the stubbing mechanism for the `process` module.fixVerify `meteor-node-stubs` is correctly installed and that your Meteor app is bundling it for the client. If using Meteor 3.x with Rspack, ensure Rspack's polyfilling for `process` is active. -
TypeError: fs.readFile is not a function
cause Attempting to use a function or feature of a Node.js built-in module (`fs` in this case) that is either not implemented or only partially implemented by its browser stub. `meteor-node-stubs` provides minimal browser compatibility, not a full Node.js environment.fixRefactor client-side code to avoid Node.js-specific APIs that lack full browser equivalents. For critical functionality, consider finding a browser-native alternative or a dedicated browser polyfill package. -
npm ERR! path /path/to/project/node_modules/meteor-node-stubs ... EPERM: operation not permitted
cause File permission issues during `npm install` or `npm update`, preventing installation or modification of files within the `meteor-node-stubs` package.fixTry running `meteor npm cache clean --force`, then remove the `node_modules` directory (`rm -rf node_modules`) and `package-lock.json` file. Reinstall dependencies with `meteor npm install`. If permissions persist, check your user's file system permissions for the project directory.
Warnings
- breaking A critical security vulnerability in `crypto-browserify` (a sub-dependency) led to an urgent update of `meteor-node-stubs` (e.g., to version `1.2.8` in April 2024). This update involved forking the vulnerable dependency and caused breaking changes for some users attempting to `import 'path'` or `import 'os'` in client-side code.
- gotcha This package provides *stubs* or browser-compatible implementations for Node.js built-in modules, not full Node.js functionality. Developers must not assume complete Node.js API parity on the client. Many functions may be limited, no-ops, or throw errors (e.g., `fs.readFile` will not work in the browser).
- gotcha Client-side imports of Node.js modules, even if stubbed, can significantly increase the client-side bundle size, particularly for modules with large browser polyfills (e.g., `crypto` can add 630KB to the bundle).
- deprecated The official GitHub repository for `meteor-node-stubs` (meteor/node-stubs) is archived and set to read-only, directing users to the main Meteor repository for current code. While the package itself is actively maintained, relying on the archived repository for issues or pull requests is no longer possible.
- breaking With Meteor 3.x's adoption of Rspack as the default bundler, there are ongoing discussions regarding the future role of `meteor-node-stubs`. Rspack has its own polyfill handling for some Node built-ins, which might lead to `meteor-node-stubs` being optional or removed as a default dependency in future Meteor versions (e.g., 3.4+). This could require manual addition for specific needs.
Install
-
npm install meteor-node-stubs -
yarn add meteor-node-stubs -
pnpm add meteor-node-stubs
Imports
- path
import { join } from 'meteor-node-stubs/path';import { join } from 'path'; - process
import process from 'process';
console.log(process.env.NODE_ENV);
- Buffer
import { Buffer } from 'meteor-node-stubs/buffer';import { Buffer } from 'buffer';
Quickstart
import { Meteor } from 'meteor/meteor';
import { basename, extname } from 'path'; // Importing Node.js 'path' module
if (Meteor.isClient) {
Meteor.startup(() => {
// This code runs only on the client (browser)
const filePath = '/home/user/document.txt';
const baseName = basename(filePath);
const extension = extname(filePath);
console.log(`Original Path: ${filePath}`);
console.log(`Base Name: ${baseName}`);
console.log(`File Extension: ${extension}`);
// Demonstrate another common stub, 'process'
// process.env is stubbed for browser compatibility
console.log(`Environment (from stubbed process): ${process.env.NODE_ENV ?? 'development'}`);
console.log(`Is browser? (from stubbed process): ${process.browser ?? true}`);
// Example of a function that might not be fully stubbed or is a no-op
try {
// The 'fs' module is typically not fully implemented in browser stubs.
// Attempting to use server-side filesystem operations will fail.
// import * as fs from 'fs'; // If actually imported, would be at top
// fs.readFile('/some/file.txt', () => {});
console.log("Attempted to use fs (may not work as expected in browser stubs).");
} catch (e) {
console.warn("fs module is likely not fully implemented in browser stubs:", e.message);
}
});
}