parcel-bundler/parcel · critical · Error

NodeFS isn't available in the browser

Error message

NodeFS isn't available in the browser

What it means

Thrown unconditionally in the constructor of NodeFS when the browser-specific build is loaded. Parcel ships two implementations of NodeFS: one for Node.js (using the real fs module) and one for browsers (NodeFS.browser.js) that throws immediately. This is a compile-time replacement via Parcel's bundler aliases, not a runtime check.

Source

Thrown at packages/core/fs/src/NodeFS.browser.js:7

// @flow
import type {FileSystem} from '@parcel/types-internal';

// $FlowFixMe[prop-missing] handled by the throwing constructor
export class NodeFS implements FileSystem {
  constructor() {
    throw new Error("NodeFS isn't available in the browser");
  }
}

View on GitHub (pinned to 59484858a1)

Solutions

  1. Ensure NodeFS is only imported in Node.js contexts — use conditional imports or dynamic imports gated by `typeof window === 'undefined'`.
  2. Use MemoryFS or OverlayFS for browser-side virtual filesystem operations instead of NodeFS.
  3. If using a bundler, mark NodeFS as external or provide a browser stub that doesn't throw.

Example fix

// before
import {NodeFS} from '@parcel/fs';
const fs = new NodeFS(); // throws in browser

// after
import {MemoryFS} from '@parcel/fs';
// or use conditional dynamic import:
// const {NodeFS} = typeof window === 'undefined' ? require('@parcel/fs') : {NodeFS: null};
Defensive patterns

Strategy: validation

Validate before calling

// Prevent NodeFS instantiation in browser environments
function createFS() {
  if (typeof window !== 'undefined' || typeof process === 'undefined') {
    // Browser environment — use MemoryFS
    const {MemoryFS} = require('@parcel/fs');
    return new MemoryFS();
  }
  const {NodeFS} = require('@parcel/fs');
  return new NodeFS();
}

Type guard

// Environment guard
function isBrowser() {
  return typeof window !== 'undefined' ||
    (typeof process !== 'undefined' && process.type === 'renderer') ||
    typeof navigator !== 'undefined' && navigator.userAgent.includes('node') === false;
}

Try / catch

try {
  const fs = new NodeFS();
} catch (e) {
  if (e.message.includes("isn't available in the browser")) {
    const {MemoryFS} = require('@parcel/fs');
    fs = new MemoryFS();
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Any code path that instantiates `new NodeFS()` in a browser environment. This happens when a library or Parcel internal module that imports NodeFS is bundled for the browser without proper tree-shaking or conditional loading. The import resolves to NodeFS.browser.js via the module resolver.

Common situations: A Parcel plugin is imported into a browser-side preview or playground that doesn't guard the NodeFS import. A test runner configured for jsdom (browser-like) tries to exercise code that depends on NodeFS. A custom bundler config accidentally includes server-only modules in a browser bundle.

Related errors


AI-assisted analysis of parcel-bundler/parcel@59484858a1 (2026-08-13). Data as JSON: /api/errors/ce967d834c007c2e. Report an issue: GitHub.