Coming back to ReScript!

I have been building a web app using Typescript for a few months. I strayed from ReScript because I wanted to keep my tech stack simple. Didn’t want to have to write bindings for test framework and other external pieces. But the pain brought me back. I rewrote most of it in ReScript pretty quickly. I NEVER got into any kind of flow with Typescript and found it hard to wrap my mind around the code. Here are some of the pain points in TypeScript and what I’m missing in ReScript.

Import and export hell. In ReScript you can easily create a new type for a small thing like Milliseconds.t and then easily use it everywhere. With TypeScript you have to manually import and your code files have zillions of import statements at the top. VS Code can do automatic imports but it only works for each exported item (not whole modules by file name) and I can’t always remember the names and don’t dare using type “t”. In ReScript you just type the module name dot and it shows you everything in there.

No type inference. Spending tons of time typing the types and generic params. Makes the code super ugly and verbose. A huge benefit of type inference is it lets you code top down. You can write a function called “calculateSchedule” for example and midway through realize you need a prioritizer or logger or something. So just add a new function parameter called “prioritize” and use it as you want. In TypeScript you’d have to give that new thing an explicit function type. The inference makes it more feasible to write tons of small helper functions because you don’t need to explicitly type them as well.

No code organization within a module. In ReScript you can have modules inside modules. In TypeScript you can’t do this and so must give each function a long name that won’t conflict with the others. Or create more files to split things up and then have the import hell problem.

Piping. Code is so ugly and hard to understand without it. I tried fp-ts but it is cumbersome.

Expressions everywhere. In Typescript you’ve got to write temp variables with mysterious names and immediately executing functions.

Pattern matching and variants. You can kind of do this in Typescript but it is verbose.

Nominal types. Easily create a type called “milliseconds” that won’t ever get confused with “seconds”. Typescript has branded types but this is not type safe.

Typescript error messages are a mile long.

Interface files. I love being able to make a resi and easily look at it to see what a module is supposed to do. Also good for planning - I start there.

Biggest problems with ReScript…

No search for symbol across the project. This is a super handy way of navigating TypeScript.

The AI code generation is miles behind TypeScript. It’s less important in ReScript because the code is almost declarative.

Writing bindings is necessary. Doing that for Firebase or something is too much work. I’m planning to use ReScript for core logic with no dependencies on anything. I’ll use gentype to make components accessible from Typescript. I will use Typescript for complicated UI and interacting with the outside world.

Can’t use Zed editor.

9 Likes

Hi there, this is interesting feedback.

No search for symbol across the project.

It this would be possible to add, would of course require some work on the tooling side.

The AI code generation is miles behind TypeScript.

Yes, fair critique. You can use LLMs | ReScript Language Manual as context for your prompts. There is one for React as well LLMs | React.

Doing that for Firebase or something is too much work.

Been there, you could take a look at GitHub - nojaf/rescript-firebase

Can’t use Zed editor.

I was able to use it, after upgrading the LSP they ship with, see Allow usage of custom @rescript/language-server · Issue #8 · humaans/rescript-zed · GitHub

6 Likes

Thanks very helpful. The LLM docs don’t cover Core. The AI features keep writing code like Belt. and Js.Array even though I specifically told it not to do that. Maybe we need a doc for core library.

2 Likes

Welcome back! There’s been a lot of work to continue to improve the language, so it’s a great time to test it out again! V12 should be shopping soon and it has some great additions, so you might want to check that out.

The Core lib is documented in the API section of the docs: API | ReScript API

1 Like

I fed the LLM docs to Copilot and it still produces arrays in syntax [| 1,2,3 |] and tries to access object properties like object##prop. I think these are old Reason syntax. I kept reminding the AI to read the doc and it kept producing the wrong result. Finally it understood.

2 Likes