Relative path handling fails for one reason more than any other: code assumes the same base path in every runtime.

If you searched for , , or , this guide gives you stable patterns by environment.

Quick answer

  • Use in CommonJS.
  • Use in ESM.
  • Use for module-relative assets.
  • Avoid using for module-local files unless you explicitly want CLI working-directory semantics.

1) CommonJS in Node.js

Use for files relative to the current module.

When to use: legacy Node projects or codebases still on CJS.

2) ESM in Node.js

is not available natively in ESM. Use .

For simple asset references:

3) Browser modules

In browsers, there is no filesystem path API. Use URLs relative to the module/document.

For script tags:

Resolution is URL-based, not filesystem-based.

4) Deno

Deno uses ESM semantics by default, so is the standard pattern.

5) Bundlers (Vite/Webpack/Parcel)

Bundlers usually rewrite import paths at build time. Prefer module imports over manual string assembly:

When you need dynamic resolution, verify your bundler’s support for .

vs module-relative paths

This distinction prevents many production bugs:

APIBaseBest use
/ current fileloading module-owned assets
launch directoryCLI tools and repo-root workflows

If a test runs from a different directory than local development, assumptions often break first.

Common path-resolution mistakes

1. Mixing URL and filesystem APIs incorrectly

Use when converting to a filesystem path in Node.

2. Building paths with string concatenation

Use (filesystem) or (URL contexts) to avoid separator bugs.

3. Assuming bundler behavior in server runtime

Code that works in Vite/Webpack can fail in plain Node runtime if path transforms are missing.

Reliability pattern for service teams

When JavaScript services process async email or webhook payloads, path bugs often appear in template loading, fixture files, or attachment handling.

Use this guardrail set:

  • keep module-local assets resolved from module location, not working directory
  • run integration assertions against real message flows in Email Sandbox
  • add environment-consistent checks in Email Integration Testing
  • validate async payload behavior with Email Webhooks

Final take

Path resolution is not one universal trick. It is runtime-specific. Choose one base-path model per context, document it, and enforce it in tests so local, CI, and production behave the same way.