This section is specific to JavaScript targetting, it will guide you through the process of setting up your project and using Fable with JavaScript.

We will cover the basics of using Node.js and Vite for the browser, but you can use any tools you want.

Node.js

In this section, we are going to see how to run Fable code using Node.js.

When using JavaScript, you will need a package.json to manage your dependencies. This file also allows you to confiture the type of module that Node.js use to interpret your code.

  • Generate a package.json file.

    npm init -y
  • Add the following line to the generated package.json file:

    "type": "module",

    It should looks something like that now:

    {
      "name": "my-fable-project",
      "version": "1.0.0",
      "type": "module",
      "description": "",
      "main": "Program.fs.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "keywords": [],
      "author": "",
      "license": "ISC"
    }
  • Run your code.

    node Program.fs.js

    You should see Hello from F# in your terminal.

  • When targeting the Node.JS, you will probably want to have access to the Node.JS API.

    To do so, you can use the Fable.Node.

    dotnet add package Fable.Node
  • Change the content of Program.fs to the following:

    open Node.Api
    
    fs.writeFileSync("test.txt",  "Hello World")
  • Run Fable in watch mode

    dotnet fable watch

    If you run your node script again, you should see a new file test.txt with the content Hello World.

    Try changing the content of Hello World to something else and re-run your script.

    You should see that Fable re-compile your code and the file content changed.

Browser

In this section, we are going to use Vite as a development server to run our code in the browser.

If you want to use another bundler, please refer to their respective documentation.

  • Generate a package.json file.

    npm init -y
  • Install Vite.

    npm i -D vite
  • Create vite.config.ts file, and add the following content:

    import { defineConfig } from 'vite'
    
    // https://vitejs.dev/config/
    export default defineConfig({
        clearScreen: false,
        server: {
            watch: {
                ignored: [
                    "**/*.fs" // Don't watch F# files
                ]
            }
        }
    })
  • Create index.html file, and add the following content:

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Fable</title>
      </head>
      <body>
        <div id="root"></div>
        <script type="module" src="/Program.fs.js"></script>
      </body>
    </html>

    This file is the entry point of your application. It will load the generated JavaScript file.

  • Run Vite and go to the indicated URL.

    npx vite

    If you open the browser console, you should see Hello from F#.

  • When targeting the Browser, you will probably want to have access to the Browser API.

    To do so, you can use the Fable.Browser.Dom.

    dotnet add package Fable.Browser.Dom
  • Change the content of Program.fs to the following:

    open Browser
    
    let div = document.createElement "div"
    div.innerHTML <- "Hello world!"
    document.body.appendChild div |> ignore
  • Run Fable in watch mode and Vite in parallel.

    dotnet fable watch --verbose --run npx vite

    If you open the browser, you should see Hello world!.

    Try changing the content of Program.fs and see the result in the browser.

Alternative

When using Vite, you could also consider working with vite-plugin-fable instead.