Recommended Tooling for PureScript in 2021

If you do it three times it’s a tradition – welcome to the annual ‘Recommended Tooling for PureScript’ post! Thanks to @eikooc for reminding me to make an update. As usual, all opinions are my own. You can see previous years here:

Changes This Year

The most notable new tools for PureScript are two new formatters, both written in PureScript using the language-cst-parser library by @natefaubion.

  • purs-tidy is my personal choice among PureScript formatters. It supports several useful options like arrow-first (the most common style) or arrow-last (purty-style) formatting, as well as the ability to group operators by precedence when formatting.
  • pose is a PureScript port of purty (purty is not compatible with PureScript 0.14). It’s in low-maintenance mode and is a good option for folks who prefer the purty formatting style, but for most users I’d recommend purs-tidy instead.

There have also been some notable tools released as libraries, not standalone tools:

  • tidy-codegen is a library for generating PureScript modules (we use this at Awake Security to generate our API!).

Example Projects

As usual, you can see examples of the tools I recommend in action in these repositories:

There are also a few new excellent example projects this year, including:

Installing Tools

You can install PureScript tools (like purs) either system-wide or in a particular project using one or more methods, listed in order of popularity:

  • Use a package manager that uses the NPM registry, such as npm
  • Use the Nix package manager via easy-purescript-nix

If you use GitHub Actions, then you can use the setup-purescript GitHub Action to set up a PureScript toolchain on Windows, macOS, or Linux in your workflow.

Recommended Tools

If you are starting a new project in PureScript today, you will need at minimum:

  • purs, the compiler. Spago uses purs under the hood to compile your code, start an interactive repl, and so on. The compiler also provides an IDE server for editors to use.
  • spago, the build tool and package manager for PureScript. It’s used to install PureScript libraries, build PureScript code, generate documentation, and bundle PureScript-only applications.

While not necessary, I also recommend these tools for most projects:

  • psa is a configurable error-reporting frontend for the compiler. It lets you control reporting for errors and warnings. Spago automatically uses psa if it is available in your PATH.
  • pscid is a /fast/ file watcher that reports errors and suggestions in the shell. It’s essentially the same as the error reporting provided by your editor, but can often be faster.

If you are building a PureScript application, you may also like:

  • zephyr is a dead code elimination tool for PureScript. It’s used to remove unused PureScript code before compiling the result in order to trim bundle sizes.

If your application includes any JavaScript dependencies, then you are also going to need some JavaScript tools to make your code work. Specifically, you’ll want to have:

  • A JavaScript package manager for installing JavaScript dependencies, such as npm, yarn, or pnpm. I recommend using NPM.
  • A JavaScript bundler for including your JavaScript dependencies in your bundled PureScript code, such as webpack, parcel, or esbuild. I recommend esbuild for simple projects and webpack for more complex ones.
  • You may also want to use a linter like eslint to help check your JavaScript FFI code.

Editor support

The PureScript compiler has an IDE server included, which has been used to implement a PureScript language server that major editors can use. Some of the features that PureScript’s IDE tooling supports include:

  • Auto-completion, definitions & documentation on hover, and jump-to-definition
  • Automatically fix imports, missing types, and other compiler errors / warnings
  • Fast rebuilds on file save
  • …many more!

Most folks I know writing PureScript use:

Wrapping Up

I’ve kept the post nice and short this year! If you have any suggestions for other notable new tools or example projects using these tools that I should include, please let me know and I can edit the post. Thanks for reading!

23 Likes

Does anyone have experience with plugging in zephyr to purs-loader in webpack? Or perhaps does the bundle: true loader config do the job?

1 Like

Rather than using purs-loader, why not just have webpack watch the output directory on development via an alias and then pull from dce-output in production after you’ve called zephyr directly?

1 Like

I too don’t see a reason to use purs-loader, seems a kind of complicated piece of javascript in the middle, that would only slow things down.

2 Likes

I experimented with it in the past, but draft / not followed up: Integrate zephyr dead code elimination by andys8 · Pull Request #158 · ethul/purs-loader · GitHub

Draft or not, is it working? :wink:

Yes, it was. But not updated, released or proven to be reliable in production.

1 Like

As I had noted in the merge request, I decided against using purs-loader with zephyr. It was easier to skip it.