One of the downsides of developing web applications in Haskell is the long recompilation cycle. While working on code, it is convenient to have an editor open in one window and a browser open in another. When making changes to your Haskell code, it is nice to be able to immediately flip to your browser and interact with the updated web application.
However, long compile times for Haskell prevent this from working smoothly. Running
stack build && stack exec mywebapp every time you make a change to your Haskell code is annoying. It takes time for
stack build to finish. It also doesn't happen automatically on file change.
ghcid can be used to make this process much quicker and smoother.
ghcid is used to quickly reload your Haskell code every time it changes. It loads your Haskell project in a GHCi session and uses the GHC API to recompile your source code on every file change.
ghcid is used like the following (for a
stack ghci to load your code in GHCi. Then, on each file change,
ghcid automatically runs the GHCi command
:reload to recompile and reload all your Haskell modules. If there is a compilation error, it is reported by
:reload within GHCi is very fast, so using
ghcid for development is quite an improvement over manually re-running
However, the above command doesn't automatically run your web application if compilation succeeds.
Despite its name, the
--test flag can be used for running your web application whenever compilation succeeds.
--test flag takes any valid GHCi expression as an argument. There are two common expressions that are used.
Any valid Haskell expression. A function with the type
IO ()that runs your web application is usually used. For instance, if you have a function
defaultMain :: IO ()in your codebase, you can run that function whenever your haskell code compiles correctly with the following command:
Any valid GHCi command. For instance, the GHCi command
main :: IO ()function defined in your Haskell project. You can use the following command to do this:
ghcid will run the expression you have passed to
--test if compilation succeeds. When
ghcid detects a change in one of your Haskell files, it will kill the expression passed to
--test, recompile the code, then re-run the expression.
This is perfect for use with web applications. As long as your code compiles correctly, your web application will always be running. Recompilation is very quick, so you should almost always be able to access it from the browser.
Running Despite GHC Warnings
By default, GHCi doesn't re-run the expression passed to
--test if there are GHC compilation warnings. This is sometimes inconvenient. In order to get around this, you can use the
--warnings flag. This forces
ghcid to run the expression even if there are still GHC warnings.
Here is an example of using the
--test flag is used to actually run tests as long as compilation has succeeded.
Here's an example of how you can do this with
stack ghci --test --main-is mypackage:mypackage-test command runs GHCi using
stack in the Haskell package called
mypackage. This assumes you have a test suite defined in your
.cabal file called
ghcid command will re-run the
main :: IO () function defined in the
mypackage-test test suite whenever there is a change in any of your Haskell files.
There are a couple other often-used methods for re-building and running a web application on file change.
If you're using
stack, the easiest method is probably as follows:
This assumes you have an executable defined in your
This is easy, but
stack build --fast is normally slower than reloading in GHCi.
ghcid is a nice command for a fast feedback loop when doing Haskell development. It allows for (mostly) stress-free development of web applications in Haskell.