Docs / Language Manual / ImportFromExportToJs

You are currently looking at the v8.0.0 docs (Reason v3.6 syntax edition). You can find the latest manual page here.

Import from/Export to JS

You've seen how ReScript's idiomatic Import & Export works. This section describes how we work with importing stuff from JavaScript and exporting stuff for JavaScript consumption.

Import From JavaScript

Import a JavaScript Module's Content

Use the bs.module external:

Reason (Old Syntax)ML (Older Syntax)JS Output
 
// Import nodejs' path.dirname
[@bs.module "path"] external dirname: string => string = "dirname";
let root = dirname("/User/github"); // returns "User"

Here's what the external does:

  • [@bs.module "path"]: pass the name of the JS module as a string; in this case, "path". The string can be anything: "./src/myJsFile", "@myNpmNamespace/myLib", etc.

  • external: the general keyword for declaring a value that exists on the JS side.

  • dirname: the binding name you'll use on the ReScript side.

  • string => string: the type signature of dirname.

  • = "dirname": the name of the variable inside the path JS module. There's repetition in writing the first and second dirname, because sometime the binding name you want to use on the ReScript side is different than the variable name the JS module exported.

Import a JavaScript Module Itself (CommonJS)

By omitting the string argument to bs.module, you bind to the whole JS module:

Reason (Old Syntax)ML (Older Syntax)JS Output
 
[@bs.module] external leftPad: string => int => string = "./leftPad";
let paddedResult = leftPad("hi", 5);

Import a JavaScript Module Itself (ES6 Module Format)

If your JS project is using ES6, you're likely using Babel to compile it to regular JavaScript. Babel's ES6 default export actually exports the default value under the name default. You'd bind to it like this:

Reason (Old Syntax)ML (Older Syntax)JS Output
 
[@bs.module "./student"] external studentName: string = "default";
Js.log(studentName);

Export To JavaScript

As mentioned in ReScript's idiomatic Import & Export, every let binding and module is exported by default to other ReScript modules. If you open up the compiled JS file, you'll see that these values can also directly be used by another JavaScript file too.

We support 2 JS export formats:

  • CommonJS (usable from JS as require('myFile')).

  • ES6 modules (usable from JS as import * from 'myFile').

The output format is configurable in bsb.

Export an ES6 default value

If your JS project is using ES6 modules, you're likely exporting & importing some default values:

JS
// student.js export default name = "Al";
JS
// teacher.js import studentName from 'student.js';

Technically, since a ReScript file maps to a module, there's no such thing as "default" export, only named ones. However, we've made an exception to support default module when you do the following:

Reason (Old Syntax)ML (Older Syntax)JS Output
 
/* FavoriteStudent.re */
let default = "Bob";

You can then require the default as normal JS side:

JS
// teacher2.js import studentName from 'FavoriteStudent.js';

Note: the above JS snippet only works if you're using that ES6 import/export syntax in JS. If you're still using require, you'd need to do:

JS
let studentName = require('FavoriteStudent').default;