Integrate PureScript with your JavaScript application
Tags: purescript, javascript, functional, programming
Published: 2018-07-17 15:09:02

---
title: Integrate PureScript with your JavaScript application
published: true
description: PureScript has a top-notch FFI (Foreign-Function Interface) allowing us to call JavaScript functions from within PureScript. It means we can benefit from the type safety not only in new, but also existing applications.
tags: purescript, javascript, functional, programming
canonical_url: https://notes.maciejsmolinski.com/2018/06/10/integrate-purescript-with-your-javascript-application/
---

[PureScript](http://www.purescript.org/) is a strongly-typed functional programming language that compiles to JavaScript. It means we can benefit from the type safety not only in new, but also existing applications.

PureScript has a [top-notch FFI (Foreign-Function Interface)](https://leanpub.com/purescript/read#leanpub-auto-the-foreign-function-interface) allowing us to call JavaScript functions from within PureScript. Not only this but we can also use PureScript modules from JavaScript.

## Installing PureScript

First, we need to install global dependencies — the PureScript compiler, the package manager and the build tool: `yarn global add purescript@0.11.7 psc-package pulp`.

{% youtube 6swGCTT4fEg %}

## Generating project structure

Pulp, the build tool, allows us to generate a basic project structure by running a single command: `pulp --psc-package init`.

It will create the `src` and `test` directories as well as `psc-package.json` containing a list of dependencies. Once created, pulp will install PureScript packages to `.psc-package` directory.

You can now compile and run `src/Main.purs` by typing `pulp --watch run`. After modifying the contents of `src/Main.purs`, pulp will automatically recompile and run the module.

{% youtube RqaBznBQkG4 %}


## Installing code bundler

Since we'd like to build a JavaScript application that integrates with PureScript, a code bundler will come in handy.

[Parcel](https://parceljs.org/) helps to effortlessly transpile ES6 code, bundle modules and automatically reload the code in the browser with no extra configuration. You can install Parcel with `yarn add parcel`.

### Defining npm script and running the bundler

Once installed, it is often a good practice to add a script to the `package.json` file so that we can easily run the bundler. We're going to define `dev` script that will bundle the code and serve the application on port `1234` after running `yarn run dev` in the terminal.

```js
// package.json
"scripts": {
  "dev": "parcel serve src/index.html"
}
```

<br />

Next, we create `src/index.html`

```html
<!-- src/index.html -->
<html>
  <head>
    <title>PureScript Application</title>
  </head>

  <body>
    <script src="./index.js"></script>
  </body>
</html>
```

<br />

And `src/index.js`

```js
// src/index.js
console.log('Hello from JavaScript');
```

<br />

Now, after executing `yarn run dev`, a very basic JavaScript application is up and running on [http://localhost:1234/](http://localhost:1234/).

{% youtube KzXsgVKFALQ %}

## Calling PureScript from JavaScript 

Now, the final step. We'd like to execute PureScript code from `src/Main.purs` in our JavaScript application. We still want `yarn run dev` to be running in the background.

However, instead of running `pulp --watch run` and executing the PureScript code, we're going to run `pulp --watch build` to build the code and skip the execution part.


### The PureScript module

Now, when both commands are running in the background, we can have a look at our `src/Main.purs` module.

```haskell
module Main where

import Prelude
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Console (CONSOLE, log)

main :: forall e. Eff (console :: CONSOLE | e) Unit
main = do
  log "Hello from PureScript!"
```

<br />

Essentially, we can tell the module is named `Main` and it only has a single method called `main`. It imports a bunch of other modules in order to tell the compiler the `main` function is effectful and the particular side effect involved is JavaScript console. It also imports the `log` function which takes a string and prints it in the JavaScript console. The `main` function doesn't produce any value hence the `Unit` in the type definition.

### Importing the module

Next, after we understood the PureScript module, we can import the compiled output from our JavaScript file.

```js
// src/index.js
const Main = require('../output/Main/index');

console.log('Hello from JavaScript');

Main.main();
```

<br />

After opening the browser window again, we can see both the JavaScript code we wrote by hand and the JavaScript code produced by the PureScript compiler both executed and printed text to the JavaScript console.

Excellent! We just integrated existing JavaScript code with PureScript. Now we're free to write in both languages. We can also gradually introduce PureScript in some areas of our codebase as we learn the language.

{% youtube RPsyNpeyBp4 %}

### Next steps

We learned integrating PureScript code with JavaScript doesn't have to be a difficult task. Parcel and Pulp make it a simple process. Parcel's documentation also explains [how to bundle our application for production](https://parceljs.org/production.html).

When it comes to learning PureScript, I highly recommend the ["PureScript by Example" book by Phil Freeman](https://leanpub.com/purescript), the creator of the language. It's a fantastic resource for learning the language as well as functional programming concepts in general!

Good luck!