12 releases

0.3.8 Oct 5, 2023
0.3.7 Oct 5, 2023
0.3.6 Sep 28, 2023
0.3.0 Aug 25, 2023
0.1.1 Aug 7, 2023

#9 in #watchexec

MIT license

250KB
5.5K SLoC

Note: ghcid-ng has been renamed to ghciwatch

Please use the ghciwatch crate instead.

ghcid-ng

The next generation of ghcid, a ghci-based file watcher and recompiler. ghcid-ng watches your modules for changes and reloads them in a ghci session, displaying any errors.

Why a reimplementation?

When we started working on ghcid-ng, ghcid suffered from some significant limitations. In particular, ghcid couldn't deal with moved or deleted modules, and wouldn't detect new directories because it can't easily update the set of files being watched at runtime. We've also seen memory leaks requiring multiple restarts per day. Due to the ghcid codebase's relatively small size, a reimplementation seemed like a more efficient path forward than making wide-spanning changes to an unfamiliar codebase.

Why Rust?

Rust makes it easy to ship static binaries. Rust also shares many features with Haskell: a Hindley-Milner type system with inference, pattern matching, and immutability by default. Rust can also interoperate with Haskell, so in the future we'll be able to ship ghcid-ng as a Hackage package natively. Finally, Rust is home to the excellent cross-platform and battle-tested watchexec library, used to implement the watchexec binary and cargo-watch, which solves a lot of the thorny problems of watching files for us.

Why not just use watchexec or similar?

Recompiling a project when files change is a fairly common development task, so there's a bunch of tools with this same rough goal. In particular, watchexec is a nice off-the-shelf solution. Why not just run watchexec -e hs cabal build? In truth, ghcid-ng doesn't just recompile the project when it detects changes. It instead manages an interactive ghci session, instructing it to reload modules when relevant. This involves a fairly complex dance of communicating to ghci over stdin and parsing its stdout, so a bespoke tool is useful here.

Dependencies

~24–56MB
~1M SLoC