Home

Awesome

React-Haskell Hackage

As crazy as it seems, using React and Haskell together just may be a good idea.

I was driven to create this thing because I had a large existing Haskell codebase I wanted to put online. However, even without existing code, I think a lot of problems are better modeled in Haskell than JavaScript or other languages. Or you might want to use some existing Haskell libraries.

Examples

Let's put a simple paragraph on the page:

sample :: ReactNode a
sample = p_ [ class_ "style" ] $ em_ "Andy Warhol"

main :: IO ()
main = do
    Just doc <- currentDocument
    let elemId :: JSString
        elemId = "inject"
    Just elem <- documentGetElementById doc elemId
    render sample elem

That creates a DOM node on the page that looks like:

<p class="style">
    <em>Andy Warhol</em>
</p>

We can make that a little more complicated with some more child nodes.

sample :: ReactNode a
sample = div_ [ class_ "beautify" ] $ do
    "The Velvet Underground"

    input_

    "Lou Reed"

But of course that input doesn't do anything. Let's change that.

sample :: JSString -> ReactNode JSString
sample = div_ $ do
    "Favorite artist:"

    input_ [ onChange (Just . value . target) ]

    text str

Getting Started

The first step is a working GHCJS installation. The easiest way is to download a virtual machine with GHCJS pre-installed. I recommend <a href="https://github.com/joelburget/ghcjs-box">ghcjs-box</a>.

Now that GHCJS is installed we can use cabal to create a project.

$ mkdir project
$ cd project
$ cabal init # generate a .cabal file

Now edit the cabal file to include dependencies.

build-depends:
  base >= 4.8 && < 5,
  ghcjs-base,
  ghcjs-dom,
  react-haskell >= 1.3

Now we can write Main.hs.

sample :: ReactNode a
sample = p_ [ class_ "style" ] $ em_ "Andy Warhol"

main :: IO ()
main = do
    Just elem <- elemById "id"
    render sample elem

Next Steps

Reference

Additional Resources

Is it Right for Me?

React-Haskell is a great tool for building web UI from Haskell. However, you may want to consider the alternatives:

Small Print

MIT License

Bitdeli Badge