How I publish a PureScript package

This is how I publish a PureScript package in the post-Bower, pre-Registry era. It’s a bit involved and I often make mistakes, which are apparent in the series of version numbers on my Pursuit packages which increment the patch version several times on the same day.

But I think I’m finally getting the hang of it, and here are my notes about what I do.

First I have a shell.nix which gives me a nix-shell with these tools on the PATH:

  • purs
  • spago
  • pulp
  • node
  • bower

Then I issue the following commands.

  1. git clean -xdff

    Delete .pulp-cache, .spago, bower_components, output, node_modules, et cetera, for a totally clean build.

  2. spago bump-version --no-dry-run major

    We don’t really want to spago bump-version yet, what we want is for spago to generate a new bower.json for us, and this is the only way to get that, it seems? Commit the new bower.json. If it turns out that we didn’t need a new bower.json then this command may actually succeed, in which case it will create a new git tag, which we may have to delete.

  3. bower install

    pulp will need the bower dependencies installed.

  4. pulp build

    If this command succeeds, then we know that the pulp publish command
    later will succeed.

  5. spago test

    One last time to be sure.

  6. spago bump-version --no-dry-run major

    For real this time.

  7. git push origin main

    Push the main branch to Github. Make sure it passes CI.

  8. pulp publish --no-push

    This will publish our package to Pursuit. No README will appear because we haven’t pushed the new version tag to Github yet, which is fine.

    This command often fails the first time, but run it again and it will always succeed, in my experience.

    This is our last chance to change anything before we tag. Force-pushing main is less tacky than deleting a tag.

  9. git push the new tag.

    Now the README will appear on Pursuit.

Don’t forget to update package-sets. package-sets/ at master · purescript/package-sets · GitHub

Most of this advice is only applicable in the year 2021 and will be obsolete after the whole Bower and Registry situation is sorted out.

Probably other people have better publishing methods, and I would very much like to hear about them in this thread.


Thanks for writing. I literally referenced this when publishing purescript-halogen-svg-elems@v4.0.0 today.


Here’s my shell-purescript_0_14_3.nix too:

# Universal shell for PureScript repos
{ pkgs ? import (builtins.fetchGit {
  url = "";
  ref = "refs/tags/20.09";
  rev = "cd63096d6d887d689543a0b97743d28995bc9bc3";
  }) {}
  easy-ps = import (builtins.fetchGit {
    url = "";
    rev = "bbef4245cd6810ea84e97a47c801947bfec9fadc";
  }) { inherit pkgs; };
pkgs.mkShell {
  nativeBuildInputs = [
  LC_ALL = "C.UTF-8"; #
  shellHook = ''
    source <(spago --bash-completion-script `which spago`)