The ReScript community is obviously small compared to TypeScript. What is the typical approach you’d take if you found that you needed a nodejs dependency that did not exist in ReScript.
For example say I needed a psql and/or rabbitmq dependency. I’d imagine the options are writing types for the JS functions or creating a wrapper JS and only importing that. But I’m wondering how practical that is and how much of a hindrance this is for real world production projects.
It seems to me the prevailing opinion is, only write bindings for the subset of things you need. But that is not universally accepted by all rescripters. E.g., if you go through the posts on this forum, you will see announcements for many bindings projects and posts/comments about people wanting and writing bindings for complete libraries.
Here are a few threads you might find interesting. I pulled out a couple of quotes, but I encourage you to read the threads, and not rely on my editorializing…
Focus on the subset of the library you need and bind to that:
I’d avoid using the bindings that other people have open-sourced. We’ve had too many issues from using 3rd-party bindings (and libraries in general). You’ll want to have control over those, especially when it comes to updates. We also only write bindings for the functions we use instead of trying to write FFI for a whole library at a time. (link)
Wisest words I’ve seen this week. I’ve tried to recommend this many times but it seems this is something folks have to learn for themselves, especially when they come from the JS community. (link)
This thread discusses two options: writing big complete bindings vs binding only what you need
(note: I hesitate to link to this thread as it got a little spicy and was locked, but there is a lot of interesting info about bindings there, just be aware)
In our experience this applies really well to the general “Bindings dilemma”: When Reason / BuckleScript was pretty new (like 3-4 years ago), ppl started writing bindings for JS libraries and quickly realized that 1) it’s really hard to type the whole library, 2) that the bindings highly depended on the use-cases of the organization using it, and 3) it’s hard to keep the api similar to the JS counterpart.
So they had to do a decision: only type the parts they use in a highly specific way, or try to spend a huge amount of time trying to type the whole surface.
I still stick to the opinion that the generalized bindings approach doesn’t work that well. Everytime I write some ReScript code I copy paste the stuff I need, or write the bindings as I need them. Way less effort than trying to disect the original author’s intent.
One intriguing idea I had for a few years now was to design a dedicated gist-like snippet webapp on rescript-lang’s website to edit / share / remix and sync the bindings to your actual codebases ala flow-typed. It’s a little more flexible bc ppl can actually experiment more freely with specific use-case scenarios (and compiler / library versions).
Also, I feel like most binding libraries could be a single .res file, and having tools to enforce that workflow would be highly beneficial for vendoring bindings.
Yeah I definitely agree with this. I haven’t attempted huge full library bindings in Rescript, but I have in OCaml, and they are so tedious and end up just collapsing under the weight of maintaining them, tracking the upstream changes, whatever, and I end up giving up and just binding a couple of functions that I need. (And I even wrote a ocaml-python binding generator to make it easier, and still think tiny focused bindings are the better way generally.)
That said, I could maybe imagine a case where you are auto-generating bindings to a library, in a way that you can always keep it in sync, then maybe. But still, they would have to be pretty “boring” and close to the JS, since the way I may want something typed or ergonomic in rescript may be way different than the next person.