path.sep
Provides the platform-specific path segment separator, '/' or a backslash.
path.sep- Added in Node.js v0.7.9
Return value
stringThe platform-specific path segment separator: '\' on Windows and '/' on POSIX.
path.sep is the character that separates directory names on the current platform: '/' on POSIX, a single backslash on Windows. It is always one character long. path.posix.sep and path.win32.sep give the other platform's value when you need it explicitly.
When to reach for it
Its real use is taking paths apart, not putting them together. Splitting a path into segments, counting nesting depth, testing whether a string ends in a separator, or writing a regular expression that must match either separator — those are jobs for path.sep.
What trips people up
Building paths by joining strings with path.sep is a common but weaker habit than it looks. parts.join(path.sep) produces the same characters as path.join(...parts), but skips normalization: empty segments leave double separators and '..' segments are never collapsed. Use path.join() for construction.
Splitting is also asymmetric on Windows, where '/' is accepted as a separator on input even though only '\' is ever produced. A Windows path containing forward slashes will not split correctly on path.sep alone — run it through path.normalize() first, or split on /[\\/]/.
In a regular expression the Windows value must be escaped, since a lone backslash is not a valid pattern.
Example
When to use it
- Splitting a path into its individual segments to inspect or filter them
- Measuring how deeply nested a path is by counting separators
- Detecting whether a string already ends with a separator before appending
Frequently asked questions
What is path.sep in Node.js?
It is the platform's directory separator character: '/' on POSIX systems and a single backslash on Windows. Use path.posix.sep or path.win32.sep to get a specific platform's value regardless of where the code is running.
Should I use path.sep to build paths?
No, use path.join() instead. Joining segments with path.sep produces the right characters but skips normalization, so empty segments leave double separators and '..' segments are never collapsed. path.sep is for splitting paths and inspecting them.
How do I split a path into its parts?
Use p.split(path.sep) after normalizing, or split on the regular expression /[\\/]+/ to handle either separator. The normalization step matters on Windows, where forward slashes are accepted on input but path.sep is only the backslash.
More examples
Joining with sep is not the same as path.join()
The manual version keeps the double separator produced by the empty string and never collapses the '..'. path.join() does both, which is why it is the correct tool for building paths and path.sep is the tool for reading them.
const path = require('node:path');
const parts = ['srv', '', 'app', '..', 'public'];
console.log('manual join:', JSON.stringify(parts.join(path.sep)));
// -> "srv//app/../public" empty segment and '..' both survive
console.log('path.join: ', JSON.stringify(path.join(...parts)));
// -> "srv/public" normalizedSplitting a path safely across platforms
Windows accepts both separators on input but path.sep is only the backslash, so the naive split leaves 'srv/app' as one segment. Normalizing first converts everything to backslashes; the regex approach handles either style without a normalization pass.
const path = require('node:path');
const mixed = 'C:\\srv/app\\public';
console.log('naive win32 split:', mixed.split(path.win32.sep));
// forward slash is NOT split on
console.log('after normalize: ', path.win32.normalize(mixed).split(path.win32.sep));
console.log('regex split: ', mixed.split(/[\\/]+/));Detecting a trailing separator
The output shows the split personality of trailing separators: normalize() preserves them while resolve() removes them. Testing with endsWith(path.sep) is the portable way to check before you append another segment by hand.
const path = require('node:path');
const fs = require('node:fs');
fs.mkdirSync('sep-demo', { recursive: true });
fs.writeFileSync(path.join('sep-demo', 'a.txt'), '');
const asDir = 'sep-demo' + path.sep;
console.log('ends with sep:', asDir.endsWith(path.sep));
console.log('normalize keeps it:', JSON.stringify(path.normalize(asDir)));
console.log('resolve strips it: ', path.relative(process.cwd(), path.resolve(asDir)));
fs.rmSync('sep-demo', { recursive: true, force: true });
console.log('cleaned up:', fs.existsSync('sep-demo'));
Discussion