Skip to content

Commit 492a5d0

Browse files
Fine-tuning
1 parent f40668b commit 492a5d0

File tree

1 file changed

+93
-86
lines changed

1 file changed

+93
-86
lines changed

markdown-pages/blog/release-12-0-0.mdx

Lines changed: 93 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -20,92 +20,36 @@ The new tooling provides focused commands, better diagnostics, and smaller downl
2020

2121
You can find the complete migration guide [here](../docs/manual/migrate-to-v12.mdx).
2222

23-
## Breaking Changes
23+
## New Features
2424

25-
### Build system redesign
25+
### New Build System
2626

2727
ReScript 12 ships with the new build system introduced earlier this month in the [Reforging the Build System](./reforging-build-system.mdx) preview.
28-
The tooling now relies on a modern architecture that tracks dependencies more precisely, avoids unnecessary recompilations, and integrates with incremental workflows.
29-
The old build system remains available through `rescript-legacy`, but active projects should switch to the new commands to benefit from faster feedback loops and clearer output.
30-
31-
### Runtime package split
32-
33-
The compiler no longer embeds runtime modules.
34-
Instead, the runtime lives in the dedicated `@rescript/runtime` npm package, which contains Belt, Stdlib, Js, primitive modules, and supporting artifacts compiled in both ES Module and CommonJS formats.
35-
Earlier versions bundled these files inside the `rescript` package and exposed an optional `@rescript/std` helper.
36-
ReScript 12 removes `@rescript/std`; install `rescript` and `@rescript/runtime` together to keep projects in sync.
37-
Projects that previously published custom runtime shims should revisit their setup to ensure the new package structure remains discoverable.
38-
39-
### Bitwise operators
40-
41-
ReScript now supports F#-style bitwise operators `&&&` (AND), `|||` (OR), `^^^` (XOR), and `~~~` (NOT) for both `int` and `bigint`.
42-
Legacy OCaml-style bitwise functions such as `land`, `lor`, and `lsl` are deprecated.
43-
44-
### API naming alignment
45-
46-
APIs that previously ended with `Exn` now end with `OrThrow`.
47-
Examples include `Option.getOrThrow`, `List.headOrThrow`, `BigInt.fromStringOrThrow`, and `JSON.parseOrThrow`.
48-
The change clarifies that these functions throw JavaScript errors, aligning the naming with the language’s semantics.
49-
The deprecated `*Exn` variants remain available in v12 to ease the transition, and the codemod bundled with the migration tool can perform a mechanical rename.
50-
Note that `Result.getOrThrow` now throws a JavaScript exception, so please update any exception-handling logic that relied on OCaml exception names. We also revamped the API around JS exceptions and errors.
51-
52-
We’ve renamed JS errors to `JsError.t` to better distinguish them from the `Result.Error` variant. Since JavaScript allows throwing anything (not only proper Error objects), the previous way of catching JS exceptions was unsafe:
53-
54-
```res
55-
let foo = switch myUnsafeJsResult() {
56-
| exception Exn.Error(e) => Error(e->Error.message)
57-
// ☝️ this will crash if `e` is undefined or null
58-
| myRes => Ok(myRes)
59-
}
60-
```
61-
62-
Additionally, the coexistence of `Result.Error` and the `Error` module caused confusion.
63-
64-
The new recommended pattern is:
65-
66-
```res
67-
let foo = switch myUnsafeJsResult() {
68-
| exception JsExn(e) => Error(e->JsExn.message))
69-
// ☝️ this is now safe even `e` is undefined or null
70-
| myRes => Ok(myRes)
71-
}
72-
```
73-
74-
Utility helpers for working with JS errors are now in `JsError`, eg:
28+
The tooling now relies on a modern architecture that tracks dependencies more precisely, avoids unnecessary recompilations, and integrates with incremental workflows even across monorepo packages.
7529

76-
```res
77-
JsError.throw(JsError.RangeError.make("the payload should be below 16"))
78-
```
30+
### Improved Standard Library
7931

