TypeScript icon, indicating that this package has built-in type declarations

5.1.0 • Public • Published


Workflows - CI npm package bundlephobia size npm download per month npm license

Integrate ReScript with Vite by:

  • Starting ReScript compilation automatically
  • Showing HMR overlay for ReScript compiler errors
  • Importing .res files directly (see Using Loader)

Getting Started

If you are looking for a template to quickly start a project using Vite, ReScript and React, take a look at vitejs-template-react-rescript, the template depends on this plugin.

# npm
npm i -D @jihchi/vite-plugin-rescript

# yarn
yarn add -D @jihchi/vite-plugin-rescript

# pnpm
pnpm i -D @jihchi/vite-plugin-rescript

Configure your vite plugin in vite.config.ts:

import { defineConfig } from 'vite';
import createReScriptPlugin from '@jihchi/vite-plugin-rescript';

export default defineConfig({
  plugins: [createReScriptPlugin()],

If you're using require syntax:

const { default: createReScriptPlugin } = require('@jihchi/vite-plugin-rescript');

Using Loader

The plugin comes with support for loading .res files directly. This is optional and in most cases not necessary, but can be useful in combination with "in-source": false. When using "in-source": false (without the loader), importing local files using relative paths is troublesome. Take for example the following code:

%%raw(`import "./local.css"`)
@module("./local.js") external runSomeJs: unit => unit = "default"

The bundler will fail when reaching this file, since the imports are resolved relative to the generated JS file (which resides in lib), but the .css and .js files are not copied into this directory. By utilizing the loader it no longer fails since the bundler will resolve the files relative to the .res file instead.


The loader is configured to support lib/es6 output with .bs.js suffix by default. This can be changed by providing an options object to the plugin:

export default defineConfig({
  plugins: [
      loader: {
        output: './lib/js',
        suffix: '.mjs',

Note: It is recommended to use .bs.js suffix since the loader cannot otherwise distinguish between imports of regular JS files and those that were generated by the ReScript compiler.

Note: Using es6-global module format may cause issues with imports of ReScript node modules, since the paths to the node_modules will be generated as relative to the lib folder.


For HTML entry points, it must be imported using inline JS:

<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite App</title>
    <div id="root"></div>
    <script type="module">
      import '/src/Main.res';

If using Vite with library mode, just use the .res as entry point:

import { defineConfig } from 'vite';
import createReScriptPlugin from '@jihchi/vite-plugin-rescript';

export default defineConfig({
  plugins: [createReScriptPlugin()],
  build: {
    lib: {
      entry: 'src/Main.res',


Many thanks for your help!


npm i @jihchi/vite-plugin-rescript

DownloadsWeekly Downloads






Unpacked Size

22 kB

Total Files


Last publish


  • jihchi