node package manager



JS client for Fable that compiles F# files to individual JS files.


npm install --save-dev fable-splitter babel-core


Add the following to the scripts section in your package.json:

  "build": "fable-splitter src/MyProject.fsproj --outDir out"

You can also add --watch for watch mode. Type ./node_modules/.bin/fable-splitter --help to see the available CLI arguments.

You can then compile your app by running: dotnet fable npm-build. Check Fable website for more info.

There are more options available using the JS API. For this, you can create a config file like the following:

function resolve(relativePath) {
    return path.join(__dirname, relativePath);
module.exports = {
  entry: resolve("src/MyProject.fsproj"),
  outDir: resolve("out"),
  babel: fableUtils.resolveBabelOptions({
    presets: [["es2015", { modules: "commonjs" }]],
    sourceMaps: true,
  fable: {
    define: ["DEBUG"]

Note we're resolving paths as well as Babel options to prevent conflicts in case Fable pulls files from outside the project local directory (for example, from Nuget cache).

Then modify your build script as follows:

  "build": "fable-splitter --config splitter.config.js"

These are the options that can be passed to fable-splitter through the JS API:

  • entry: F# project entry file (.fsproj or .fsx).
  • outDir: Output directory where JS files must be saved. Current directory will be used if not specified.
  • port: Fable daemon port (61225 by default).
  • fable: Options to be passed to Fable:
    • define: Array of compiler directives passed to the F# compiler (like DEBUG). Note Fable will ignore the DefineConstants property in .fsproj.
    • plugins: Array of paths to Fable plugins (.dll files).
    • typedArrays: Translate numeric arrays as JS Typed Arrays. True by default.
    • clampByteArrays: If true, Fable will translate byte arrays as Uint8ClampedArray.
    • fableCore: Specify a directory containing Fable.Core JS files, normally used for testing new Fable versions.
  • babel: Babel options, check Babel website to find more.

Path resolution

For paths pointing to resources other than F# or JS files, you can use the ${entryDir} and ${outDir} macros to make sure the final JS file will contain a relative path that can be resolved properly:

let imgPath = "${entryDir}/../images/foo.png"
  • ${entryDir} resolves to the directory of the F# entry file (usually the .fsproj).
  • ${outDir} resolves to the directory set as outDir in fable-splitter options.