ReScript, the "Fast, Simple, Fully Typed JavaScript from the Future", has been around for awhile now. The name "ReScript" came into existence in 20...
For further actions, you may consider blocking this person and/or reporting abuse
Regarding your "Why would I pick this over TypeScript?" points:
a
andb
variables as numbers by default when code islet add = (a, b) => a + b
doesn't make sense to me. Calling thisadd()
function with strings is perfectly valid in JS.Don't really see why any TS developer would want to switch to this.
First off, thanks for taking the time to read and leave a comment! I'll answer your points one by one.
You need a secondary tool configured correctly to handle this, and developers can easily by-pass that with a quick ESlint ignore comment. ReScript does not require additional tooling to enforce type safety, and it's not dependent on how you have it configured. Everyone works with the same strong type system.
That is valid code in JS, which of course makes it valid code in TS. In ReScript the
+
operator is only for adding togetherint
. There's+.
forfloat
and++
forstring
. Because the type system is simple everything can only ever be of one type, so function calls and operators can only ever work with one type. This allows it to always correctly know the types based on usage.While you can rely on type inference, it can really slow down the compiler in large projects. Microsoft recommends that you use type annotations to avoid slow downs on large projects. The ReScript compiler will not slow down on large codebases or when you omit annotations.
This again depends on an external tool to enforce, which can be configured in any number of ways. You can also rely on code reviews and establish patterns on your team for what you consider to be the "bad" parts. ReScript doesn't have all of the JS baggage, which means you don't need to work around the footguns of JS or add extra linters.
Yes, it is getting much better, but it's still not "blazing fast". I have project with 32k TypeScript files that takes 2 minutes to run full typechecking with TSC on a cold start, and saving a file with watch mode on takes 4 seconds to type check. A ReScript project with 50k files takes 1 minute to fully compile on a cold start, and when saving it takes under 400 ms to typecheck. It's enough of a difference to greatly improve the feedback loop of local development. I've never once had to wait to see type definitions in VSCode when using ReScript.
Rust is one of the most loved languages by developers, and for good reason. Working with tagged unions, pattern matching, and option and result types make it easier to handle business logic and prevent bugs. I dig more into that here: dev.to/jderochervlk/rescript-rust-...
There are probably a ton of TS devs that are happy with the state of TS, but there are also many devs forced to work with TS coming from other languages that want something better, or maybe they just want a language that works out of the box the same way for everyone using it without the need for external linters and formatters. TS will probably be on top for a long time, but it's nice to have other options available.
OMG! Split that in smaller modules/packages dude! 🤣 ...and then you won't ever have a problem ever again with the typechecking performance as bonus.
Haha we have since broken that up into a monorepo, for better TS and eslint performance. While monorepos can be a nice solution, I don't like that we were forced into it to avoid VSCode crashing on us.
I still can't wrap my head around it. A project with 50k files ...just navigating it must be a nightmare ...and the resulting bundle must be so heavy. What the heck does your software do to be that large?! Just for context, out of curiosity, I checked how many source files the react repo has. It's a monorepo containing 26 packages, totalling ~1600 files. That's more human. You definitely don't have some average project.
It's a project with 40 devs working in one repo. A good chunk of it is probably not even used, but we keep adding to it. This also includes unit tests.
I've worked on larger projects at saas companies in the past, things can get complicated and large real quick.
Man... split that monster ...it's overdue ...40 people on the same repo is too much ...I don't get it
Hey, Google has just 1 repo, so if it works it works.
But seriously, we have a large website that requires a lot of devs to build features at the pace we want, and the teams often work on the same pages. We've tossed around the idea of a poly repo approach, but we'd have to pull in federated microfrontends, which are a headache, and even then devs would still just be locally linking 4 repos together to complete a feature. A monorepo was a good choice for us.
So what's the website requiring this 50k files? Now I'm even more curious of that beast :P
You would be very disappointed lol. Its a lot of logic for a/b testing and landing pages that most people will never see.
Isn't Google's homegrown version-control system a piece of history by now? ...somehow I doubt they have a monorepo in the sense we speak of. I also think they switched to git by now.
They do have a massive amount of tooling, and as far as I know they still have billions of sloc in a single repo. research.google/pubs/why-google-st...
Microsoft has a million files in 1 repo: devblogs.microsoft.com/bharry/the-...
Thank you for taking the time to write such an extensive answer 🙂
After reading your "ReScript: Rust like features for JavaScript" article, I have to admit that ReScript does have some very nice features and should be a great choice for people looking for a better than JS, simple and fast scripting language.
BTW, talking about simple and fast languages, do you know "V programming language" (vlang.io)? It's basically a better version of Go. Used V for a hobby project and loved its simplicity.
I'll have to check it out, thanks!
I think the great strength of typescript is that it's not trying to replace javascript, but rather to play along with it. That's the reason of existence for types like "any" and many other design choices.
There were countless attempts of languages "compiling into" JS. They all failed, since decades. The reason is that the important thing is not the language. It's the ecosystem. The sheer amount of libraries, the frameworks, the tooling, etc. Sure, you can use your new fancy language with a super syntax in your bubble ...but it'll stay there, in the small bubble.
I agree 100% that easy interop and gradual adoption is what led to TypeScript's success.
Other compile to JS languages have always been slightly outside the JS ecosystem, such as Elm, PureScript, Reason, or Clojure. They had they're own package manager, frameworks, or difficult interop with JS. ReScript is on NPM and you can easily use it with your existing build tools, or even partially use it in a JS/TS project. It's not a separate ecosystem, which is what hurt adoption of other compile to JS languages.
But I can't use it in my IntelliJ or the integration may be crappy, I can't use it in vue or react or angular. Heck, I can't even use another lib if it hasn't an "any" type! ...and please don't tell me I should just write the definitions of every lib I want to use first, that would be so contra-productive.
The VScode integration is great actually and has had a ton of effort put into it.
And for any JS library you want to use, you'll either need to write some bindings for the functions you use (which is usually not everything in a library) or find one published on NPM. It's similar to typescript in 2017ish, where you had to find types on NPM or write a d.ts file.
Rescript has JSX and React support out of the box, which covers a lot of ground for most web dev projects.
Still, I guess you can notice your arguments are not really convincing.
While I respect your efforts and it is certainly impressive, I sadly cannot encourage your endeavor. It just leads to even more fragmentation of the community, which I consider counter-productive from a birds eye perspective.
I can't say I come to the same conclusion, but I always expect to have typescript defenders pop up. I had this same debate about why typescript was good in the first place, and again when everyone hated JSX. Progress is tough, and adoption is hard. Not everything will break through, but I try and advocate for the tools that I believe will make our lives as developers easier.
Sure, and you are right to so. It's also not that I love TS or JS ...actually, I find them kind of poor. JS is kind of fucked up if you think about it. There is no sensible language where
[77, 5, 123].sort()
would lead to[123, 5, 77]
. But hey, we have to live with, that's where all the millions of libs, and the frameworks, and the tooling is.Maybe someday WASM will save us all.
support counter arguments!
good points but you are really missing out in the powerful pattern marching variants with the switch
I wish I can downvote because of last sentence. so this is downvote
Good post. I done bigger projects in both rescript and typescript and I must say rescript is really a wonderful language. Having a properly inferred sound nominal type system is one of the biggest things. Just because a thing looks like a duck, quacks like a duck it doesn't mean its a duck. Having the ability to alias a string to a custom type then hide it using an interface file is super powerful.
Other things like having tail recursive functions be compiled down to a while loop is something TS can't do.
Having named arguments for functions reduces the need for adding objects all over the place.
Having proper sum types not the discriminated unions in TS that are so verbose that they are pretty useless.
Having a blazingly fast compiler really changes how you develop things.
The list just goes on and on.
Typescript has some fancy type magic as well that rescript doesn't but really never missed that when doing rescript. The type system is just cleaner, simpler and more elegant.
I think a lot of TS developers really need to try this language write a 10kloc project in it then you can say what you think about it. I think a lot of people would be converted if they just past the barrier and are open minded.
Once you have sum types and pattern matching you wonder how anyone gets anything done without them.
Yes once you have proper sum types you start to reason about problems that way and it frustrating when you don't have that language feature.
Thanks for this post! It's been a few years since I've heard about ReScript, I'm very glad to hear it's still going strong!
For anyone intrigued by this language remember that it does compile to very readable JavaScript. IIRC it would be human editable if need be. That means you have a very easy gradual migration path (and a fallback if you don't end up liking it). No reason not to try it out.
Yup! It's very easy to just commit the compiled JS to GitHub and delete rescript. You would probably want to clean up some function names, but it'll work as is and be readable.
Well this is something new . I guess trying is not too harmful ..
Give it a shot! rescript-lang.org/try
rescript-lang.org/docs/manual/late...
Hi Josh Derocher-Vlk,
Top, very nice !
Thanks for sharing
thanks for taking the time to write this, I am always looking for ways to avoid Typescript and this looks promising, my initial reaction to the synatx below is negative
only as it reminds me of PHP in the scheme of things but that is a non issue
does it have "Either" ?
question arises w.r.t your section on bindings the final actual pattern matching seems to me a bit verbose, I am not an OCaml dev but could that not be a simple Either?
Rescript looks really good
This is the pipe syntax. If you haven't worked with a language that has it, it can be really strange to see, but once you get used to working with pipes you never want to work in a language that lacks them.
Without pipes that last function would have looked like this:
It has a Result type.
Yeah, I selected my most recent bindings and the underlying library has a weird API, so it was tricky to keep simple. It returns an object, 'undefined' or
false
. I had to make a custom variant type to figure that out. Variant types can have any name, and choosingMatch
andFalse
is probably not clear. This is internal to the module I was working on, so the outside doesn't have to look at it.It would be clearer to have named it
Yes
andNo
like this:I've updated the example in the article (and in my project!) to be a bit more clear.
amazing
yes definitly better than Either in this case
At the end it doesn’t matter. These languages doesn’t provide runtime type safety just because they are transpiled to javascript which doesn’t have type safety. So in essence these “type safety” languages just benefit on IDE’s
"Runtime type safety" isn't really a thing, even Haskell and Rust are compile-time checks.
ReScript is a compiled language, so it's more than just a check for the IDE. If I have a source file that has a type error in it, that file will never become JavaScript, which means it will never run on Node or in the browser. Unfortunately for TypeScript, this usually isn't the case since most build tools are just stripping out the type information and we type check as a separate step in our build pipeline.
Rust does go way beyond simple type checking. The robust static type checking and ownership model is strong enough to ensure the application is stable even during runtime.
Sugar-coated languages doesn't bring any benefits of any of their typing models once they are compiled to Javascript which is purely untyped language.
If you are comparing the rust binaries to some javascript bundles then you are comparing apple to oranges.
Yes, if you are looking for auto-completes, documentation and development experience, yes these fancy languages are good on IDE's.
I can technically write a function that receive input as
int
for example and still bind it to an html number input that returns a floating point. Which completely defeats the purpose.One downside of not being able to have two files with the same name is that when you use a React framework which uses file based routing you have to wrap ReScript React code/components in a JS or TS file, because you can't have multiple
page.res
orroute.res
files.Yeah, that's the one pain point I've found, but the workaround is pretty easy. You have to create thin JS files with the correct name and folder that just re-export from the compiled ReScript files.
I don't really like the weird "~" and "->" as opposed to plain "."
when you want to appeal average typescript devs, you need to make it seamless familiar to them.
Typescript is already good enough most of the case
The
~
and->
are not equivalent or replacements for.
.~
is a labled argument which allows you to pass in an argument in any order, it compiles down to an object in JS.rescript-lang.org/docs/manual/late...
And
->
is the pipe operator. It takes the previous value and passes it as the first argument of the next function.rescript-lang.org/docs/manual/late...
You lost me at
We had to do this with TypeScript for years.