Nodejs exposes various filesystem features, but not all filesystems share the same behaviors. Here are recommended guidelines to maintain simplicity and safety in your code when working with diverse filesystems.

Understanding Filesystem Behavior

Before interacting with a filesystem, it’s essential to comprehend its behavior. Different filesystems exhibit distinct characteristics such as case sensitivity, Unicode form handling, timestamp resolution, extended attributes, permissions, inodes, and more. Relying solely on process.platform to infer filesystem behavior is unwise. For instance, being on Darwin doesn’t guarantee a case-insensitive filesystem (HFS+) as the user might be on a case-sensitive one (HFSX).

Probing Filesystem Behavior

While the operating system might not readily provide filesystem behavior insights, there’s an alternative to maintaining an exhaustive filesystem list. You can probe certain easily detectable features that often indicate other more complex behaviors. This method helps infer the overall behavior of the filesystem.

Avoiding Lowest Common Denominator

Resist the temptation to normalize everything to a lowest common denominator, like uppercase filenames, NFC Unicode form, or simplified timestamp resolution. This approach restricts interaction to only the most basic filesystems. It impedes compatibility with advanced filesystems, leading to data loss, bugs, and complications when dealing with diverse filesystem attributes.

Adopting a Superset Approach

Enhance cross-platform compatibility by embracing a superset approach. For instance, a portable backup program should accurately sync btimes on Windows systems without affecting Unix permissions on Linux systems. Instead of downgrading capabilities to the lowest common denominator, aim to support an expansive feature set including case-sensitivity, Unicode form handling, permissions, and more.

Prioritizing Case and Unicode Form Preservation

When handling filenames and Unicode forms, prioritize preservation over normalization. If a filesystem retains case information, keep filenames as-is; if Unicode form is maintained, stick to the original form. Embrace normalization for comparison purposes, not as a means of altering data.

Dealing with Timestamp Resolution

Timestamp resolution varies across filesystems. While setting a precise timestamp might lead to unexpected results in certain systems, remember that normalization should only be used for comparison, not to modify data. Avoid corrupting filenames and timestamps through unnecessary normalization.

Applying Comparison Functions

Choose appropriate comparison functions based on the filesystem’s behavior. Avoid using case-insensitive comparisons on case-sensitive filesystems, and be cautious with Unicode form insensitivity. Adjust comparison functions to match the filesystem’s intricacies.

Accounting for Differences

Acknowledge minor discrepancies in comparison functions. Different filesystems might have nuanced variations even in supposedly standardized features like Unicode form handling.


In essence, your code should interact with diverse filesystems by embracing their capabilities rather than reducing everything to a common denominator. Prioritize preservation over normalization, employ appropriate comparison functions, and tailor your approach to each filesystem’s unique behavior. This strategy ensures better compatibility and data integrity across various platforms.

✨ Thank you for reading and I hope you find it helpful. I sincerely request for your feedback in the comment’s section.