Skip to content

Commit 52720f3

Browse files
Rename release blogpost file
1 parent 3ff6006 commit 52720f3

File tree

1 file changed

+220
-0
lines changed

1 file changed

+220
-0
lines changed
Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
---
2+
author: rescript-team
3+
date: "2025-11-17"
4+
previewImg: /static/blog/compiler_release_12_0.webp
5+
badge: release
6+
title: "Announcing ReScript 12"
7+
description: |
8+
ReScript 12 arrives with a redesigned build toolchain, a modular runtime, and a wave of ergonomic language features.
9+
---
10+
11+
## Introduction
12+
13+
ReScript 12 is now available.
14+
This release completes the multi-year effort to separate the compiler from legacy constraints, refreshes critical developer workflows, and delivers a modern feature set that is grounded in real-world feedback.
15+
The headline upgrades include a rewritten build system, a standalone runtime package, unified operator support, JSX preserve mode, and numerous syntax improvements that make ReScript code easier to write and maintain.
16+
17+
Teams upgrading from ReScript 11 should review the highlighted breaking changes and schedule time for migration.
18+
The new tooling provides focused commands, better diagnostics, and smaller downloads, while the language additions flatten sharp edges that many of you encountered in larger codebases.
19+
20+
## Breaking Changes
21+
22+
### Build system redesign
23+
24+
ReScript 12 ships with the new build system introduced earlier this month in the [Reforging the Build System](./2025-11-04-reforging-build-system.mdx) preview.
25+
The tooling now relies on a modern architecture that tracks dependencies more precisely, avoids unnecessary recompilations, and integrates with incremental workflows.
26+
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.
27+
28+
### Runtime package split
29+
30+
The compiler no longer embeds runtime modules.
31+
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.
32+
Earlier versions bundled these files inside the `rescript` package and exposed an optional `@rescript/std` helper.
33+
ReScript 12 removes `@rescript/std`; install `rescript` and `@rescript/runtime` together to keep projects in sync.
34+
Projects that previously published custom runtime shims should revisit their setup to ensure the new package structure remains discoverable.
35+
36+
### Updated bitwise operator surface
37+
38+
Legacy OCaml-style bitwise functions such as `land`, `lor`, and `lsl` are deprecated.
39+
They continue to work in v12 with warnings but will be removed in v13.
40+
ReScript now prefers unified operator syntax: `&&&`, `|||`, `^^^`, and `~~~` cover AND, OR, XOR, and NOT for both `int` and `bigint`.
41+
42+
### API naming alignment
43+
44+
APIs that previously ended with `Exn` now end with `OrThrow`.
45+
Examples include `Option.getOrThrow`, `List.headOrThrow`, `BigInt.fromStringOrThrow`, and `JSON.parseOrThrow`.
46+
The change clarifies that these functions throw JavaScript errors, aligning the naming with the language’s semantics.
47+
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.
48+
Be aware that `Result.getOrThrow` now throws a JavaScript `Error`, so update any exception handling logic that depended on OCaml exception names.
49+
50+
### JSX version requirement
51+
52+
JSX v3 has been removed.
53+
ReScript 12 requires JSX v4 configuration in `rescript.json`, using the `"jsx": { "version": 4 }` schema.
54+
ReScript React projects must update their configuration before moving to v12.
55+
Projects attempting to compile with v3 will receive an explicit error, ensuring that your codebase uses the current transform and associated tooling.
56+
57+
### Deprecation of OCaml compatibility helpers
58+
59+
The standard library continues its shift away from OCaml-specific aliases.
60+
Functions such as `succ`, `pred`, `abs_float`, `string_of_int`, `fst`, `raise`, and the `char` type are now deprecated.
61+
The recommended replacements are the JavaScript-aligned counterparts in `Int`, `Float`, `Bool`, `Pair`, and related modules, alongside the `throw` keyword for exceptions.
62+
References to the OCaml composition operators (`|>`, `@@`) now warn and will be removed in v13; the ReScript pipe operator `->` replaces them.
63+
The migration tool highlights deprecated usage, and incremental cleanups are encouraged so your codebase is ready before the next major release.
64+
65+
## New features
66+
67+
### Unified operators
68+
69+
ReScript 12 finalizes the unified operator work introduced [earlier this year](./2025-04-11-introducing-unified-operators.mdx).
70+
Arithmetic, comparison, and bitwise operators now behave consistently across `int` and `bigint`, allowing the compiler to infer the correct specialization from the left operand.
71+
72+
### Expanded bitwise capabilities
73+
74+
In addition to deprecating the OCaml-style helpers, ReScript 12 adds new operator spellings.
75+
JavaScript-style bitwise operators (`&`, `|`, `^`, `~`) and shift operators (`<<`, `>>`, `>>>`) are first-class citizens that compile directly to their JavaScript equivalents.
76+
Combined with the unified F#-style operators, developers can select the syntax that best fits their code policies without sacrificing performance or type safety.
77+
78+
### Dict literals and pattern matching
79+
80+
The language now supports dictionary literals (`dict{"foo": "bar"}`) that compile to plain JavaScript objects.
81+
Dict literals work with variables, multi-line formatting, and optional entries, and they drastically reduce the boilerplate compared to `Dict.fromArray`.
82+
Pattern matching also understands dicts, enabling concise destructuring of JSON payloads and configuration objects.
83+
The compiler emits the same optimized JavaScript while preserving ReScript's type guarantees.
84+
85+
```rescript
86+
let user = dict{"name": "Ada", "role": "engineer"}
87+
88+
switch user {
89+
| dict{"name": name, "role": role} => Console.log2(name, role)
90+
| _ => Console.log("missing user metadata")
91+
}
92+
```
93+
94+
### Nested and inline record types
95+
96+
Nested record definitions and inline record payloads remove the need for auxiliary type declarations.
97+
You can define optional nested structures directly inside records, or attach record payloads to variant constructors without creating standalone types.
98+
The feature supports mutable fields, type parameters, and record spreading, providing better locality for complex domain models with no runtime penalty.
99+
100+
```rescript
101+
type profile = {
102+
name: string,
103+
extra?: {
104+
location: {city: string, country: string},
105+
mutable note: option<string>,
106+
},
107+
}
108+
```
109+
110+
### Variant pattern spreads
111+
112+
Pattern spreads (`| ...SomeVariant as value =>`) allow you to reuse handlers for entire subsets of constructors.
113+
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.
114+
The compiler enforces subtype relationships and ensures that runtime representations remain compatible.
115+
116+
```rescript
117+
type base = Start | Stop | Pause
118+
type extended = | ...base | Resume
119+
120+
let handle = (event: extended) =>
121+
switch event {
122+
| ...base as core => Console.log2("base", core)
123+
| Resume => Console.log("resuming")
124+
}
125+
```
126+
127+
### JSX preserve mode
128+
129+
Projects that rely on downstream JSX tooling can enable [preserve mode](../docs/manual/v12.0.0/jsx#preserve-mode) via `"jsx": { "version": 4, "preserve": true }`.
130+
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.
131+
This mode keeps JSX readable in the output, retains spread props, and maintains compatibility with React Server Components.
132+
React classic mode is no longer supported, so projects must use the JSX v4 transform regardless of preserve mode settings.
133+
When preserve mode is disabled, the compiler continues to output the optimized runtime calls you are accustomed to.
134+
135+
### Function-level directives
136+
137+
The new `@directive` attribute emits JavaScript directive strings at the top of generated functions.
138+
Use it to mark server actions with `'use server'`, memoized handlers with `'use memo'`, or any other directive that your framework requires.
139+
The attribute works on synchronous and asynchronous functions, supports labeled parameters, and removes the need for `%raw` blocks.
140+
Combined with JSX preserve mode, this enables clean integration with [React Server Components](../docs/react/latest/server-components.mdx) and other directive-based runtimes.
141+
142+
### Regex literals
143+
144+
ReScript now understands JavaScript-style regular expression literals (`/pattern/flags`).
145+
They are full equivalents of `%re` expressions, supporting all ECMAScript flags, Unicode character classes, and sticky searches.
146+
The literals compile directly to JavaScript regex objects, so existing APIs like `RegExp.exec` and `RegExp.test` continue to work exactly as before, but with clearer syntax and better editor support.
147+
148+
```rescript
149+
let emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/i
150+
151+
if emailPattern->RegExp.test("contact@rescript-lang.org") {
152+
Console.log("Valid email")
153+
}
154+
155+
switch emailPattern->RegExp.exec("invalid") {
156+
| Some(match) => Console.log(match->RegExp.Result.fullMatch)
157+
| None => Console.log("No match")
158+
}
159+
```
160+
161+
### Experimental `let?` syntax
162+
163+
This release introduces an experimental `let?` syntax for zero-cost unwrapping of `option` and `result` values.
164+
The syntax remains behind an opt-in flag while the community evaluates its ergonomics.
165+
Refer to the forum discussion at https://forum.rescript-lang.org/t/proposing-new-syntax-for-zero-cost-unwrapping-options-results/6227 for the current proposal, examples, and feedback guidelines.
166+
167+
```rescript
168+
type user = {
169+
address?: {
170+
city?: string,
171+
},
172+
}
173+
174+
let userCity = (user: user): option<string> => {
175+
let? Some(address) = user.address
176+
let? Some(city) = address.city
177+
Some(city)
178+
}
179+
```
180+
181+
## Platform and tooling improvements
182+
183+
### Cleaner JavaScript output
184+
185+
The printer now emits compact arrow functions and streamlines anonymous function expressions, making generated JavaScript easier to audit.
186+
These changes preserve semantics while aligning the output with modern JavaScript style.
187+
188+
### Internal architecture updates
189+
190+
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.
191+
These changes simplify future feature work and reduce maintenance overhead.
192+
193+
### ESM-first distribution
194+
195+
The `rescript` npm package declares `"type": "module"` and ships ESM code across the CLI.
196+
Import statements replace CommonJS `require` usage, improving compatibility with contemporary bundlers and enabling better tree-shaking.
197+
198+
### Platform-specific binaries
199+
200+
Installer footprints shrink thanks to platform-specific binary packages such as `@rescript/darwin-arm64`, `@rescript/linux-x64`, and `@rescript/win32-x64`.
201+
npm installs only the binary that matches your operating system and architecture, delivering substantially faster installs and smaller cache footprints for CI pipelines.
202+
The primary `rescript` package loads the appropriate binary at runtime and surfaces clear error messages if the matching package is missing.
203+
204+
## Acknowledgments
205+
206+
![ReScript core team during the 2025 Vienna retreat](/static/blog/rescript-retreat-2025.webp)
207+
208+
Thank you to every contributor, tester, and partner who helped shape ReScript 12.
209+
The core team gathered in Vienna earlier this year to map out this release, and your feedback guided every decision.
210+
Community pull requests, bug reports, and experiments across the ecosystem gave us the confidence to complete large refactors and deprecations.
211+
212+
## Reach out
213+
214+
Join the conversation on the community forum if you have migration questions or want to share what you build with ReScript 12.
215+
Businesses that rely on ReScript can contact the association at https://rescript-association.org/contact to explore support, sponsorship, or collaboration.
216+
Funding enables the team to ship features like the new runtime architecture faster, so every contribution, financial or otherwise, helps the language move forward.
217+
218+
We look forward to hearing what you create with ReScript 12.
219+
220+
![The ReScript team at the 2025 retreat in Vienna](/static/blog/rescript-team-2025.webp)

0 commit comments

Comments
 (0)