npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@rpominov/rescript-promise

v0.2.1

Published

Another Promise bindings for ReScript

Downloads

33

Readme

@rpominov/rescript-promise

Another Promise bindings for ReScript. I wrote this primarily for myself to use in my own projects, so the API can be opinionated and unconventional in some places. Also, the API is not stable as I’m still exploring the best way to work with promises in ReScript.

Features / design decisions:

  • Does not allow to create Promise.t<Promise.t<'a>> as this is not possible in the underlying JavaScript implementation. The library will throw an exception if you try to create such a value.
  • Native Js.Exn is preferred to ReScript exceptions. Because of the better support in the environment. For example, stack is printed correctly for uncaught exceptions in NodeJS.
  • Provides some utilities for Promise.t<result<'a, 'b>>.
  • Might not work in the browser as it uses some NodeJS APIs like process.exit().

Installation

npm i @rpominov/rescript-promise

In your bsconfig.json add it to bs-dependencies

{
  ...,
  "bs-dependencies": [..., "@rpominov/rescript-promise"],
}

Example

Promise.make(resolve => Js.Global.setTimeout(() => {resolve(1)}, 1000)->ignore)
->Promise.chain(x => Ok(x)->Promise.resolve)
->Promise.mapOk(x => Ok(x + 1))
->Promise.done(result =>
  switch result {
  | Ok(x) => Js.log(x)
  | Error(message) => Js.log(message)
  }
)

API

type Promise.t<'a>

Just an alias for Js.Promise.t<'a>

Promise.resolve: 'a => Promise.t<'a>

The same as Promise.resolve(value) in JavaScript.

If the given value is a promise-like object, will create a rejected promise with a Js.Exn exception. This is necessary because the underlying JavaScript implementation automatically flattens any Promise.t<Promise.t<'a>> into a Promise.t<'a>, but this special case behavior cannot be expressed with ReScript type system.

// This will raise an exception!
Promise.resolve(Promise.resolve(1))

Note that the above issue occurs not only with promises, but with any object that has a then property, that happens to be a function.

Promise.make: (('a => unit) => unit) => Promise.t<'a>

Promise.make(resolve => resolve(val)) is the same as new Promise(resolve => resolve(val)) in JavaScript.

The reject callback is not provided by design. Resolve with a result's Error instead or use Js.Promise.make.

If you pass a promise into resolve(), the promise will reject with a Js.Exn exception instead of resolving (same as with Promise.resolve above)!

Promise.reject: Js.Exn.t => Promise.t<'a>

The same as Promise.reject(error) in JavaScript.

Promise.makeJsError: string => Js.Exn.t

The same as new Error(string) in JavaScript. Added to use in conjunction with Promise.reject.

Promise.catch: (Promise.t<'a>, exn => 'b) => Promise.t<result<'a, 'b>>

Catches the error that the given promise might reject with, passes that error to the provided function, and returns a Promise containing Error(fn(exn)).

If the given promise doesn't reject, wraps the value in an Ok().

Promise.make(_ => {
  Js.Exn.raiseError("Test")
})
->Promise.catch(exn =>
  switch exn {
  | Js.Exn.Error(jsExn) => jsExn->Js.Exn.message
  | _ => Some("Unknown exception")
  }
)
->Promise.done(result => {
  switch result {
  | Ok(_) => Js.log("Not going to log this")
  | Error(msg) => Js.log(msg) // Test
  }
})

Note that the callback gets a ReScript exception as an argument, even if the original promise contained a JavaScript Error. This works the same as in try..catch: https://rescript-lang.org/docs/manual/latest/exception#catching-js-exceptions

Promise.chain: (Promise.t<'a>, 'a => Promise.t<'b>) => Promise.t<'b>

promise->Promise.chain(fn) is the same as promise.then(fn) in JavaScript, where fn returns a promise.

Promise.map: (Promise.t<'a>, 'a => 'b) => Promise.t<'b>

promise->Promise.map(fn) is the same as promise.then(fn) in JavaScript, where fn returns something other than promise.

Note: if fn returns a promise, will reject with Js.Exn (same as with Promise.resolve above)!

Promise.done: (Promise.t<'a>, 'a => unit) => unit

  • If the given promise resolves with a value, calls the provided callback with that value as an argument.
  • If the given promise rejects, logs the error and crashes the Node process.
  • If the provided callback raises an exception, logs the exception and crashes the Node process.

The idea is that you catch the recoverable errors with Promise.catch / try..catch, and in the case of unrecoverable errors, we crash the process:

promise
->Promise.catch(catchRecoverable)
->Promise.done(result => {
  try {
    handleResult(result)
  } catch {
  | SomeRecoverableException => handleRecoverable()
  }
})

And if you don't expect any errors:

promise
->Promise.done(result => {
  handleResult(result)
})

Promise.race: array<Promise.t<'a>> => Promise.t<'a>

The same as Promise.race(array) in JavaScript.

Promise.all: array<Promise.t<'a>> => Promise.t<array<'a>>

The same as Promise.all(array) in JavaScript.

Promise.all2: ((Promise.t<'a>, Promise.t<'b>)) => Promise.t<('a, 'b)>

The same as Promise.all, but with a two-value tuple instead of an array.

There're also all3, all4, all5, and all6 with the corresponding numbers of arguments.

Promise.sequence: array<unit => Promise.t<'a>> => Promise.t<array<'a>>

Given an array of functions that return promises, calls the functions in sequence: calls the next function only after the promise returned by the previous function resolves.

If any of the promises reject, does not call the remaining functions, and the result promise rejects with the same error.

In case of successful completion of all promises, the result promise contains an array of values produced by the promises.

Promise.sequence([
  () => Promise.resolve(1),
  () => Promise.resolve(2),
])->Promise.done(arr => {
  Js.log(arr) // [1, 2]
})

Promise.chainOk: (Promise.t<result<'a, 'b>>, 'a => Promise.t<result<'c, 'b>>) => Promise.t<result<'c, 'b>>

The same as Promise.chain, but calls the provided function with val as an argument only if the original promise contains an Ok(val).

Promise.resolve(Ok(1))->Promise.chainOk(x => Promise.resolve(Ok(x + 1))) // Promise(Ok(2))

// The function hasn't been called
Promise.resolve(Error(1))->Promise.chainOk(x => Promise.resolve(Ok(x + 1))) // Promise(Error(1))

Promise.mapOk: (Promise.t<result<'a, 'b>>, 'a => result<'c, 'b>) => Promise.t<result<'c, 'b>>

The same as Promise.map, but calls the provided function with val as an argument only if the original promise contains an Ok(val).

Promise.resolve(Ok(1))->Promise.mapOk(x => Ok(x + 1)) // Promise(Ok(2))

// The function hasn't been called
Promise.resolve(Error(1))->Promise.mapOk(x => Ok(x + 1)) // Promise(Error(1))