Extend an example

git clone https://gitlab.com/platonic/shpadoinkle.git
cd Shpadoinkle

Building Examples

Shpadoinkle works with both GHC and GHCjs.

Building from source can take a long time. If you run with nix-build it’s highly recommended you use Cachix.


When built with GHCjs, Shpadoinkle Haskell code is compiled to JavaScript. This is, for the majority of use cases, the recommended path for running code in production.

nix-build --arg isJS true -A Shpadoinkle-examples

This will generate a folder called result. This contains the output of GHCjs. You can now serve an example. Here we use warp, which is a static file server written in Haskell, however you can serve result/bin/counter.jsexe in any way you’d like.

nix-shell -p haskellPackages.wai-app-static --command "warp -d result/bin/counter.jsexe -p 8080"

Open localhost:8080 in your browser.


When built with GHC, Shpadoinkle runs via JSaddle Warp. This allows frontend Haskell code to be compiled and executed as a backend binary. IO effects are sent to the browser over a websocket, where they are executed by a minimal client written in JavaScript.

nix-build --arg isJS false -A Shpadoinkle-examples

This will generate a folder called result. This contains the output of GHC. You can now serve an example.


Open localhost:8080 in your browser.

Live development

For live development, building a fully optimized build from scratch with nix-build can be too slow. When writing code, we need rapid feedback to be productive.


Either "GHCi as a daemon" or "GHC + a bit of an IDE". To a first approximation, it opens GHCi and runs :reload whenever your source code changes, formatting the output to fit a fixed-height console.
— ndmitchell

GHCID is supplied by the nix-shell in Shpadoinkle. You can use GHCID to get rapid feedback as follows:

nix-shell examples
ghcid --command "cabal repl examples:counter"

You can also get this with a one-liner

nix-shell examples --command "ghcid --command 'cabal repl examples:counter'"

Repl Serving

The easiest way to get changes into your browser as fast as possible is to reload main in a REPL.

nix-shell examples
cabal repl examples:counter

You can then run the application with main. This will serve the application on localhost:8080. When you make changes to the code, simply press btn:[Ctrl + C] then reload and run main once again.


Refresh your browser to view updates. Live reloading is also possible with JSaddle Warp, but has not yet been implemented.

Incremental Builds

Right now incremental builds only work with GHC.

nix-shell examples
cabal build examples:counter

Using cabal build directly will use the standard Haskell incremental builds. Results can be found in the dist folder as you would expect.