Yeah, like chenglou said, generally, the best and worst outcomes are just reflecting attributes of JavaScript/NPM/Node, but there are a few ReScript-specific things. Do you have experience with Node services in production? What is it that steers you towards OCaml? I think those would have a big impact on any answers.
The company I work for has a ton of ReScript backend code in production and I’ve spent a lot of time in this area thinking about these same issues. Without knowing more details, it’s hard to say but I’ll try to drop a few notes from using ReScript for some large backend projects over the past few years. We’re fairly happy with things. Our problems generally don’t have anything to do with ReScript.
If JS is important to you, then 100% go with ReScript. If you have JS code you need to interact with, or you feel like Node is a really good solution for your problem, then ReScript is what you want. If JS is not important to you, I’d suggest writing little servers in each to get a taste of what you’ll be working with. Try how things like async control flow, db interaction, testing, ide integration, documentation, learning material, and debugging feel. Different people/companies have different expectations and a week of exploration here could save a world of trouble down the road.
…though we all know the real trouble never shows up until you’ve sunk a year into a project.
If you’re considering OCaml, F# could also be a good fit, feels similar, and is generally easier to hire for and get started with (in my experience).
nPlus / minuses for integrations with platforms like AWS, CockroachDB, etc.
(mainly the ease of use with databases and handling large amount of multifaceted data structures).
You mostly just write FFI bindings to NPM libraries, same as frontend, and so how nicely things integrate is very dependent on the libraries you use and how well they fit your situation. If you aren’t happy with the JS libraries you can find, you’ll probably spend time writing your own framework/infrastructure-layer modules… I know we have.
How scalable is it in regards to extending base features into a more complex architecture?
Do you have examples of what you mean here? Base features of the language? The language itself isn’t really written to be extended.
As far as complex architecture, a lot of things depend on the kinds of async control flow you’ll need. On the backend you don’t have a framework like React to do most of the heavy lifting. You’ll probably use a library like Fastify for your server, you’ll have a DB library, and the rest is up to you. You’ve got promises and callbacks, usual JS/Node stuff… if you need more than that, ReScript doesn’t add anything new in this area. I’ve written our own effect/async tooling and libraries but I don’t really suggest that. It was a lot of work and just happened to be something I’m into. OCaml and F# have more things out-of-the-box around concurrent and async programming… but with that greater control comes greater complexity to manage.
Frameworks that could make this a bit faster?
Again, it’s all Node stuff. I don’t know of any frameworks but it depends on the type of service you’re writing. Fastify is nice, GRPC is nice… GraphQL solves some people’s problems. It’s more that there are a lot of libraries and you build your own framework with them.
I feel like OCaml isn’t too different in this area Ocsigen is the most “frameworky” thing I can think of but I just might be out-of-date. F# feels a bit more “batteries-included” and “just use our frameworks”.
A few other notes:
- Thanks to Node you never have to worry about threading. This is very nice but you have the usual Node performance limits, and the usual Node solutions to those limits. Spin up a bunch of instances and stick them behind something to spread the work out.
- 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.
- Quality of JS libraries varies greatly. Some libraries where a clever, weird interface is just a little interesting in JS can be terrible in ReScript. For example, I recently lost a few days tracking down issues with all of our Knex queries when we updated to the latest ReScript version. But at the same time, the AWS libraries have been great!
- You’re generally able to build the same data structures in both ReScript and OCaml. But if you’re using JS libraries to interact with databases, you’re just going to get JS Objects that are friendly to writing JS back, and if you just use those JS Objects or you try to convert them into a different data structure is up to you.