diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -5,6 +5,8 @@
 
 # Stutter
 
+[![Build Status](https://travis-ci.org/nmattia/stutter.svg?branch=master)](https://travis-ci.org/nmattia/stutter)
+
 Stutter is a string utterer.
 
 > utterer: someone who expresses in language; someone who talks (especially
@@ -14,21 +16,44 @@
 Stutter takes a string definition and crafts as many different strings as it
 can. See the [examples](#examples) section below for inspiration.
 
-# Building
+# Installing
 
-You need the Haskell build tool
-[stack](https://docs.haskellstack.org/en/stable/README/). Just run:
+## Download
 
+You can download the latest release build from the [release
+page](https://github.com/nmattia/stutter/releases). The executable depends on
+the `gmp` library (needed by the Haskell runtime system), which is most likely
+already present on your system. If not, install it from your favorite package
+manager. For Ubuntu:
+
 ``` shell
-$ stack build
+$ sudo apt-get install libgmp-dev
 ```
 
-# Installing
+Make sure `stutter` is on your `PATH`.
 
-You currently need the Haskell build tool
-[stack](https://docs.haskellstack.org/en/stable/README/). Just run:
+## Nix
 
+If you have [nix](http://nixos.org/nix/) installed, you can install `stutter`
+with the following command:
+
 ``` shell
+$ nix-env -i stutter
+```
+
+## Building
+
+The recommended way is to build `stutter` with
+[stack](https://docs.haskellstack.org/en/stable/README/). Run the following
+command in the cloned repo:
+
+``` shell
+$ stack build
+```
+
+You can then install it with
+
+``` shell
 $ stack install
 ```
 
@@ -158,3 +183,23 @@
 $ stutter 'a{42}' | wc -l
 42
 ```
+
+# Release checklist
+
+
+1. Make sure you're on (latest) master.
+
+1. Bump the version in `stutter.cabal`: `0.MAJOR.MINOR.PATCH`.
+
+> Given a version number MAJOR.MINOR.PATCH, increment the:
+>
+> MAJOR version when you make incompatible API changes,
+> MINOR version when you add functionality in a backwards-compatible manner, and
+> PATCH version when you make backwards-compatible bug fixes.
+
+1. Commit the updated `stutter.cabal` file with commit name `Release
+   v0.MAJOR.MINOR.PATCH`.
+1. Tag the commit with `git tag v0.MAJOR.MINOR.PATCH`.
+1. Push with `git push --follow-tags`.
+1. Run `cabal sdist` and `cabal upload --publish ./dist/stutter...` to upload
+   `stutter` to `hackage`.
diff --git a/exe/Stutter.hs b/exe/Stutter.hs
--- a/exe/Stutter.hs
+++ b/exe/Stutter.hs
@@ -2,7 +2,6 @@
 import Control.Monad.IO.Class (liftIO)
 import Data.Attoparsec.Text   (parseOnly, endOfInput)
 import Data.Conduit
-import Data.Monoid
 import Data.List
 
 import qualified Data.Conduit.Combinators as CL
diff --git a/src/Stutter/Producer.hs b/src/Stutter/Producer.hs
--- a/src/Stutter/Producer.hs
+++ b/src/Stutter/Producer.hs
@@ -7,12 +7,12 @@
 
 module Stutter.Producer where
 
+import Control.Monad.Catch (MonadThrow)
 import Control.Monad.IO.Class
 import Control.Monad.State
 import Control.Monad.Trans.Resource (MonadResource)
 import Data.Conduit
 import Data.Conduit.Internal (zipSources)
-import Data.Monoid
 import System.IO (stdin)
 
 import qualified Data.ByteString.Lazy     as BL
@@ -61,7 +61,7 @@
 cardinality PStdin{} = Nothing
 cardinality PText{} = pure 1
 
-produceRanges :: (Monad m) => [Range] -> Producer m T.Text
+produceRanges :: (Monad m) => [Range] -> ConduitT () T.Text m ()
 produceRanges = CL.yieldMany
               . concat
               . map rangeToList
@@ -71,14 +71,14 @@
     tshow = T.pack . show
 
 produceGroup
-  :: (MonadIO m, MonadResource m)
+  :: (MonadIO m, MonadResource m, MonadThrow m)
   => ProducerGroup
-  -> Source m T.Text
+  -> ConduitT () T.Text m ()
 produceGroup (PRanges rs) = produceRanges rs
 produceGroup (PText t) = yield t
 produceGroup (PProduct g g') =
     produceGroup g
-    .| awaitForever ( \t -> forever (yield ())
+    .| awaitForever (\t -> forever (yield ())
     .| produceGroup g'
     .| awaitForever (\t' -> yield (t <> t')))
 produceGroup (PSum g g') = produceGroup g >> produceGroup g'
diff --git a/stutter.cabal b/stutter.cabal
--- a/stutter.cabal
+++ b/stutter.cabal
@@ -1,63 +1,62 @@
-name: stutter
-version: 0.1.0.1
-cabal-version: >=1.10
-build-type: Simple
-license: MIT
-license-file: LICENSE
-copyright: (c) 2017 Nicolas Mattia
-maintainer: nicolas@nmattia.com
-homepage: https://github.com/nmattia/stutter#readme
-synopsis: (Stutter Text|String)-Utterer
-description:
-    CLI regex-like string generator
-category: Tools
-author: Nicolas Mattia
-extra-source-files:
-    README.md
+name:                stutter
+version:             0.1.0.2
+synopsis:            (Stutter Text|String)-Utterer
+description:         CLI regex-like string generator
+homepage:            https://github.com/nmattia/stutter#readme
+license:             MIT
+license-file:        LICENSE
+author:              Nicolas Mattia
+maintainer:          nicolas@nmattia.com
+copyright:           (c) 2018 Nicolas Mattia
+category:            Tools
+build-type:          Simple
+extra-source-files:  README.md
+cabal-version:       >=1.10
 
 library
-    exposed-modules:
-        Stutter.Parser
-        Stutter.Producer
-    build-depends:
-        base >=4.9.1.0 && <4.10,
-        attoparsec >=0.13.1.0 && <0.14,
-        bytestring >=0.10.8.1 && <0.11,
-        conduit >=1.2.10 && <1.3,
-        conduit-combinators >=1.1.1 && <1.2,
-        conduit-extra >=1.1.16 && <1.2,
-        mtl >=2.2.1 && <2.3,
-        resourcet >=1.1.9 && <1.2,
-        text >=1.2.2.1 && <1.3
-    default-language: Haskell2010
-    hs-source-dirs: src/
-    ghc-options: -Wall
+  hs-source-dirs:     src/
+  ghc-options:         -Wall
+  exposed-modules:
+                      Stutter.Parser
+                      Stutter.Producer
+  build-depends:
+                       base < 5
+                     , attoparsec
+                     , bytestring
+                     , conduit
+                     , conduit-combinators
+                     , conduit-extra
+                     , exceptions
+                     , mtl
+                     , resourcet
+                     , text
+  default-language:    Haskell2010
 
 executable stutter
-    main-is: Stutter.hs
-    build-depends:
-        base >=4.9.1.0 && <4.10,
-        attoparsec >=0.13.1.0 && <0.14,
-        conduit >=1.2.10 && <1.3,
-        conduit-combinators >=1.1.1 && <1.2,
-        optparse-applicative >=0.13.2.0 && <0.14,
-        stutter >=0.1.0.1 && <0.2,
-        text >=1.2.2.1 && <1.3
-    default-language: Haskell2010
-    hs-source-dirs: exe/
-    ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall
+  main-is:             Stutter.hs
+  hs-source-dirs:      exe/
+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N1 -Wall
+  build-depends:
+                       base < 5
+                     , attoparsec
+                     , conduit
+                     , conduit-combinators
+                     , optparse-applicative
+                     , stutter
+                     , text
+  default-language:    Haskell2010
 
 test-suite stutter-test
-    type: exitcode-stdio-1.0
-    main-is: Main.hs
-    build-depends:
-        base >=4.9.1.0 && <4.10,
-        attoparsec >=0.13.1.0 && <0.14,
-        snipcheck >=0.1.0.1 && <0.2,
-        stutter >=0.1.0.1 && <0.2,
-        tasty >=0.11.2.1 && <0.12,
-        tasty-ant-xml >=1.0.5 && <1.1,
-        tasty-hunit >=0.9.2 && <0.10
-    default-language: Haskell2010
-    hs-source-dirs: test/
-    ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall
+  main-is:             Main.hs
+  hs-source-dirs:      test/
+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N -Wall
+  type:                exitcode-stdio-1.0
+  build-depends:
+                       base
+                     , attoparsec
+                     , snipcheck >= 0.1.0.2
+                     , stutter
+                     , tasty
+                     , tasty-ant-xml
+                     , tasty-hunit
+  default-language:    Haskell2010
