permalinkGetting Started with PureScript and React
This tutorial will walk you through installing all the machinery, so you can focus on writing actual code. By the end of it we'll have a Hello World style React app written in PureScript.
permalinkInstalling tooling
I will assume you have npm installed. If not, here's how to install it.
permalinkSpago
PureScript has an excellent package manager called Spago.
We can easily install it with npm.
npm install -g spagopermalinkAn editor of your choice
PureScript has support for many editors. I recommend IntelliJ IDEA with the PureScript plugin. You can also use VSCode with the PureScript IDE plugin. Finally, if you'd like to drastically increase the chance of not finishing this tutorial, you can use VIM or Emacs.
permalinkCreating a new project
We can create a new project with spago init.
mkdir purescript-react-app
cd purescript-react-app
spago initNow we have the PureScript part done.
However, since we want to use a JavaScript library (namely, react), we also need to create a package.json file.
This is about as easy and goes:
npm init -ypermalinkInstalling dependencies
We will need to install a few dependencies:
npm install react react-dom
spago install react-basic react-basic-dom react-basic-hooksYou can now build the PureScript part with
spago bundle-appAfter running this command there should be a index.js file at the root of the project.
We've told spago to take our Main.purs file and compile it to JavaScript that runs its main function.
permalinkMaking a webpage
Let's create the following index.html file in our project root:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>PureScript React App</title>
</head>
<body>
<div id="root"></div>
<script src="/index.js"></script>
</body>
</html>This is the shell of our website. We will be rendering our app into the <div> where id is "root".
Note how the <script> tag references the compiled JavaScript code from the previous step.
If you open this file in a browser, you will see a blank page.
Let's change that.
permalinkFinding the root and rendering hello world
Replace the Main.purs file with this:
module Main where
import Prelude
import Effect (Effect)
import Web.HTML (window)
import Data.Maybe (Maybe, Maybe(..))
import Web.DOM.Internal.Types (Element)
import Web.HTML.Window (document)
import Web.HTML.HTMLDocument (toNonElementParentNode) as HTMLDocument
import Web.DOM.NonElementParentNode (getElementById)
import Data.Foldable (for_)
import React.Basic.DOM.Client as ReactDOM
import React.Basic.DOM (text) as R
import Effect.Console (error) as Console
main :: Effect Unit
main = do
maybeRootElement <- findElementByIdInDocument "root"
case maybeRootElement of
Nothing -> Console.error "Could not find element with id 'root'"
Just rootElement -> do
reactRoot <- ReactDOM.createRoot rootElement
ReactDOM.renderRoot reactRoot $ R.text "Hello, React"
findElementByIdInDocument ∷ String → Effect (Maybe Element)
findElementByIdInDocument id = do
win ← window
doc ← document win
let node = HTMLDocument.toNonElementParentNode doc
getElementById id nodeIt goes through the DOM API and finds the element with the id "root", then creates a React root and renders a text node into it.
permalinkTry it out
If we run spago bundle-app now again, spago will tell us that we use some dependencies that we're not explicitly declaring.
Fortunately it prints the exact command we need to run to fix this:
spago install foldable-traversable maybe web-dom web-htmlIf we do it now again:
spago bundle-app
npx http-serverWe can open http://localhost:8080 and see our app running!
Just look at it!