Inspiration

Generating unique identifiers is a common requirement in modern software. Anything from database management systems (unique IDs for records), to applications that generate unique URLs (think links to builds in CircleCI/GitHub actions or deploy previews in Netlify), to authorization tokens for API requests need unique identifiers.

Currently, the "standard" to generate these identifiers is using UUID v4. However, for modern web applications (aka JavaScript-based apps), we can do better. Nano ID is a tiny, secure, URL-friendly, unique string ID generator that is small (by dependency size), cryptographically safe, faster than UUID (by ~16%), and compact (i.e. is uses a larger alphabet so the ID size was reduced from 36 to 21 symbols).

The original implementation of Nano ID was in JavaScript, but the library has since been ported to many other languages like Go, Rust, Python, and more. However, no Nano ID implementation currently exists for Reason, a JavaScript-like syntax for OCaml that many say is the future of web development; hence, our project: re-nanoid!

What it does

re-nanoid is a rewrite of the popular Nano ID library in Reason. Since Reason can be written in two different ways: (1) by using BuckleScript to compile to JavaScript and (2) by using the OCaml compiler to compile to barebones assembly, we wanted to write a library usable by each type of project. Thus, our library allows it to be consumed by both BuckleScript and native projects.

How we built it

Aside from the Reason language itself, we used a few tools within our project:

  • BuckleScript - Compiler for BuckleScript projects
  • Yarn - Package manager for BuckleScript projects
  • OCaml - OCaml :)
  • Esy - Package manager for native Reason/OCaml projects
  • Dune - Build system for native Reason/OCaml
  • Jest - JavaScript testing framework for the BuckleScript library
  • Rely - Testing framework for native Reason projects

Challenges we ran into

Targeting two languages is not trivial, especially since the different implementations were in the same repository; the main challenges involved setting up our build processes for the library, getting tests to run properly, and organizing our repository in an idiomatic way. Moreover, getting our developer environments set up with all the necessary tooling was challenging, since Reason is a relatively new language and there are certain parts of their getting started guide that could use improvement (in particular, Reason development on Windows is not great).

Accomplishments that we're proud of

We were able to achieve a working implementation of the algorithm, with comprehensive unit tests for included. In addition, we were able to create some example projects that consume our library to verify other developers will be able to use what we built!

What we learned

How to publish a Reason library to be consumed by two different types of projects with different languages, package managers, and build systems! We also gained more knowledge about functional programming and some of the core concepts behind it --- porting a library from an object-oriented to a functional language is not nearly as straightforward as we thought!

What's next for re-nanoid

The original library, after writing the initial implementation, added support for new features like an asynchronous API or providing your own random bytes generator. Eventually, we want to achieve feature parity with this library. Furthermore, we'd also like to formally publish our library on the NPM/opam registries.

Built With

  • bucklescript
  • dune
  • esy
  • ocaml
  • reason
Share this project:

Updates