Most programming languages have built-in support for manipulating path. For example, Node.js has path module, C# has Path class. But the semantics of them are not necessary the same, sometimes causing confusion for programmers used to one certain programming language.

Node.js path.join() vs. C# Path.Combine() on Windows

Node.js path.join(): Backslash after drive specifier is optional.

> path.win32.join('C:', 'file.txt')
> path.win32.join('C:\\', 'file.txt')

C# Path.Combine(): Backslash after drive specifier is required.

> Path.Combine("C:", "file.txt")
> Path.Combine("C:\\", "file.txt")

Node.js path.join(): The second and following parameters (counting from 1) are always relative.

> path.win32.join('C:\\x', 'y')
> path.win32.join('C:\\x', '\\y')
> path.win32.join('C:\\x', 'y', '\\z')

C# Path.Combine(): All parameters can be absolute or relative.

> Path.Combine("C:\\x", "y")
> Path.Combine("C:\\x", "\\y")
> Path.Combine("C:\\x", "y", "\\z")

Node.js path.join(): Resulting path is normalized.

> path.win32.join('a', '.\\b')
> path.win32.join('a', '..\\b')
> path.win32.join('a', '..\\..\\b')

C# Path.Combine(): Resulting path is not normalized.

> Path.Combine("a", ".\\b")
> Path.Combine("a", "..\\b")
> Path.Combine("a", "..\\..\\b")

Node.js path.join(): Forward slash and backslash are all normalized to backslash.

> path.win32.join('a/b', 'c\\d')

C# Path.Combine(): Forward slash and backslash are left as is.

> Path.Combine("a/b", "c\\d")

Node.js path.join(): Zero-length resulting path is returned as . (representing the current working directory).

> path.win32.join('', '')

C# Path.Combine(): Zero-length resulting path is returned as is.

> Path.Combine("", "")