Dead Code Analysis in ReScript

This guide provides a detailed walkthrough on how to leverage ReScript’s powerful dead code analysis tools to maintain a clean, efficient, and distraction-free codebase.

Dead code refers to code that's present in your codebase but is never executed. It can lead to:

  • Increased compilation times

  • Confusion during development

  • Misleading assumptions about functionality

ReScript’s language design allows for accurate and efficient dead code analysis using the ReScript Code Analyzer, available via the official VSCode extension.

Prerequisites

  • ReScript VSCode extension (v1.8.2 or higher)

Activation

  1. Open the Command Palette: Cmd/Ctrl + P

  2. Run: > ReScript: Start Code Analyzer

Deactivation

  • Run: > ReScript: Stop Code Analyzer

  • Or click “Stop Code Analyzer” in the status bar

Result

  • The “Problems” pane populates with dead code warnings and suggestions.

Real-World Use Cases

1. Unused Record Fields

RESCRIPT
type useReturn = { items: array<item>, toggleItemChecked: string => unit, // ← Never used setCheckedOnItem: (string, bool) => unit, checkAll: unit => unit, uncheckAll: unit => unit, }

Remove unused fields to simplify code.

2. Unused Variant Cases

RESCRIPT
type textType = | Text(string) | TextWithIcon({icon: React.element, text: string}) | Render(React.element) // ← Never constructed

Removing unused variants allows simplifying rendering logic.

3. Unused Parts of State

RESCRIPT
type validationState = Idle | Invalid | Valid type state = { oldPassword: string, newPassword: string, newPasswordRepeated: string, validationState: validationState, // ← Never read }

Old validation logic might remain after refactors—clean it up.

4. Unnecessary Interface Exposure

RESCRIPT
// DrilldownTarget.resi MetricParam.parse // ← Never used MetricParam.serialize // ← Never used

Keep interfaces minimal by removing unused exports.

5. Unused Functions

RESCRIPT
let routerUrlToPath = ... // ← Never used let routeUrlStartsWith = ... // ← Never used

Removing these often uncovers further unused logic.

6. Unused Components

Components never referenced in production should be removed, unless explicitly preserved.

Keeping Some Dead Code

Use @dead and @live

@dead

Suppresses warnings but notifies if code becomes alive again.

RESCRIPT
type user = { name: string, @dead age: int, }

@live

Permanently marks code as alive (no future warnings).

RESCRIPT
@live let getUserName = user => user.name

Configuration

Add to your rescript.json:

JSON
"reanalyze": { "analysis": ["dce"], "suppress": ["src/bindings", "src/stories", "src/routes"], "unsuppress": [], "transitive": false }

Options:

  • analysis: Enables dead code analysis ("dce")

  • suppress: Silences reporting for paths (still analyzes)

  • unsuppress: Re-enables reports within suppressed paths

  • transitive: Controls reporting of indirectly dead code

Recommendation: Set transitive: false for incremental cleanup.

Summary

ReScript’s dead code analyzer helps you:

  • Incrementally clean up your codebase

  • Avoid confusion and complexity

  • Improve long-term maintainability

Use it regularly for the best results.