80-
### JSX version requirement
32+
The new standard library [`@rescript/core`](https://github.com/rescript-lang/rescript-core) is now included in the compiler runtime. So you can get rid if the dependency on `@rescript/core` in your projects. To avoid collisions we have named the new internal library just `Stdlib`, so you can keep using it alongside `Core` if you cannot migrate yet. There have been tons of additions as well, so you can shrink your `Utils` files down a bit. Check it out here: [Stdlib](../docs/manual/api/stdlib).
8133

82-
JSX v3 has been removed.
83-
ReScript 12 requires JSX v4 configuration in `rescript.json`, using the `"jsx": { "version": 4 }` schema.
84-
ReScript React projects must update their configuration before moving to v12.
85-
Projects attempting to compile with v3 will receive an explicit error, ensuring that your codebase uses the current transform and associated tooling.
34+
### Operator Improvements
8635

87-
### Deprecation of OCaml compatibility helpers
36+
#### Unified Operators
8837

89-
The standard library continues its shift away from OCaml-specific aliases.
90-
Functions such as `succ`, `pred`, `abs_float`, `string_of_int`, `fst`, `raise`, and the `char` type are now deprecated.
91-
The recommended replacements are the JavaScript-aligned counterparts in `Int`, `Float`, `Bool`, `Pair`, and related modules, alongside the `throw` keyword for exceptions.
92-
References to the OCaml composition operators (`|>`, `@@`) now warn and will be removed in a future version; the ReScript pipe operator `->` replaces them.
93-
The migration tool highlights deprecated usage, and incremental cleanups are encouraged so your codebase is ready before the next major release.
38+
ReScript 12 finalizes the unified operator work introduced [earlier this year](./introducing-unified-operators.mdx).
39+
Arithmetic operators (`+`, `-`, `*`, `/`, and the newly added `%` and `**`) now work consistently for `int`, `float` and `bigint`, allowing the compiler to infer the correct specialization from the left operand. You can ditch all the `+.`, `-.`, `*.`, and `/.` now!
9440

95-
## New features
41+
In addition you can also now use `+` for string concatenation, while `++` still works as before.
9642

97-
### Unified operators
43+
#### Bitwise Operators
9844

99-
ReScript 12 finalizes the unified operator work introduced [earlier this year](./introducing-unified-operators.mdx).
100-
Arithmetic, comparison, and bitwise operators now behave consistently across `int` and `bigint`, allowing the compiler to infer the correct specialization from the left operand.
45+
ReScript now supports F#-style bitwise operators `&&&` (AND), `|||` (OR), `^^^` (XOR), and `~~~` (NOT) for both `int` and `bigint`.
46+
Legacy OCaml-style bitwise functions such as `land`, `lor`, and `lsl` are deprecated.
10147

102-
### Expanded bitwise capabilities
48+
#### Shift Operators
10349

104-
In addition to deprecating the OCaml-style helpers, ReScript 12 adds new operator spellings.
105-
JavaScript-style bitwise operators (`&`, `|`, `^`, `~`) and shift operators (`<<`, `>>`, `>>>`) are first-class citizens that compile directly to their JavaScript equivalents.
106-
Combined with the unified F#-style operators, developers can select the syntax that best fits their code policies without sacrificing performance or type safety.
50+
For shift operators there was luckily no conflict in the character space, which means ReScript now supports `<<` (logical left shift), `>>` (logical right shift) and `>>>` (unsigned right shift), just like JavaScript.
10751

108-
### Dict literals and pattern matching
52+
### Dict Literals and Pattern Matching
10953

11054
The language now supports dictionary literals (`dict{"foo": "bar"}`) that compile to plain JavaScript objects.
11155
Dict literals work with variables, multi-line formatting, and optional entries, and they drastically reduce the boilerplate compared to `Dict.fromArray`.
@@ -121,9 +65,9 @@ switch user {
12165
}
12266
```
12367

124-
### Nested and inline record types
68+
### Nested Record Types
12569

126-
Nested record definitions and inline record payloads remove the need for auxiliary type declarations.
70+
Nested record definitions remove the need for auxiliary type declarations.
12771
You can define optional nested structures directly inside records, or attach record payloads to variant constructors without creating standalone types.
12872
The feature supports mutable fields, type parameters, and record spreading, providing better locality for complex domain models with no runtime penalty.
12973

@@ -137,7 +81,7 @@ type profile = {
13781
}
13882
```
13983

140-
### Variant pattern spreads
84+
### Variant Pattern Spreads
14185

14286
Pattern spreads (`| ...SomeVariant as value =>`) allow you to reuse handlers for entire subsets of constructors.
14387
When a variant extends another variant through spreads, you can match the shared constructors in one branch and delegate to helper functions, keeping exhaustive matches concise even as the hierarchy grows.
@@ -154,22 +98,23 @@ let handle = (event: extended) =>
15498
}
15599
```
156100

157-
### JSX preserve mode
101+
### JSX Preserve Mode
158102

159103
Projects that rely on downstream JSX tooling can enable [preserve mode](../docs/manual/jsx.mdx#preserve-mode) via `"jsx": { "version": 4, "preserve": true }`.
160104
The compiler will emit JSX syntax directly instead of transforming elements to `react/jsx-runtime` calls, allowing bundlers such as ESBuild, SWC, or Babel to apply their own transforms.
161-
This mode keeps JSX readable in the output, retains spread props, and maintains compatibility with React Server Components.
105+
This mode keeps JSX readable in the output and maintains compatibility with React Compiler.
106+
162107
React classic mode is no longer supported, so projects must use the JSX v4 transform regardless of preserve mode settings.
163108
When preserve mode is disabled, the compiler continues to output the optimized runtime calls you are accustomed to.
164109

165-
### Function-level directives
110+
### Function-Level Directives
166111

167112
The new `@directive` attribute emits JavaScript directive strings at the top of generated functions.
168113
Use it to mark server actions with `'use server'`, memoized handlers with `'use memo'`, or any other directive that your framework requires.
169114
The attribute works on synchronous and asynchronous functions, supports labeled parameters, and removes the need for `%raw` blocks.
170115
Combined with JSX preserve mode, this enables clean integration with [React Server Components](../docs/react/server-components.mdx) and other directive-based runtimes.
171116

172-
### Regex literals
117+
### Regex Literals
173118

174119
ReScript now understands JavaScript-style regular expression literals (`/pattern/flags`).
175120
They are full equivalents of `%re` expressions, supporting all ECMAScript flags, Unicode character classes, and sticky searches.
@@ -188,7 +133,7 @@ switch emailPattern->RegExp.exec("invalid") {
188133
}
189134
```
190135

