Getting Started

Shpadoinkle is built with Nix, but you can build however you like. stack and cabal are supported with or without Nix.

⛄ Snowman

The fastest way to start a new Shpadoinkle project is to build a Snowman. The following command will setup a new "hello world" project for you.

bash <( curl https://gitlab.com/platonic/shpadoinkle/-/raw/master/snowman/generate.sh )

Building

You can use Nix to build the Haskell server:

nix-build

Or you can build the JavaScript frontend single-page application:

nix-build --arg isJS true

This will generate build outputs in a symlinked folder named ./result/. The Haskell server executable will be found as ./result/bin/<your-project-name>, and the JavaScript frontend SPA will be found under ./result/bin/<your-project-name.jsexe/. This will include unminified and minified JavaScript outputs (as all.js and all.min.js respectively), and a default index.html. To build unminified JavaScript only, you can supply --arg optimize false to your nix-build command.

Building from source can take a long time. If you run nix-build or nix-build --arg isJS true, it’s highly recommended you use Cachix.
If you are seeing version errors in your build, or getting something like "attribute X not found", you may need to update your snowman’s Nix channel. You can manually set the field chan (line 1) in nix/base.nix to either a specific nix-channel version, or a Nixpkgs hash (the latest hash that builds Shpadoinkle can be found here). Furthermore, you can set the channel for a build with the --argstr chan argument — for instance nix-build --argstr chan "20.03".

Cabal

If you’d prefer to use cabal as a build command rather than nix-build, that is also supported, but only from the context of a Nix shell. This way, all of the Haskell dependencies are already resolved with their correct versions, without you needing to adjust version constraints:

nix-shell
cabal build # build your project
cabal repl # enter ghci

This will output your build results under the traditional cabal ./dist-newstyle/ folder, rather than the ./result/ symlink mentioned above.

You can also enter a GHCjs Nix shell with nix-shell --arg isJS true.

Stack

Stack is also supported as a build tool. Running the following command should build your Haskell server:

stack build

This will output your build results under the traditional stack ./.stack-work/ folder, rather than the ./result/ symlink mentioned above.

This build relies on the operating system environment for dependencies — a common build requirement is the presence of Perl-Compatible Regular Expressions (PCRE) C header files. On Ubuntu, this can be resolved with the libpcre++-dev APT package.

Development Environment

Once you have your new project you can get live reloads with the following command:

nix-shell --run "ghcid --command 'cabal repl' -W -T Main.dev"

This will use nix-shell to setup a development environment for you, then execute ghcid inside the environment to watch your files, and execute Main.dev inside a repl. You can see results at http://localhost:8080. Of course you must have [Nix] installed for nix-shell to work.

Installing Nix

Nix works on all Linux distributions, as well as Darwin-based operating systems such as MacOS. To install Nix run:

curl -L https://nixos.org/nix/install | sh
👏 Follow 👏 Instructions
The install script outputs important instructions you need to follow. Read the output and follow instructions.

Success is indicated by the presence of the Nix toolchain in your terminal…​

nix --version
MacOS
Installing Nix on MacOS should work fine, but if you end up in a sticky situation, this article may help. You can also refer to the official manual for more information about Nix.

Cachix

Some of the work done with Nix includes deviations not present on the official Nix package set. As such, some dependencies are not cached on https://cache.nixos.org. Building these dependencies from source can be very slow. If you would like to avoid this wait, you can use our Cachix cache of pre-built dependencies:

nix-env -iA cachix -f https://cachix.org/api/v1/install # install cachix
cachix use shpadoinkle # apply our cache

After executing the above, subsequent builds will use cached dependencies from shpadoinkle.cachix.org, which are kept up to date with master using GitLab CI.