Advanced Features¶
These features provide additional productivity tools for ReScript development.
Code Lens¶
LSP Required
Code Lens displays inferred type signatures as inline annotations above function definitions. This gives you immediate visibility into the types the compiler has inferred, without needing to hover over each identifier.
// (int, int) => int <-- Code Lens annotation
let add = (a, b) => a + b
// string => string <-- Code Lens annotation
let greet = (name) => `Hello, ${name}!`
// (array<'a>, 'a => 'b) => array<'b> <-- Code Lens annotation
let mapArray = (arr, fn) => arr->Array.map(fn)
How It Works¶
Code Lens is powered by the LSP textDocument/codeLens protocol, bridged to IntelliJ’s CodeVision API:
The plugin sends a
codeLensrequest to the rescript-language-server for the current fileThe language server returns an array of Code Lens entries, each containing a line position and a
command.titlewith the inferred type stringThe plugin maps each entry to a
TextCodeVisionEntryand positions it above the corresponding line in the editor
Code Lens annotations are display-only — they show the inferred type but do not trigger any action when clicked.
Configuration¶
Toggle Code Lens: Go to Settings > Editor > Inlay Hints > Code Vision and find “ReScript Type Annotations” in the list
Anchor position: Annotations always appear above the function definition line (top anchor)
File types: Code Lens is shown only in
.resfiles, not in.resiinterface files (since interface files already contain explicit type declarations)
Requirements¶
Code Lens requires the Language Server to be running. If the LSP server is not connected, no annotations are displayed. The project must also be built at least once so the language server has type information available.
Code Lens shows inferred type signatures directly above function definitions, so you can see the types without adding explicit annotations or hovering over each identifier.
See also
Syntax Highlighting covers the semantic token system that powers Code Lens type annotations.
Compiled JavaScript Preview¶
Native
A dedicated tool window that shows the compiled JavaScript output for the currently active ReScript file, providing a side-by-side view of your ReScript source and its JavaScript compilation result.
Open: View > Tool Windows > Compiled JS Preview
Auto-Update Behavior¶
The preview panel automatically refreshes in two situations:
Active file change — When you switch between editor tabs, the preview updates to show the compiled JS for the newly focused
.resor.resifileCompilation success — When the ReScript compiler finishes a successful build (detected via
rescript/compilationStatusLSP notification), the preview reloads to display the latest compiled output
Split View Setup¶
For a side-by-side workflow:
Open a
.resfile in the editorOpen View > Tool Windows > Compiled JS Preview
Drag the tool window tab to the right side of the editor to create a vertical split
As you edit and save your ReScript code, the JavaScript output updates automatically on the right
Toolbar Actions¶
The preview panel includes two toolbar buttons:
Refresh — Manually reloads the compiled JS content for the current file
Open in Editor — Opens the compiled
.jsfile as a full editor tab (useful for searching or copying larger sections)
Use Cases¶
Understanding compilation output — See how ReScript constructs (pattern matching, pipe operators, variants) translate to JavaScript
Debugging — Compare the source and output when investigating runtime behavior
Performance review — Verify that the generated JavaScript is efficient and meets expectations
Learning — Understand how ReScript features map to JavaScript idioms
If the compiled JS file is not found (e.g., the project has not been built), the panel displays a message prompting you to build the project first.
The Compiled JS Preview gives you a live side-by-side view of ReScript and its JavaScript output, helping you understand the compilation result, debug runtime issues, and verify performance characteristics without leaving the IDE.
Module Hierarchy¶
Native
View the module structure and dependency relationships for any ReScript module.
Open: Place the cursor on a module, then use Navigate > Type Hierarchy (Ctrl+H)
Two View Modes¶
The hierarchy browser provides two distinct tree views:
1. Module Nesting
Shows the nested module structure within a file. This is the default view. It displays how modules are organized hierarchically:
// File: Utils.res
module String = { // <-- Root
module Validate = { // child of String
let isEmail = ...
let isUrl = ...
}
module Format = { // child of String
let capitalize = ...
let truncate = ...
}
}
module Number = { // <-- Root
module Parse = { // child of Number
let toInt = ...
}
}
In the hierarchy view, this displays as:
Utils.res
+-- String
| +-- Validate
| +-- Format
+-- Number
+-- Parse
2. Module Dependencies
Shows modules referenced by open and include statements. This view reveals the external dependencies of the current file:
open Belt
open Belt.Array
include SharedUtils
let process = (arr) => arr->Array.map(x => x + 1)
The dependency view lists:
MyModule.res
+-- open Belt
+-- open Belt.Array
+-- include SharedUtils
Inlay Hints¶
LSP Required
The Language Server displays inferred types as inline hints next to variables and parameters, making it easier to understand code without explicit type annotations.
let x /* : int */ = 42
let name /* : string */ = "ReScript"
let items /* : array<int> */ = [1, 2, 3]
let greet = (name /* : string */, age /* : int */) => {
`${name} is ${age->Int.toString} years old`
}
let result /* : option<string> */ = list->List.head
Configuration¶
Navigate to Settings > Editor > Inlay Hints > ReScript to configure inlay hints:
Enable/disable — Toggle inlay hints globally for ReScript files
Inlay hints are provided by the Language Server; their availability depends on the LSP server being connected and the project being built
Difference from Code Lens¶
Code Lens shows the full function signature above the function definition line
Inlay Hints show individual type annotations inline next to each variable or parameter
Both features rely on the Language Server, but they display information in different locations and at different granularities.
PPX Annotation Hints¶
PPX annotation hints display inline descriptions of what each @-attribute generates or binds to, helping developers understand PPX behavior without consulting documentation.
@react.component // generates React.createElement
let make = (~name: string) => {
<div> {React.string(name)} </div>
}
@module("fs") // binds to JS module "fs"
external readFile: string => promise<string> = "readFile"
@genType // generates .gen.tsx
let format = (s: string) => s->String.trim
Supported annotations include @react.component, @genType, @module, @val, @send, @get, @set, @new, @deriving(json), @deriving(accessors), @unboxed, @scope, @string, @int, @unwrap, @return, @obj, @variadic, @as, @live, @dead, and @inline.
Configure via Settings > Editor > Inlay Hints > ReScript > PPX annotations.
Inlay hints make the type system visible without cluttering your source code — inferred types appear as subtle annotations next to each binding, giving you the benefit of explicit types with the conciseness of type inference.
JSON Schema for rescript.json¶
Native
The plugin provides JSON Schema validation and auto-completion for rescript.json and bsconfig.json configuration files. The schema covers the full ReScript build configuration specification.
Auto-Completed Fields¶
When editing rescript.json, you get auto-completion and validation for all top-level and nested fields, including:
Field |
Description |
|---|---|
|
Package name (required) |
|
Source directory configuration (required) |
|
ReScript package dependencies |
|
Development-only ReScript dependencies |
|
JSX transformation settings ( |
|
Output file suffix (e.g., |
|
Module format ( |
|
Package namespace configuration |
|
PPX preprocessor macros |
|
Warning number configuration and error promotion |
|
Dead code analysis settings ( |
|
Editor-specific settings (autocomplete extensions) |
|
Experimental compiler features (e.g., |
Features¶
Auto-completion — Press
Ctrl+Spaceto see available configuration keys at any nesting levelValidation — Invalid values are highlighted with error markers (e.g., using an unsupported module format)
Hover documentation — Hover over any key to see its description and expected type
Nested structure support — Full completion inside
sources,jsx,reanalyze, and other nested objects
The schema file is bundled with the plugin and applied automatically when you open any file named rescript.json or bsconfig.json.
JSON Schema support turns rescript.json editing from guesswork into a guided experience — auto-completion suggests valid configuration keys, and validation catches mistakes before you run the compiler.
Markdown Code Fence Highlighting¶
Native
ReScript code blocks in Markdown files receive full syntax highlighting:
```rescript
type user = {name: string, age: int}
let greet = (user) => `Hello, ${user.name}!`
```
Integration Mechanism¶
The plugin registers a CodeFenceLanguageProvider that recognizes three info-string identifiers:
```rescript— Primary identifier```res— Short form for ReScript implementation files```resi— Short form for ReScript interface files
When the Markdown plugin encounters a code fence with one of these identifiers, it delegates syntax highlighting to the ReScript lexer. This provides the same token-level highlighting (keywords, strings, comments, operators) that you see in .res files.
Requirements¶
This feature requires the Markdown plugin to be installed, which is bundled with most JetBrains IDEs. If the Markdown plugin is not present, code fences render as plain text.
ReScript code fences in Markdown files get the same syntax highlighting as .res files, making documentation, READMEs, and code examples visually consistent and easier to read.
JavaScript Injection in %raw()¶
Native
JavaScript code inside %raw() and %%raw() blocks receives full JavaScript syntax highlighting, enabling comfortable FFI (Foreign Function Interface) editing within ReScript files.
let add = %raw(`
function(a, b) {
return a + b;
}
`)
let timestamp = %raw(`Date.now()`)
%%raw(`
import * as fs from 'fs';
const data = fs.readFileSync('config.json', 'utf8');
`)
Language Injection Mechanism¶
The plugin uses IntelliJ’s MultiHostInjector API to inject JavaScript into string literals inside %raw() blocks:
Pattern detection — The injector checks whether a string literal is preceded by the token pattern
% raw ((with optional whitespace between tokens)Range calculation — For regular strings (
"..."), the enclosing quotes are trimmed from the injection range. For template strings (` ... `), the full string content is usedLanguage resolution — The injector looks for either “JavaScript” or “ECMAScript 6” language support in the IDE
What You Get¶
Inside injected %raw() blocks, you have access to:
JavaScript syntax highlighting (keywords, strings, numbers, comments)
Basic error highlighting for JavaScript syntax errors
Bracket matching within the JavaScript block
Requirements¶
This feature requires the JavaScript plugin (or JavaScript and TypeScript support) to be available in your JetBrains IDE. IntelliJ IDEA Ultimate and WebStorm include this by default. For IntelliJ IDEA Community, you may need to install the JavaScript plugin separately.
JavaScript injection inside %raw() means you get proper JS syntax highlighting and error detection when writing FFI code, rather than working with a plain uncolored string.
RegExp Injection in %re()¶
Native
Regular expressions inside %re() blocks receive full RegExp language support, including syntax highlighting, validation, and bracket matching.
let emailPattern = %re("/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/")
let phonePattern = %re("/^\+?[1-9]\d{1,14}$/")
let urlPattern = %re("/^https?:\/\/[\w\-]+(\.[\w\-]+)+[/#?]?.*$/i")
Language Injection Mechanism¶
The plugin uses IntelliJ’s MultiHostInjector API to inject the RegExp language into string literals inside %re() blocks:
Pattern detection — The injector checks whether a string literal is preceded by the token pattern
% re (Range calculation — The regex delimiters (
/…/) are detected and the injection range is set to the content between delimitersFlags handling — Regex flags after the closing delimiter (e.g.,
i,g,m) are passed to the RegExp language
What You Get¶
Inside injected %re() blocks:
RegExp syntax highlighting (character classes, quantifiers, groups, anchors)
Error highlighting for invalid regex patterns
Bracket matching for groups
(…)Hover documentation for regex constructs (when the RegExp plugin provides it)
Requirements¶
This feature uses IntelliJ’s built-in RegExp language support, which is available in all JetBrains IDEs.
RegExp injection gives you syntax highlighting and validation inside %re() patterns, helping you catch regex errors at edit time rather than discovering them at runtime.
Injected Language Formatting¶
Native
When you format a ReScript file (Cmd+Option+L), any injected language fragments (e.g., JavaScript inside %raw()) are also formatted according to their own language’s formatting rules.
This feature provides a FormattingModelBuilder that delegates formatting to the injected language’s formatter, so injected code stays properly formatted alongside your ReScript code.
When you format a ReScript file, injected JavaScript inside %raw() is also formatted according to its own rules, so a single format command keeps both languages clean.
Grazie Integration¶
Native
When the Grazie plugin is installed, the ReScript plugin extracts natural language text from comments and string literals for grammar and spell checking.
Supported text domains:
Comments — Line comments (
//), block comments (/* */), and documentation comments (/** */) are extracted asCOMMENTSdomain textStrings — String literals, template strings, and character literals are extracted as
LITERALSdomain text
This is an optional integration — if Grazie is not installed, the feature is simply not available.
With Grazie integration, your ReScript comments and strings get the same grammar and spell checking as natural language text, improving documentation quality without switching tools.
Index Pattern Builder¶
Native
Enhances the IDE’s TODO/FIXME detection by providing a lexer-based index pattern builder for ReScript files. This enables more accurate pattern matching within comments compared to the basic text-based approach.
The index pattern builder uses the ReScript JFlex lexer to correctly classify comment tokens (line comments, block comments, and doc comments), ensuring that TODO/FIXME patterns are only matched inside actual comments and not in string literals or code.
Lexer-aware TODO detection prevents false positives — only TODOs inside actual comments are indexed, not string literals containing the word “TODO”.
Element Signature Provider¶
Native
Provides stable element signatures that persist editor fold states across IDE restarts. When you collapse code blocks in the editor, their folded state is remembered using a signature format (TYPE#name#offset) that survives file modifications.
This ensures your code folding preferences persist across IDE sessions — blocks you collapsed stay collapsed, even after editing and restarting.
Project Wizard¶
Native
Create new ReScript projects directly from the IDE with 16 pre-configured templates covering frontend, backend, serverless, mobile, and more.
Steps¶
File > New > Project
Select ReScript from the generator list on the left
Configure project settings:
Project name and location
Template — Choose from 16 project templates grouped by category
Package manager — Choose between npm, pnpm, yarn, or bun
Validation library — Choose between
zodandsury. Every template wires the choice into aValidation.reswhose input differs by template (HTTP body, CLI options, form input, IPC payload, config file, or public API arguments)
Click Create to generate the project
Available Templates¶
Category |
Template |
Description |
|---|---|---|
Basic |
Basic |
Minimal ReScript project with console output |
Frontend |
Vite + React |
React single-page application with Vite bundler |
Frontend |
Next.js |
Server-side rendered React application with Next.js |
Desktop |
Electron |
Cross-platform desktop application with Electron |
Backend |
Hono (Node.js) |
Lightweight web server with Hono framework on Node.js |
Backend |
Hono GraphQL |
Hono server hosting |
Serverless |
Cloudflare Workers |
Serverless API on Cloudflare Workers with Hono |
Serverless |
AWS Lambda |
Serverless function on AWS Lambda with Hono |
Serverless |
Google Cloud Run |
Container-based service on Google Cloud Run with Hono |
Mobile |
React Native (Expo) |
Mobile application with React Native and Expo |
Mobile |
React Native (Community CLI) |
Mobile app with React Native Community CLI (bare workflow) for native Android/iOS access |
Library |
npm Library |
Publishable npm package with |
Tool |
CLI Tool |
Command-line tool with argument parsing |
Full Stack |
Monorepo (Hono + React) |
Full-stack monorepo with Hono backend and React frontend |
Full Stack |
Full-Stack (single package) |
Single-package alternative to Monorepo: one |
Full Stack |
res-x (HTMX on Bun) |
Server-driven web app with |
For per-template detail pages (generated layout, dependencies, key files, scripts, day-two recipes), see Project Templates.
Generated Project Structure¶
Each template generates a ready-to-use project with rescript.json, package.json, and template-specific source files.
Basic template:
my-project/
+-- rescript.json
+-- package.json
+-- src/
+-- App.res
Vite + React template:
my-project/
+-- rescript.json
+-- package.json
+-- index.html
+-- vite.config.mjs
+-- src/
+-- App.res
+-- Main.res
Monorepo template:
my-project/
+-- package.json # Root with workspaces
+-- packages/
+-- shared/
| +-- rescript.json
| +-- package.json
| +-- src/Types.res
+-- server/
| +-- rescript.json
| +-- package.json
| +-- src/Server.res
+-- client/
+-- rescript.json
+-- package.json
+-- src/App.res
Template Details¶
React-based templates (Vite+React, Next.js, Electron, React Native (Expo), React Native (Community CLI)) include JSX configuration in rescript.json and React dependencies.
React Native (Community CLI) targets Android Studio / Xcode users who need direct access to the native android/ and ios/ projects. The template ships only the JavaScript/TypeScript + ReScript surface and a metro.config.js that resolves .res.mjs; the native projects themselves are produced by running @react-native-community/cli after project creation. A src/NativeGreeting.res file demonstrates how to bind a custom Kotlin/Swift NativeModule through @module("react-native") @scope("NativeModules"), though the Kotlin/Swift implementation itself is outside the scope of the template and should be written following the official React Native docs.
Hono-based templates (Hono, Hono GraphQL, Cloudflare Workers, AWS Lambda, Google Cloud Run) share common Hono bindings (src/Hono.res) and differ in their deployment configuration:
Hono (Node.js) — Uses
@hono/node-serverfor local developmentCloudflare Workers — Includes
wrangler.jsoncconfigurationAWS Lambda — Includes esbuild bundling and Lambda adapter bindings
Google Cloud Run — Includes a
Dockerfilefor containerized deployment
npm Library includes @genType configuration for generating TypeScript type definitions.
CLI Tool includes a bin entry in package.json and argument parsing via Process.argv.
Validation Library¶
All 16 templates ship a Validation.res module whose backing library is selected via the Validation library wizard option — either zod (default) or sury (ReScript-native). The function signature is the same across backends — parseXxx: <input> => result<T, string> — so callers don’t need to branch on the library choice. What each template validates depends on the shape of its input boundary:
Template |
Validates |
|---|---|
Hono / Hono GraphQL / AWS Lambda / Cloudflare Workers / Google Cloud Run / Next.js / Full-Stack / Monorepo / res-x |
Incoming HTTP JSON bodies (failures short-circuit to HTTP 400) |
CLI Tool |
|
npm Library |
Public API arguments from JS/TS consumers |
Basic |
|
Electron |
IPC responses returned from the main process |
React Native (Expo) / React Native (Community CLI) |
Draft todo input on the form |
Vite + React |
Greet-form input before the fetch call |
After Project Creation¶
After the wizard creates the project:
Run your package manager’s install command (e.g.,
pnpm install) to install dependenciesRun
rescript build(or use the ReScript run configuration) to compile the projectThe Language Server will start automatically once
@rescript/language-serveris available innode_modules
Quality of Life¶
Every generated project ships with the same baseline so you can start coding right away:
README.md — Documents prerequisites, install/dev commands tuned to the selected package manager, and template-specific deployment notes (e.g. Cloudflare Workers
wrangler deploy, AWS Lambda upload, Cloud Rungcloud run deploy).gitignore— Excludesnode_modules/, ReScript build artifacts, OS files, and template-specific output (.next/,dist/,.wrangler/, …).editorconfig— Pins indentation (2 spaces) and line endings (LF).github/workflows/ci.yml— Minimal CI pipeline that installs dependencies and runsrescript, plus thebuild/testscript when the template defines onepackageManagerfield inpackage.json— Pins the toolchain version for Corepack so collaborators get the same package managerVitest smoke test + coverage — Every template ships
src/__tests__/*.test.mjs(or workspace equivalents) wired totestandtest:coveragescripts (backed by@vitest/coverage-v8). Monorepo fans out withpnpm -r run test/yarn workspaces foreach/npm --workspaces run test --if-present; React Native uses a filesystem smoke test sincereact-nativewon’t load under Node; Hono-based templates use Hono’s built-inapp.request()harness to hit DB-free baseline routes.nvmrc/LICENSE/.github/dependabot.yml— Every template pins the Node major version, ships an MIT license using the project name as the copyright holder, and wires Dependabot to poll npm + GitHub Actions dependencies weekly.env.example— Templates that read environment variables (Hono REST, Hono GraphQL, Full-Stack, Monorepo server, Google Cloud Run) ship a.env.exampledocumenting the expected keys (DATABASE_URL,PORT, etc.);.envis added to.gitignoreso populated copies never get committedHono
app.onErrorglobal handler — Hono-based templates (REST, GraphQL, Full-Stack, Monorepo server) wireapp.onErrorto log the exception and return a JSON 500, so uncaught errors never leak a raw stack trace to clientsCentralized dependency versions — All template versions live in
wizard/templates/TemplateVersions.kt; a nightly GitHub Actions job (integration-tests.yml) verifies that every template still installs and compiles
Vite+ Toolchain (Vite + React, Electron, Monorepo)¶
The Vite + React, Electron, and Monorepo templates use Vite+ (vite-plus) — a unified wrapper that bundles Vite, Vitest, Oxlint, Oxfmt, and Rolldown. Scripts are exposed as vp dev, vp build, vp test, etc.
Known issue: Vite+ is pre-1.0 and currently does not link cleanly with
@vitejs/plugin-reactvia pnpm’s nested store, sovp buildmay fail withERR_MODULE_NOT_FOUNDonvite/internal. As a fallback, replacevite-pluswithviteinvite.config.mjsand switch the npm scripts tovite/vite build. The migration back to Vite+ is a one-line change once Vite+ stabilizes.
The Project Wizard lets you create a fully configured ReScript project in seconds — select a template, choose your package manager, and get a ready-to-build project without manually writing configuration files.
File Templates¶
Native
Create new ReScript files with pre-filled boilerplate code via the context menu.
How to Use¶
Right-click on a directory in the Project panel
Select New > ReScript File
Enter the file name (without extension)
Choose a template from the dropdown
Available Templates¶
Module — Creates a .res file with a module comment header:
// MyModule module
Interface — Creates a .resi interface file with a comment header:
// MyModule interface
Component — Creates a .res file with a React component boilerplate:
@react.component
let make = () => {
<div> {React.string("MyComponent")} </div>
}
In all templates, the file name you enter is automatically substituted into the template content. The Component template is particularly useful for React projects, providing a ready-to-use functional component with JSX.
Customizing Templates¶
File templates can be customized in Settings > Editor > File and Code Templates. Look for the templates under the Internal tab with names starting with “ReScript”. You can modify the template content using IntelliJ’s template variable syntax (e.g., ${NAME} for the file name).
File templates give you a consistent starting point for new modules, interfaces, and React components, so every new file follows the same pattern without copying boilerplate from an existing file.
.d.ts Binding Generation¶
Native
Generate ReScript external binding code from TypeScript .d.ts definition files. This automates the tedious process of writing FFI declarations manually.
How to Use¶
Right-click a
.d.tsfile in the Project panelSelect Generate ReScript Binding
The plugin parses the file using the TypeScript Compiler API and generates a
.resfile with binding declarations
The action is also available from the editor context menu when a .d.ts file is open.
Supported Constructs¶
TypeScript |
ReScript Output |
|---|---|
|
|
|
Record type |
|
Module with |
|
|
|
Polymorphic variant |
|
Module with |
|
|
Type Mapping¶
TypeScript |
ReScript |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
String literal union |
Polymorphic variant with |
Requirements¶
Node.js must be installed and available in PATH (or configured in Settings)
TypeScript must be installed in the project’s
node_modules(the plugin searches parent directories for monorepo support)
Limitations¶
The following TypeScript constructs are not yet supported and will generate /* TODO */ comments:
Conditional types and mapped types
Template literal types
Complex generics with constraints
Intersection types (generates
JSON.tfallback)Overloaded function signatures (uses first signature)
Declaration merging
Writing ReScript FFI bindings for TypeScript libraries is one of the most tedious tasks in ReScript development — this generator automates the conversion, producing correct external declarations that you can refine rather than write from scratch.
Color Preview¶
Native
Inline color swatches are displayed in the editor gutter for color values in your ReScript code:
Hex colors:
"#ff0000","#f00"RGB:
"rgb(255, 0, 0)"HSL:
"hsl(0, 100%, 50%)"
Click the swatch to open the color picker.
let primaryColor = "#3498db"
let errorColor = "rgb(231, 76, 60)"
let successColor = "hsl(120, 39%, 49%)"
Color values inside string literals are detected and a small color swatch appears in the editor gutter next to the corresponding line.
Inline color swatches let you visually verify color values without running the application — see the actual color next to the hex, RGB, or HSL code and click to open the color picker for adjustments.
VCS Code Vision¶
Native
Author and last-change annotations appear on top-level declarations (let, type, module, external), providing Git blame information directly in the editor. Enable via Settings > Editor > Inlay Hints > Code Vision.
VCS annotations on declarations show who last changed each function or type, so you know who to ask about unfamiliar code without running git blame separately.
Package Dependencies¶
Native
A dedicated tool window shows the dependencies and devDependencies from your rescript.json:
Open: View > Tool Windows > ReScript Dependencies
The tree view organizes packages into “Dependencies” and “Dev Dependencies” groups with version numbers.
The Package Dependencies view gives you a quick overview of your project’s ReScript dependencies and their versions without opening rescript.json or running npm list.
Quick Documentation¶
LSP Required
Press Ctrl+Q (or hover) to see documentation for ReScript elements. When the LSP server is connected, documentation comes from the language server. When LSP is unavailable, a PSI-based fallback shows the declaration type, name, and source file.
Quick Documentation surfaces type information and doc comments without navigating away from your current position, letting you understand APIs inline while coding.
Safe Delete¶
Native
Use Refactor > Safe Delete to delete ReScript declarations with usage checking. If the element is still referenced, a confirmation dialog shows all usage locations before proceeding.
Safe Delete prevents accidental breakage by checking for references before removing a declaration, so you can confidently clean up code without worrying about hidden dependencies.
Name Suggestions¶
Native
During rename refactoring, the plugin suggests names based on:
The element’s type (e.g.,
userforUser.t)The containing file name
camelCase conversion from snake_case
Intelligent name suggestions speed up rename refactoring by proposing contextually appropriate names, so you can pick a good name from a list rather than inventing one from scratch.
Reader Mode¶
Native
Files in node_modules/ directories are automatically displayed in Reader Mode, providing a cleaner read-only view for library source files.
Reader Mode gives library source files a clean, distraction-free presentation, making it easier to read third-party code when exploring how a dependency works.
TODO Indexing¶
Native
The plugin integrates with IntelliJ’s TODO tool window (Alt+6 > TODO tab) to detect and list TODO, FIXME, and other task comments in ReScript files.
Recognized patterns include:
// TODO: ...// FIXME: .../* TODO: ... */
TODO items appear in the IDE’s TODO panel alongside items from other file types in your project. You can customize TODO patterns and filters in Settings > Editor > TODO.
TODO indexing brings your ReScript task comments into the IDE’s unified TODO panel, so you can track outstanding work across all languages in one place.
Open Statement Index¶
Native
The plugin indexes all open statements across your project for fast module resolution. This powers features like auto-import suggestions and module dependency analysis.
The open statement index enables instant module lookups across the entire project, powering auto-import and dependency analysis without scanning files on every request.
Project View Enhancements¶
Native
Interface indicator:
.resfiles with a corresponding.resishow a “(has .resi)” suffixVersion display:
rescript.jsonshows the ReScript version from its contentCompiled JS nesting: Compiled JS files (
.res.js/.mjs/.cjs,.bs.js/.mjs/.cjs) are nested under their corresponding.ressource file in the Project panel, reducing visual clutterCompiled JS graying: Nested compiled JS files are displayed in gray text to visually distinguish generated output from source files
Project View enhancements reduce visual clutter by nesting generated files under their sources and surfacing useful metadata like interface presence and ReScript version, so the file tree stays focused on your source code.
Auto Import Options¶
Native
Configure auto-import behavior in Settings > Editor > General > Auto Import:
Toggle automatic
openstatement insertionExclude specific modules from auto-import
Fine-grained auto-import settings let you control which modules are automatically opened, preventing unwanted imports from cluttering your files.
Expression Type¶
LSP Required
Press Ctrl+Shift+P (Cmd+Shift+P on macOS) to display the inferred type of the expression at the cursor position.
let add = (a, b) => a + b
// Place caret on "add", press Ctrl+Shift+P
// Shows: (int, int) => int
The type information is fetched from the Language Server via an LSP textDocument/hover request. If the LSP is not connected, a message indicates that no type information is available.
Tip
This is useful when you want to quickly check the type of a sub-expression without adding an explicit type annotation. Unlike inlay hints (which show types persistently), Expression Type is on-demand and works on any expression, not just declarations.
Expression Type gives you on-demand type inspection for any expression — unlike persistent inlay hints, you invoke it only when needed, keeping the editor clean while still having instant access to type information.
Type Info Tool Window¶
LSP Required
A persistent tool window that continuously displays the inferred type of the expression at the current caret position. Unlike Expression Type (Ctrl+Shift+P) which shows types on demand, the Type Info Tool Window updates automatically as you navigate through code.
Open: View > Tool Windows > ReScript Type
How It Works¶
As you move the caret in a ReScript file, the tool window sends an LSP
textDocument/hoverrequest for the current positionThe response is debounced to avoid excessive requests during rapid navigation
The inferred type is displayed in the tool window panel, updating in real time
Use Cases¶
Exploring unfamiliar code — See types continuously without pressing any shortcut
Debugging type errors — Move through expressions to understand where types diverge
Learning ReScript — Observe how the type system infers types for different expressions
Requirements¶
The Type Info Tool Window requires the Language Server to be running. If LSP is not connected, the panel shows a “No type information available” message.
The Type Info Tool Window provides always-on type visibility as you navigate code — unlike Expression Type which requires a shortcut, this panel updates automatically, making it ideal for exploring unfamiliar codebases.
LSP Auto-Install¶
Native
When you open a ReScript project without @rescript/language-server installed, the plugin displays a notification with a one-click install button.
Notification Actions¶
Action |
Description |
|---|---|
Install with npm/yarn/pnpm |
Installs |
Configure… |
Opens the ReScript settings page to set a custom LSP path |
Don’t show again |
Dismisses the notification for the current session |
The installation runs in the background with a progress indicator. On success, the Language Server starts automatically — no IDE restart required.
The notification only appears when:
The project contains
rescript.jsonorbsconfig.jsonNo custom LSP path is configured in settings
The Language Server is not found in
node_modules
LSP Auto-Install removes the most common setup hurdle — instead of manually running npm commands and configuring paths, one click installs the Language Server and starts it automatically.
GitHub Error Reporter¶
Native
The plugin includes an automatic error reporting system that sends unhandled exceptions to GitHub Issues, helping the maintainers quickly identify and fix bugs.
How It Works¶
When an unexpected exception occurs within the plugin, the IDE’s standard error dialog appears with a Report to Plugin Author button. Clicking this button opens a pre-filled GitHub issue in your browser with:
The exception stack trace
Plugin version and IDE version
Operating system information
Privacy¶
The error report is opened in your browser as a draft GitHub issue. You can review and edit the content before submitting. No data is sent automatically — you have full control over what is shared.
Requirements¶
A GitHub account is required to submit error reports. The report opens on the plugin’s GitHub repository issue tracker.
The error reporter makes it easy to help improve the plugin — when something goes wrong, a pre-filled GitHub issue lets you report the problem with minimal effort while maintaining full control over what is shared.
Inspection Suppressor¶
Native
Suppress specific inspections using // noinspection comments:
// noinspection RescriptDuplicateOpen
open Belt
open Belt // This duplicate open won't be flagged
When an inspection produces false positives in specific locations, you can suppress it with a comment rather than disabling it globally, keeping the inspection active elsewhere.
Framework Detector¶
Native
The plugin automatically detects ReScript projects by looking for rescript.json files. When a project containing rescript.json is opened, the IDE recognizes it as a ReScript project and suggests configuring the framework accordingly.
This enables framework-aware features like project-specific settings and tool integrations.
Automatic framework detection means the plugin activates its full feature set as soon as you open a ReScript project, with no manual configuration required.
Code Rearranger¶
Native
Rearrange top-level declarations in your ReScript files into a canonical ordering via Code > Rearrange Code.
The default order is:
open/includestatementstypedeclarationsexceptiondeclarationsmoduledeclarationsexternaldeclarationsletdeclarations
This helps maintain a consistent file structure across your project.
Automatic rearrangement enforces a consistent declaration ordering across all files, so readers always know where to find types, modules, and functions without relying on individual developer habits.
Module Dependency Diagram¶
Native
Visualize module dependency relationships as a Mermaid graph that you can paste into any Mermaid renderer or export as Graphviz DOT.
Open: View > Tool Windows > ReScript Module Diagram, or use Tools > Show ReScript Module Diagram
How It Works¶
The diagram provider scans every .res file in the project and builds a directed graph from open and include statements. Each module becomes a node; every open ModuleName or include ModuleName becomes an edge from the current module to the referenced one. The result is rendered as Mermaid graph TD syntax in the tool window.
Tool Window Layout¶
Toolbar: Refresh (rebuild the graph from current PSI), Copy as DOT, Copy as Mermaid
Main area: Read-only text panel with the Mermaid
graph TDsourceStatus bar: Module count and edge count
Exporting¶
Copy as Mermaid — Puts the
graph TDtext on the clipboard. Paste into Mermaid Live Editor or any Markdown file with Mermaid support to render the graphCopy as DOT — Puts a Graphviz
digraphon the clipboard. Pipe intodot -Tpngor paste into a.dotfile for rendering with Graphviz
Module names containing spaces, dots, or quotes are automatically escaped so the exported text is safe to feed into either renderer.
Use Cases¶
Understanding project structure — See how modules relate to each other at a glance
Identifying tight coupling — Spot modules with too many dependencies
Refactoring planning — Understand the impact of moving or splitting modules
The dependency diagram reveals your project’s module structure visually, making it easy to spot circular dependencies, tightly coupled modules, and refactoring opportunities that are hard to see in code alone.
PPX Expansion View¶
LSP Required
A tool window that displays the expanded output of PPX macros applied to the current file.
Open: View > Tool Windows > PPX Expansion
How It Works¶
The PPX Expansion View runs the ReScript compiler’s PPX preprocessor on the current file and displays the transformed AST output. This helps you understand what code the PPX generates behind the scenes.
Supported PPX Attributes¶
@react.component— Shows the generatedReact.createElementcalls and component wrapper@deriving(json)— Shows the generatedtoJsonandfromJsonfunctions@deriving(accessors)— Shows the generated field accessor functions@genType— Shows the generated TypeScript type definitions
Use Cases¶
Debugging PPX behavior — Understand why generated code doesn’t work as expected
Learning — See how PPX attributes transform your source code
Optimization — Review the generated output for performance considerations
PPX macros generate code that you never see in your source files — this view makes the generated code visible, helping you debug PPX-related issues and understand what the compiler actually produces.
Type Signature Search¶
LSP Required
Search for functions by their type signature in the Search Everywhere dialog (Shift+Shift).
How to Use¶
Open Search Everywhere with
Shift+ShiftSwitch to the Types tab
Enter a type signature query (e.g.,
string => int,array<'a> => int,(int, int) => int)Matching functions from the project and dependencies are listed
Query Syntax¶
Type signature queries use standard ReScript type syntax:
Query |
Matches |
|---|---|
|
Functions taking a string and returning an int |
|
Functions taking any array and returning an int |
|
Functions taking two ints and returning an int |
|
Functions unwrapping option values |
The search matches against function type signatures from the project’s stub index, providing fast lookup without requiring the LSP server.
When you know what type of function you need but not its name, type signature search lets you discover the right function by its shape — a natural fit for a type-inferred language like ReScript.
Restart LSP Action¶
LSP Required
If the Language Server becomes unresponsive or you need to pick up configuration changes, you can restart it via Tools > Restart ReScript Language Server.
When to Use¶
After manually updating
@rescript/language-serverWhen the LSP server stops responding
After changing LSP-related settings that require a server restart
The action is only available when a project is open. It stops the current LSP server instance and starts a fresh one.
A quick manual restart is the simplest fix when the Language Server gets into a bad state, avoiding the need to restart the entire IDE.
LSP Initialization Options¶
LSP Required
The plugin sends several initialization options to the ReScript Language Server, matching the settings available in the VSCode extension. Configure these in Settings > Languages & Frameworks > ReScript.
Available Options¶
Setting |
Default |
Description |
|---|---|---|
Enable signature help |
On |
Show function parameter information on |
Signature help for constructor payloads |
On |
Show signature help for variant constructor payloads |
Enable project config caching |
On |
Cache project configuration for faster LSP startup |
Enable inlay hints |
Off |
Show LSP-provided inlay hints in the editor (experimental) |
Inlay hints max length |
25 |
Maximum character length for inlay hint labels (0 = unlimited) |
Enable compile status |
On |
Receive compile status notifications from the LSP server |
Changes to these settings take effect after the LSP server restarts (which happens automatically when you click Apply in the settings dialog).
These initialization options give you the same configuration flexibility as the VSCode extension, so you can fine-tune LSP behavior like signature help, caching, and inlay hints to match your preferences.
Dump LSP State¶
LSP Required
The Dump LSP State action displays diagnostic information about the ReScript Language Server for troubleshooting.
Access: Tools > Dump ReScript LSP State
What It Shows¶
The action collects and displays:
LSP server status and count
ReScript project detection information
Relevant plugin settings
Use Cases¶
Troubleshooting LSP issues — Verify the LSP server is running and configured correctly
Bug reports — Include LSP state when reporting issues to plugin maintainers
Debugging — Check what configuration the LSP server has loaded
Dump LSP State provides the diagnostic information needed to troubleshoot Language Server issues or include in bug reports, without manually inspecting configuration files or log output.
Predefined Code Style¶
Native
The plugin registers a “ReScript Standard” predefined code style that can be applied via Settings > Editor > Code Style > ReScript > Set from… > Predefined Style > ReScript Standard.
This provides a one-click way to configure indentation and formatting settings to match the standard ReScript conventions (2-space indentation, no tabs).
For manual indentation and tab/space configuration, go to Settings > Editor > Code Style > ReScript.
The predefined code style gives you correct ReScript formatting conventions in one click, so you do not need to configure indentation settings manually.
Element Descriptions¶
Native
The plugin provides human-readable descriptions of ReScript elements for use in IDE dialogs such as Find Usages, Safe Delete, and refactoring confirmations.
For example, when using Safe Delete on a function, the confirmation dialog shows:
Delete function ‘greet’?
rather than a generic “Delete element” message. This applies to let bindings, type declarations, module declarations, external declarations, and exception declarations.
Descriptive element names in IDE dialogs make refactoring confirmations clearer — you see “Delete function ‘greet’” instead of a generic message, reducing the risk of accidental deletions.
Build Watch Auto-Start Prompt¶
Native
When you open a ReScript project, the plugin shows a one-time balloon notification offering to start the ReScript watch build (rescript build -w).
When It Appears¶
The prompt appears at project startup if:
The project contains
rescript.jsonThe ReScript CLI (
rescript) is found innode_modules/.bin/The prompt hasn’t been dismissed for the current IDE session
Notification Actions¶
Action |
Description |
|---|---|
Start Build Watch |
Launches |
Don’t ask again |
Dismisses the prompt for this IDE session |
Clicking Start Build Watch opens the Run tool window with a live-recompiling build process.
The build watch prompt ensures you start getting live compilation feedback from the moment you open your project, without needing to remember to run the build command manually.
REPL¶
Native
An interactive read-eval-print loop for executing ReScript code snippets directly within the IDE.
Open: View > Tool Windows > ReScript REPL
How to Use¶
Open the REPL tool window
Type ReScript code in the input area at the bottom
Click Run to execute
Output appears in the output area above
Click Clear to reset the output
Expression Handling¶
The REPL automatically wraps simple expressions for output:
letbindings,type/moduledeclarations, andopenstatements are used as-isCode already containing
Js.logorConsole.logis used as-isSimple expressions are automatically wrapped:
1 + 2becomesJs.log(1 + 2)
// Input: simple expression
1 + 2
// Output: 3
// Input: let binding
let greeting = "Hello"
Js.log(greeting)
// Output: Hello
How It Works¶
Each execution is isolated:
Creates a temporary
.resfile with the user codeCompiles with
npx rescript buildExecutes the compiled JavaScript with
nodeDisplays stdout/stderr in the output area
Requirements¶
ReScript CLI (
rescript) must be installed in the projectNode.js must be available in PATH
Limitations¶
No persistent state between executions (each run is isolated)
30-second timeout for compilation and execution
The REPL provides an interactive feedback loop for testing expressions and exploring APIs without creating files, compiling, and running — ideal for learning ReScript or verifying quick assumptions.
Worksheet Mode¶
Native
Worksheet files (.resw) allow you to write ReScript code and have each top-level expression evaluated with results displayed inline.
How to Use¶
Create a new file with the
.reswextensionWrite ReScript code with top-level expressions
Each expression is evaluated and the result is displayed as an inline comment
let x = 1 + 2
// => 3
let greeting = "Hello, " ++ "World!"
// => Hello, World!
type color = Red | Green | Blue
// (type declarations are skipped)
Expression Grouping¶
The worksheet understands multi-line expressions by tracking brace and parenthesis depth. Empty lines, comments, type declarations, module declarations, and open statements are skipped during evaluation.
Requirements¶
ReScript CLI (
rescript) must be installed in the projectNode.js must be available in PATH
Worksheets provide a notebook-like experience where you see every expression’s result inline, making them ideal for prototyping algorithms, testing transformations, and verifying documentation examples.
Scratch Files¶
Native
Create temporary ReScript files in the IDE’s Scratches panel for quick experiments without adding files to your project.
How to Use¶
Open File > New > Scratch File (or
Cmd+Shift+Non macOS)Select ReScript from the language list
A new scratch file opens with a default template:
// ReScript Scratch File
let result = "Hello"
Js.log(result)
Features¶
Full ReScript syntax highlighting and language support
Standalone files stored outside your project directory
Can be compiled and run like normal
.resfilesUseful for prototyping, testing library functions, or learning ReScript syntax
Scratch files give you a disposable workspace for quick experiments without adding files to your project or polluting your source tree.
Call Hierarchy¶
Native
View the call graph around a function, showing both what calls it (Callers) and what it calls (Callees).
Open: Place the cursor on a function name and press Ctrl+Alt+H (Cmd+Alt+H on macOS)
View Modes¶
The hierarchy browser provides two tabs:
Callers (default) — Shows all functions in the project that call the selected function. Discovery uses text-based search across the entire project.
Callees — Shows all functions that the selected function calls. Discovery scans the function body within the same file.
Navigation¶
Double-click a node to navigate to the function source
Use Previous/Next buttons to navigate between functions
Nodes are sorted alphabetically
How It Works¶
The call hierarchy uses PSI-based text search rather than LSP:
Callers: Searches for text occurrences of the function name across all project files
Callees: Scans the function body for identifier tokens and cross-references them against declarations in the same file
Limitations¶
Text-based matching — aliased or module-qualified calls may not be found
Callees are detected within the same file only (no cross-file callee detection)
Works on
letandexternaldeclarations in.resfiles
Understanding the call chain of a function is essential when refactoring or debugging — this view reveals who calls a function and what it calls without manually tracing through the code.
Comment Code Evaluation¶
Native
Evaluate ReScript code examples embedded in documentation comments directly from the editor.
When a
/** ... */documentation comment contains a code block, the plugin can evaluate the code and display the result inline. This helps verify that code examples in documentation are correct and up to date.How to Use¶
Write a code example inside a documentation comment
Place the caret inside the code block
Use Code > Evaluate Comment Code (or the gutter action)
The plugin extracts the code block, compiles and runs it, and displays the result as an inline annotation.
Comment code evaluation verifies that documentation examples are correct and up to date, catching stale or broken code samples before they mislead users.