191-
### Experimental `let?` syntax
136+
### Experimental `let?` Syntax
192137

193138
This release introduces an experimental `let?` syntax for zero-cost unwrapping of `option` and `result` values.
194139
The syntax remains behind an opt-in flag while the community evaluates its ergonomics.
@@ -208,29 +153,91 @@ let userCity = (user: user): option<string> => {
208153
}
209154
```
210155

211-
## Platform and tooling improvements
156+
## Platform and Tooling Improvements
212157

213-
### Cleaner JavaScript output
158+
### Cleaner JavaScript Output
214159

215160
The printer now emits compact arrow functions and streamlines anonymous function expressions, making generated JavaScript easier to audit.
216161
These changes preserve semantics while aligning the output with modern JavaScript style.
217162

218-
### Internal architecture updates
163+
### Internal Architecture Updates
219164

220165
The compiler cleans up its internal abstract syntax tree, removes unused OCaml-era nodes, and tracks async and partial function metadata directly on AST nodes.
221166
These changes simplify future feature work and reduce maintenance overhead.
222167

223-
### ESM-first distribution
168+
### ESM-First Distribution
224169

225170
The `rescript` npm package declares `"type": "module"` and ships ESM code across the CLI.
226171
Import statements replace CommonJS `require` usage, improving compatibility with contemporary bundlers and enabling better tree-shaking.
227172

228-
### Platform-specific binaries
173+
### Platform-Specific Binaries
229174

230175
Installer footprints shrink thanks to platform-specific binary packages such as `@rescript/darwin-arm64`, `@rescript/linux-x64`, and `@rescript/win32-x64`.
231176
npm installs only the binary that matches your operating system and architecture, delivering substantially faster installs and smaller cache footprints for CI pipelines.
232177
The primary `rescript` package loads the appropriate binary at runtime and surfaces clear error messages if the matching package is missing.
233178

179+
## Breaking Changes
180+
181+
### Build System
182+
183+
The old build system remains available through `rescript-legacy`, but active projects should switch to the new commands to benefit from faster feedback loops and clearer output.
184+
185+
### Runtime Package Split
186+
187+
The runtime modules were moved from the main `rescript` npm package to a dedicated `@rescript/runtime` npm package. It is automatically installed as a dependency of the main `rescript` package.
188+
The new `@rescript/runtime` package also replaces the standalone runtime package `@rescript/std` from earlier versions.
189+
190+
### API Naming Alignment
191+
192+
APIs that previously ended with `Exn` now end with `OrThrow`.
193+
Examples include `Option.getOrThrow`, `List.headOrThrow`, `BigInt.fromStringOrThrow`, and `JSON.parseOrThrow`.
194+
The change clarifies that these functions throw JavaScript errors, aligning the naming with the language’s semantics.
195+
The deprecated `*Exn` variants remain available in v12 to ease the transition, and the codemod bundled with the migration tool can perform a mechanical rename.
196+
Note that `Result.getOrThrow` now throws a JavaScript exception, so please update any exception-handling logic that relied on OCaml exception names. We also revamped the API around JS exceptions and errors.
197+
198+
We’ve renamed JS errors to `JsError.t` to better distinguish them from the `Result.Error` variant. Since JavaScript allows throwing anything (not only proper Error objects), the previous way of catching JS exceptions was unsafe:
199+
200+
```res
201+
let foo = switch myUnsafeJsResult() {
202+
| exception Exn.Error(e) => Error(e->Error.message)
203+
// ☝️ this will crash if `e` is undefined or null
204+
| myRes => Ok(myRes)
205+
}
206+
```
207+
208+
Additionally, the coexistence of `Result.Error` and the `Error` module caused confusion.
209+
210+
The new recommended pattern is:
211+
212+
```res
213+
let foo = switch myUnsafeJsResult() {
214+
| exception JsExn(e) => Error(e->JsExn.message))
215+
// ☝️ this is now safe even `e` is undefined or null
216+
| myRes => Ok(myRes)
217+
}
218+
```
219+
220+
Utility helpers for working with JS errors are now in `JsError`, eg:
221+
222+
```res
223+
JsError.throw(JsError.RangeError.make("the payload should be below 16"))
224+
```
225+
226+
### JSX Version Requirement
227+
228+
JSX v3 has been removed.
229+
ReScript 12 requires JSX v4 configuration in `rescript.json`, using the `"jsx": { "version": 4 }` schema.
230+
ReScript React projects must update their configuration before moving to v12.
231+
Projects attempting to compile with v3 will receive an explicit error, ensuring that your codebase uses the current transform and associated tooling.
232+
233+
### Deprecation of OCaml Compatibility Helpers
234+
235+
The standard library continues its shift away from OCaml-specific aliases.
236+
Functions such as `succ`, `pred`, `abs_float`, `string_of_int`, `fst`, `raise`, and the `char` type are now deprecated.
237+
The recommended replacements are the JavaScript-aligned counterparts in `Int`, `Float`, `Bool`, `Pair`, and related modules, alongside the `throw` keyword for exceptions.
238+
References to the OCaml composition operators (`|>`, `@@`) now warn and will be removed in a future version; the ReScript pipe operator `->` replaces them.
239+
The migration tool highlights deprecated usage, and incremental cleanups are encouraged so your codebase is ready before the next major release.
240+
234241
## Acknowledgments
235242

236243
<Image
@@ -243,7 +250,7 @@ Thank you to every contributor, tester, and partner who helped shape ReScript 12
243250
The core team gathered in Vienna earlier this year to map out this release, and your feedback guided every decision.
244251
Community pull requests, bug reports, and experiments across the ecosystem gave us the confidence to complete large refactors and deprecations.
245252

246-
## Reach out
253+
## Reach Out
247254

248255
Join the conversation on the community forum if you have migration questions or want to share what you build with ReScript 12.
249256
Businesses that rely on ReScript can contact the association at https://rescript-association.org/contact to explore support, sponsorship, or collaboration.

0 commit comments

Comments
 (0)