Full GUIDE: Path Module in Node.js

1. Introduction

The path module in node allows us to work with files and directories. Everything you can do with the command line (or a mouse) can be done with the path module.

This blog post aims to be the vest resource out there and includes my experience as a long time node developer. If you have some tips and tricks then please leave a comment!

It’s important to note that the path module is generally platform independent, not caring what flavour of linux, windows or Mac you’re on, although typically you’re probably running Centos / Ubuntu or some other server flavour of linux.

However, just because it’s generally platform independent doesn’t mean that you won’t have issues, especially around file access permissions! Typically the process running node also needs full access to the directories you’re working with. If you get errors then permissions is usually the culprit.

Another thing to be aware of is that some commands return default directory separators for that particular operating system. Eg double backslash (\\) in Windows or single forward slash in *nix (/). Where that’s the case you should probably use the following classes:

path.win32.[your_function] which gives you double backslash separators no matter the system OS.

path.posix.[your_function] which gives you single forward slash separators no matter the system OS.

For the remainder of this reference article we will assume you’re running on some flavour of Linux server and won’t be switching between the two. If you do have to support multiple environments then just be aware of the above.

2. Information from Directory or Path

A very common use case you’ll come across is to get certain pieces of information from a file or directory. Typically you’ll mostly want the file name. Let’s take a file location such as:

/var/www/html/data/private_diary.txt

It’s very common of the beginner to think “just split the string by the / character and take the last member of the array as the filename”. Yes, you can do this but some operating systems use backslash directory separators. That means more complex code and no guarantee your code will run on another OS.

Instead, node:path has this figured out already! You can use the following:

path.basename(path, [ext])

This method allows you to extract the filename from a path, eg:

path.basename(/var/www/html/data/private_diary.txt) => private_diary.txt

You can also tell path to remove the file extension but you have to know (or query) the file extension beforehand:

path.basename(/var/www/html/data/private_diary.txt, “.txt”) => private_diary

This extension removal function is case sensitive so be very careful. Normally that’s not an issue as most extensions are lower case but could be a gotcha in your case.

Personally, if I need the extension then I tend to use a string.split by period character. The last member of the array should be the extension (or if no file extension is present then there should only be one member in array, in which case there’s nothing to do). Alternatively you can use the extname method detailed later in this article.

path.dirname(path)

This method allows you to retrieve information about the path preceding the file name. Eg:

path.dirname(“/var/www/html/index.ts) => /var/www/html

NOTE: The final directory separator ( / ) is not included in the result!

path.extname(path)

This method retrieves the extension of the file (after a period character):

path.extname(/var/www/index.ts) => .ts

NOTE 1: This method returns the period as well! Result from this can be used as the second argument in the path.basename function to strip the filename extension.

NOTE 2: If there’s no extension then this will return an empty string, so you may want to check for that.

NOTE 3: If the file name has only a period without extension eg: “myfile.” then a single period “.” will be returned.

NOTE 4 (important): If the path starts with a period eg: “.myfile” then you will get a blank string returned (GOTCHA!).

I find you need to really validate results with this method to be sure you’re getting what you expect, especially if you have uncontrolled user inputs.

path.parse(path)

Takes a path and breaks it up into constituent components accessible as properties:

path.parse(‘/var/www/site/key.txt’) will output an object with properties:

{ root: ‘/’,
dir: ‘/var/www/site’,
base: ‘key.txt’,
ext: ‘.txt’,
name: ‘key’ }

I use this function quite often as it abstracts away all the issues around breaking down the constituent components of a path.

path.isAbsolute(path)

This method checks if the path passed in is absolute (by comparing it to the root of the filesystem), eg:

path.isAbsolute(‘/var/www/file.txt’) => true
path.isAbsolute(‘/www/file.txt’) => false

3. Manipulating and Creating Paths

path.join([…paths])

This method takes multiple paths and combines them into one path.

Despite the documentation syntax indicating an array you do not pass an array into the argument. Instead it expects a comma separated list of strings:

path.join(‘/foo’, ‘bar’, ‘baz/asdf’) => /foo/bar/baz/asdf

Note that if you include a delimiter ( / ) then the function will pick that up as a preconfigured path segment. Be very careful of adding posix command strings such as “..” which means to go back one level in the path, eg:

path.join(‘/foo’, ‘bar’, ‘..’) => /foo

For the above you might expect /foo/bar but addition of the “..” command makes it go back one directory!

path.resolve([…paths])

This method provides an absolute path from the paths passed in. If the first path does not include the path delimiter ( / ) then the current working directory will be added to the start of the resulting path. Eg, if your current directory is /home/user/:

path.resolve(“www”, “index.ts”) => /home/user/www/index.ts

However, note that the current working directory will not be added if you include the delimiter in the first argument:

path.resolve(“/www”, “index.ts”) => /www/index.ts

path.normalize(path)

This function trims any trailing slashes or period characters to clean up your path string, eg:

path.normalize(‘/var/www/../index.ts’) => /var/www/index.ts’

4. Bonus: Other Useful path Properties and Classes

path.sep

This property returns the current path separator depending on operating system ( \ or / )

path.win32

You can use all of the methods in this post but this class will return Windows specific versions of the results (even if you’re on another OS).

path.posix

You can use all of the methods in this post but this class will return Linux specific versions of the results (even if you’re on another OS).

5. Wrap Up

There are many useful methods in node:path but there are also many gotchas if you plan on running cross platform. If that is you then test, test, test to be sure the output you’re getting is what you need! Personally I have all my paths run through the posix class (section 4) so I have no issues with delimiters. Then all you need is to be sure of absolute directories as they are different on Windows / Nix / Other.

Finally, if you enjoy this post then one of these 2 posts might interest you:

Ultimate Guide to Async vs Sync in Javascript

Filesystem (fs) Promises in Node JS

Leave a Comment