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:
| API | Base | Best use |
|---|---|---|
/ | current file | loading module-owned assets |
| launch directory | CLI 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.