path.resolve vs path.join
nuance of path construction.
join concatenates and normalizes relative segments, resolve builds an absolute path right to left from cwd and resets on any absolute segment.
treating them as interchangeable.
What's really being asked
This probes subtle but important differences between two heavily used path functions. Misusing them causes files to be read from the wrong directory, a classic source of works-on-my-machine bugs.
The full answer
path.join takes the given segments, joins them with the platform separator, and normalizes the result, collapsing redundant slashes and resolving . and .. segments. If all inputs are relative, the output stays relative. path.resolve instead computes an absolute path. It processes arguments from right to left, prepending segments until it has an absolute path, defaulting to the process current working directory if none of the inputs are absolute. Crucially, if any segment is itself an absolute path, resolve discards everything to its left and restarts from that segment. So resolve is about producing a definitive absolute location, while join is about stitching fragments together.
The mistakes people make
Saying both always return identical strings. Claiming join also consults the current working directory, which it does not. Forgetting that an absolute segment resets resolve's accumulation.
What usually comes next
What does path.normalize do compared to these. When is __dirname preferable to relying on cwd. How does an absolute segment behave inside join.
A concrete example
Given inputs '/foo', 'bar', '/baz', 'qux': path.join('/foo', 'bar', '/baz', 'qux') returns '/foo/bar/baz/qux', simply concatenating and normalizing. path.resolve('/foo', 'bar', '/baz', 'qux') returns '/baz/qux', because the later absolute segment /baz discards the earlier /foo/bar. This divergence is exactly why you cannot treat the two as interchangeable.
Interview question
Given path.resolve('/foo', 'bar', '/baz', 'qux'), what is returned and why?
- a.qux because resolve uses only the last segment
- b./foo/bar/baz/qux because resolve concatenates like join
- c./foo/bar/qux because /baz is treated as a filename
- d./baz/qux because an absolute segment discards everything to its leftCorrect
Why? this is the answer
resolve processes right to left and a leading-slash segment resets the path, so /baz/qux results. join would keep /foo/bar/baz/qux; resolve does not simply concatenate or use only the last segment.
Just read this? Test yourself on what you have been reading.
Read the original → nodejs.org
- #nodejs
- #path
- #filesystem
- #core-modules
- #normalization
Put your scrolling time to good use
Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on nodejs — each one lists the topics its interview covers.
See open roles