Case Sensitivity with `localeCompare` in JavaScript

I recently ran into a bug using code like the following:

someArray.sort((a, b) =>

At a glance this seems fine—localCompare enjoys fantastic browser support, and as the name suggests, it isn’t English-centric. However, this is still the web we’re building for, and the familiar gotcha of inconsistent behavior amongst browsers is lurking here. This can lead to hard-to-debug inconsistencies and bugs.

Most browsers—including Chrome, Edge, and Firefox—and Node treat localeCompare as case-insensitive by default, treating an uppercase “A” as the same as a lowercase “a”. Safari, however, does something different.

Safari uses a variant of case-sensitive sorting, but not in the usual ASCII order where “Z” sorts above “a”. Instead Safari sorts lowercase letters above their uppercase companions, but in alphabetical order otherwise, like “aAbBcC”.

In many cases this is fine—sorting based on the user’s locale is not only acceptable, it’s preferable. But that’s not always true, particularly in scenarios where data is expected to match the order from a server, such as when sorting properties before hashing for verification or as a checksum, or when hydrating server-side rendered React. In these cases, consistent behavior across environments is important and can be achieved by specifying a few additional options to localeCompare:, "en", { sensitivity: "base" })

The sensitivity: "base" option tells browsers to use the base character for comparison (MDN), effectively making the comparison case-insensitive. This results in consistent sorting behavior across Node and all common browsers (including IE11).


Now read this

Fixing Homebrew Postgres Installation on macOS Catalina

I recently upgraded to macOS Catalina and needed to reinstall PostgreSQL via Homebrew. The usual process is simple enough: brew install postgresql does the bulk of the work, and then running brew services start postgres would normally... Continue →