diff --git a/.nix-helpers/nixpkgs.nix b/.nix-helpers/nixpkgs.nix
--- a/.nix-helpers/nixpkgs.nix
+++ b/.nix-helpers/nixpkgs.nix
@@ -19,107 +19,42 @@
   # however this will mean the environment will need to be rebuilt every
   # time the termonad source changes.
   indexTermonad ? false
+  # Extra Haskell packages that will be visible by Termonad when it compiles
+  # itself.  See ./termonad-with-packages.nix for an example of how to use
+  # this.
+, extraHaskellPackages ? null
 }:
 
 let
+  flake-lock = builtins.fromJSON (builtins.readFile ../flake.lock);
+
   nixpkgsSrc =
     if isNull nixpkgs
       then
         builtins.fetchTarball {
-          # Recent version of nixpkgs master as of 2021-05-09 which uses nightly-2020-05-07.
-          url = "https://github.com/NixOS/nixpkgs/archive/1c16013bd6e94da748b41cc123c6b509a23eb440.tar.gz";
-          sha256 = "1m2wif0qnci0q14plbqlb95vx214pxqgw5li86lyw6hsiy7y3zfn";
+          url = "https://github.com/NixOS/nixpkgs/archive/${flake-lock.nodes.nixpkgs.locked.rev}.tar.gz";
+          sha256 = flake-lock.nodes.nixpkgs.locked.narHash;
         }
       else nixpkgs;
 
-  compilerVersion = if isNull compiler then "ghc8104" else compiler;
-
-  # An overlay that adds termonad to all haskell package sets.
-  haskellPackagesOverlay = self: super: {
-    haskell = super.haskell // {
-      packageOverrides = hself: hsuper:
-        super.haskell.packageOverrides hself hsuper // {
-          termonad =
-            let
-              filesToIgnore = [
-                ".git"
-                ".nix-helpers"
-                "result"
-                ".stack-work"
-                "stack.yaml"
-                "stack-nightly.yaml"
-                ".travis.yml"
-              ];
-
-              src =
-                builtins.filterSource
-                  (path: type: with self.lib;
-                    ! elem (baseNameOf path) filesToIgnore &&
-                    ! any (flip hasPrefix (baseNameOf path)) [ "dist" ".ghc" ]
-                  )
-                  ./..;
-
-              extraCabal2nixOptions =
-                self.lib.optionalString buildExamples "-fbuildexamples";
-
-              termonadDrv =
-                hself.callCabal2nixWithOptions
-                  "termonad"
-                  src
-                  extraCabal2nixOptions
-                  {
-                    # There are Haskell packages called gtk3 and pcre2, which
-                    # makes these system dependencies not able to be resolved
-                    # correctly.
-                    inherit (self) gtk3 pcre2;
-                    vte_291 = self.vte;
-                  };
-            in
-            termonadDrv;
-        };
-    };
+  haskellPackagesOverlays = import ./overlays.nix;
 
-    # A Haskell package set where we know the GHC version works to compile
-    # Termonad.  This is basically just a shortcut so that other Nix files
-    # don't need to figure out the correct compiler version to use when it is
-    # not given by the user.
-    termonadKnownWorkingHaskellPkgSet = self.haskell.packages.${compilerVersion};
+  # This overlays sets some of the options use we at development time.
+  termonadOptionsOverlay = self: super: {
+    termonadCompilerVersion =
+      if isNull compiler then super.termonadCompilerVersion else compiler;
 
-    # This is a shell environment for hacking on Termonad with cabal.  See the
-    # top-level shell.nix for an explanation.
-    termonadShell =
-      let
-        # Nix-shell environment for hacking on termonad.
-        termonadEnv = self.termonadKnownWorkingHaskellPkgSet.termonad.env;
+    termonadBuildExamples = buildExamples;
 
-        # Build tools that are nice to have.  It is okay to get Haskell build tools
-        # from any Haskell package set, since they do not depend on the GHC version
-        # we are using.  We get these from the normal haskellPackages pkg set because
-        # then they don't have to be compiled from scratch.
-        convenientNativeBuildTools = [
-          self.cabal-install
-          self.gnome3.glade
-          self.haskellPackages.ghcid
-          self.hlint
-        ];
-      in
+    termonadIndexTermonad = indexTermonad;
 
-      if indexTermonad
-        then
-          termonadEnv.overrideAttrs (oldAttrs: {
-            nativeBuildInputs =
-              let
-                ghcEnvWithTermonad =
-                  self.termonadKnownWorkingHaskellPkgSet.ghcWithHoogle (hpkgs: [ hpkgs.termonad ]);
-              in
-              oldAttrs.nativeBuildInputs ++ convenientNativeBuildTools ++ [ ghcEnvWithTermonad ];
-          })
-        else
-          self.termonadKnownWorkingHaskellPkgSet.shellFor {
-            withHoogle = true;
-            packages = hpkgs: [ hpkgs.termonad ];
-            nativeBuildInputs = termonadEnv.nativeBuildInputs ++ convenientNativeBuildTools;
-          };
+    termonadExtraHaskellPackages =
+      if isNull extraHaskellPackages then super.termonadExtraHaskellPackages else extraHaskellPackages;
   };
 
-in import nixpkgsSrc { overlays = [ haskellPackagesOverlay ] ++ additionalOverlays; }
+in
+
+import nixpkgsSrc {
+  overlays =
+    haskellPackagesOverlays ++ [ termonadOptionsOverlay ] ++ additionalOverlays;
+}
diff --git a/.nix-helpers/overlays.nix b/.nix-helpers/overlays.nix
new file mode 100644
--- /dev/null
+++ b/.nix-helpers/overlays.nix
@@ -0,0 +1,154 @@
+
+let
+  # An overlay that adds termonad to all haskell package sets.
+  haskellPackagesOverlay = self: super: {
+    haskell = super.haskell // {
+      packageOverrides = hself: hsuper:
+        super.haskell.packageOverrides hself hsuper // {
+          termonad =
+            let
+              filesToIgnore = [
+                "default.nix"
+                "flake.nix"
+                "flake.lock"
+                ".git"
+                ".nix-helpers"
+                "result"
+                "shell.nix"
+                ".stack-work"
+                "stack.yaml"
+                "stack-nightly.yaml"
+                ".travis.yml"
+              ];
+
+              src =
+                builtins.path {
+                  # Naming this path makes sure that people will get the same
+                  # hash even if they checkout the termonad repo into a
+                  # directory called something else.
+                  name = "termonad-src";
+                  path = ./..;
+                  filter = path: type:
+                    with self.lib;
+                    ! elem (baseNameOf path) filesToIgnore &&
+                    ! any (flip hasPrefix (baseNameOf path)) [ "dist" ".ghc" ];
+                };
+
+              extraCabal2nixOptions =
+                self.lib.optionalString self.termonadBuildExamples "-fbuildexamples";
+
+              termonadDrv =
+                hself.callCabal2nixWithOptions
+                  "termonad"
+                  src
+                  extraCabal2nixOptions
+                  {
+                    # There are Haskell packages called gtk3 and pcre2, which
+                    # makes these system dependencies not able to be resolved
+                    # correctly.
+                    inherit (self) gtk3 pcre2;
+                    vte_291 = self.vte;
+                  };
+            in
+            termonadDrv;
+        };
+    };
+
+    # This defines which compiler version is used to build Termonad.
+    #
+    # Either this, or termonadKnownWorkingHaskellPkgSet can be changed in an overlay
+    # if you want to use a different GHC to build Termonad.
+    termonadCompilerVersion = "ghc902";
+
+    # A Haskell package set where we know the GHC version works to compile
+    # Termonad.  This is basically just a shortcut so that other Nix files
+    # don't need to figure out the correct compiler version to use when it is
+    # not given by the user.
+    termonadKnownWorkingHaskellPkgSet = self.haskell.packages.${self.termonadCompilerVersion};
+
+    # See ./nixpkgs.nix for an explanation of that this does.
+    termonadBuildExamples = false;
+
+    # See ./nixpkgs.nix for an explanation of that this does.
+    termonadIndexTermonad = false;
+
+    # This is a shell environment for hacking on Termonad with cabal.  See the
+    # top-level shell.nix for an explanation.
+    termonadShell =
+      let
+        # Nix-shell environment for hacking on termonad.
+        termonadEnv = self.termonadKnownWorkingHaskellPkgSet.termonad.env;
+
+        # Build tools that are nice to have.  It is okay to get Haskell build tools
+        # from any Haskell package set, since they do not depend on the GHC version
+        # we are using.  We get these from the normal haskellPackages pkg set because
+        # then they don't have to be compiled from scratch.
+        convenientNativeBuildTools = [
+          self.cabal-install
+          self.glade
+          self.haskellPackages.ghcid
+          self.hlint
+        ];
+      in
+
+      if self.termonadIndexTermonad
+        then
+          termonadEnv.overrideAttrs (oldAttrs: {
+            nativeBuildInputs =
+              let
+                ghcEnvWithTermonad =
+                  self.termonadKnownWorkingHaskellPkgSet.ghcWithHoogle (hpkgs: [ hpkgs.termonad ]);
+              in
+              oldAttrs.nativeBuildInputs ++ convenientNativeBuildTools ++ [ ghcEnvWithTermonad ];
+          })
+        else
+          self.termonadKnownWorkingHaskellPkgSet.shellFor {
+            withHoogle = true;
+            packages = hpkgs: [ hpkgs.termonad ];
+            nativeBuildInputs = termonadEnv.nativeBuildInputs ++ convenientNativeBuildTools;
+          };
+
+    # Default Haskell packages that you can use in your Termonad configuration.
+    # This is only used if the user doesn't specify the extraHaskellPackages
+    # option.
+    termonadExtraHaskellPackages = hpkgs: with hpkgs; [
+      colour
+      lens
+    ];
+
+    termonad-with-packages =
+      let
+        # GHC environment that has termonad available, as well as the packages
+        # specified above in extraHaskellPackages.
+        env =
+          self.termonadKnownWorkingHaskellPkgSet.ghcWithPackages
+            (hpkgs: [ hpkgs.termonad ] ++ self.termonadExtraHaskellPackages hpkgs);
+      in
+      self.stdenv.mkDerivation {
+        name = "termonad-with-packages-ghc-${env.version}";
+        buildInputs = [
+          self.gdk_pixbuf
+          self.gnome3.adwaita-icon-theme
+          self.hicolor-icon-theme
+        ];
+        nativeBuildInputs = [ self.wrapGAppsHook ];
+        dontBuild = true;
+        unpackPhase = ":";
+        # Using installPhase instead of buildCommand was recommended here:
+        # https://github.com/cdepillabout/termonad/pull/109
+        installPhase = ''
+          runHook preInstall
+          mkdir -p $out/bin
+          ln -sf ${env}/bin/termonad $out/bin/termonad
+          gappsWrapperArgs+=(
+            --set NIX_GHC "${env}/bin/ghc"
+          )
+          runHook postInstall
+        '';
+        preferLocalBuild = true;
+        allowSubstitutes = false;
+      };
+  };
+in
+
+[ haskellPackagesOverlay ]
diff --git a/.nix-helpers/stack-shell.nix b/.nix-helpers/stack-shell.nix
--- a/.nix-helpers/stack-shell.nix
+++ b/.nix-helpers/stack-shell.nix
@@ -8,9 +8,9 @@
   buildInputs = [
     cairo
     git
-    gnome3.vte
     gobjectIntrospection
     gtk3
+    vte
     zlib
   ];
   ghc = termonadKnownWorkingHaskellPkgSet.ghc;
diff --git a/.nix-helpers/termonad-with-packages.nix b/.nix-helpers/termonad-with-packages.nix
--- a/.nix-helpers/termonad-with-packages.nix
+++ b/.nix-helpers/termonad-with-packages.nix
@@ -87,50 +87,17 @@
 # }
 # ```
 
-let
-  # Default Haskell packages that you can use in your Termonad configuration.
-  # This is only used if the user doesn't specify the extraHaskellPackages
-  # option.
-  defaultPackages = hpkgs: with hpkgs; [
-    colour
-    lens
-  ];
-in
-
-{ extraHaskellPackages ? defaultPackages
+{ extraHaskellPackages ? null
 , nixpkgs ? null
 , additionalOverlays ? []
 , compiler ? null
 , buildExamples ? false
 }@args:
 
-with (import ./nixpkgs.nix { inherit compiler nixpkgs additionalOverlays buildExamples; });
-
 let
-  # GHC environment that has termonad available, as well as the packages
-  # specified above in extraHaskellPackages.
-  env =
-    termonadKnownWorkingHaskellPkgSet.ghcWithPackages
-      (hpkgs: [ hpkgs.termonad ] ++ extraHaskellPackages hpkgs);
+  pkgs = import ./nixpkgs.nix {
+    inherit compiler nixpkgs additionalOverlays buildExamples extraHaskellPackages;
+  };
 in
 
-stdenv.mkDerivation {
-  name = "termonad-with-packages-ghc-${env.version}";
-  buildInputs = [ gdk_pixbuf gnome3.adwaita-icon-theme hicolor-icon-theme ];
-  nativeBuildInputs = [ wrapGAppsHook ];
-  dontBuild = true;
-  unpackPhase = ":";
-  # Using installPhase instead of buildCommand was recommended here:
-  # https://github.com/cdepillabout/termonad/pull/109
-  installPhase = ''
-    runHook preInstall
-    mkdir -p $out/bin
-    ln -sf ${env}/bin/termonad $out/bin/termonad
-    gappsWrapperArgs+=(
-      --set NIX_GHC "${env}/bin/ghc"
-    )
-    runHook postInstall
-  '';
-  preferLocalBuild = true;
-  allowSubstitutes = false;
-}
+pkgs.termonad-with-packages
diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,14 @@
+## 4.2.0.1
+
+*   Added an
+    [example](https://github.com/cdepillabout/termonad/blob/50b20dc3f5bb2a4a080fd703e818bf721c9c3884/example-config/ExampleDraculaColourExtension.hs)
+    of how to setup a Dracula color scheme. Thanks @craigem!
+    [#195](https://github.com/cdepillabout/termonad/pull/195)
+
+*   Bump to allow both aeson-1 and aeson-2.
+    Thanks [@gelisam](https://github.com/gelisam)!
+    [#210](https://github.com/cdepillabout/termonad/pull/210)
+
 ## 4.2.0.0
 
 *   Add new options `highlightFgColour` and `highlightBgColour` for setting
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -63,7 +63,7 @@
 
 ### Arch Linux
 
-First, you must install the required GTK system libraries:
+First, you must install the required Gnome/GTK system libraries:
 
 ```sh
 $ pacman -S vte3 gobject-introspection
@@ -78,9 +78,30 @@
 $ stack install
 ```
 
+Note that Termonad depends on the [`haskell-gi`](https://github.com/haskell-gi/haskell-gi) family of Haskell libraries.  `haskell-gi` contains Haskell wrappers for for Gnome/GTK system libraries.  It uses the [GObject Introspection](https://gi.readthedocs.io/en/latest/) functionality from the Gnome libraries.
+
+One problem that Arch users often run into is that their system Gnome/GTK libraries are newer than what the `haskell-gi` dependencies from Stackage support.  If you run into this problem, there are a couple things you can try:
+
+- Manually switch to a newer Stackage resolver (probably Stackage Nightly).  Newer Stackage resolvers often have newer versions of the `haskell-gi` libraries.  Newer versions of the `haskell-gi` libraries are more likely to support your newer system Gnome/GTK libraries.  If you get something working like this, please open a PR.
+- Use `cabal` for building Termonad instead of `stack`.  Make sure `cabal`'s constraint solver picks the latest versions of the `haskell-gi` libraries on Hackage.
+- Use Nix for installing Termonad.
+
+My suggestion is to use Nix, since it is highly likely to "just work" (because with Nix, _all_ libraries are pinned to known working versions, even system libraries).
+
 ### Ubuntu / Debian
 
-First, you must install the required GTK system libraries:
+Termonad can be installed through `apt` on Debian and Ubuntu:
+
+```console
+$ sudo apt install termonad libghc-termonad-dev
+```
+
+Note that the `libghc-termonad-dev` package is necessary if you want to be able
+to compile the Haskell-based settings file, `termonad.hs`.
+
+#### Compiling from source on Ubuntu / Debian
+
+First, you must install the required Gnome/GTK system libraries:
 
 ```sh
 $ apt-get install gobject-introspection libgirepository1.0-dev libgtk-3-dev libvte-2.91-dev libpcre2-dev
diff --git a/default.nix b/default.nix
--- a/default.nix
+++ b/default.nix
@@ -23,5 +23,5 @@
 , buildExamples ? false
 }@args:
 
-import .nix-helpers/termonad-with-packages.nix args
+(import .nix-helpers/nixpkgs.nix args).termonad-with-packages
 
diff --git a/example-config/ExampleDraculaColourExtension.hs b/example-config/ExampleDraculaColourExtension.hs
new file mode 100644
--- /dev/null
+++ b/example-config/ExampleDraculaColourExtension.hs
@@ -0,0 +1,112 @@
+{-# LANGUAGE OverloadedStrings #-}
+-- | This is an example Termonad configuration that shows how to use the
+-- Dracula colour scheme https://draculatheme.com/
+
+module Main where
+
+import Data.Maybe (fromMaybe)
+import Termonad
+  ( CursorBlinkMode(CursorBlinkModeOn)
+  , Option(Set)
+  , ShowScrollbar(ShowScrollbarNever)
+  , TMConfig
+  , confirmExit
+  , cursorBlinkMode
+  , defaultConfigOptions
+  , defaultTMConfig
+  , options
+  , showMenu
+  , showScrollbar
+  , start
+  , FontConfig
+  , FontSize(FontSizePoints)
+  , defaultFontConfig
+  , fontConfig
+  , fontFamily
+  , fontSize
+  )
+import Termonad.Config.Colour
+  ( AlphaColour
+  , ColourConfig
+  , Palette(ExtendedPalette)
+  , addColourExtension
+  , createColour
+  , createColourExtension
+  , defaultColourConfig
+  , defaultStandardColours
+  , defaultLightColours
+  , backgroundColour
+  , foregroundColour
+  , palette
+  , List8
+  , mkList8
+  )
+
+-- This is our main 'TMConfig'.  It holds all of the non-colour settings
+-- for Termonad.
+--
+-- This shows how a few settings can be changed.
+myTMConfig :: TMConfig
+myTMConfig =
+  defaultTMConfig
+    { options =
+        defaultConfigOptions
+          { showScrollbar = ShowScrollbarNever
+          , confirmExit = False
+          , showMenu = False
+          , cursorBlinkMode = CursorBlinkModeOn
+          , fontConfig = fontConf
+          }
+    }
+
+-- This is our Dracula 'ColourConfig'.
+dracula :: ColourConfig (AlphaColour Double)
+dracula =
+  defaultColourConfig
+    -- Set the default background & foreground colour of text of the terminal.
+    { backgroundColour = Set (createColour  40  42  54)  -- black.0
+    , foregroundColour = Set (createColour 248 248 242)  -- white.7
+    -- Set the extended palette that has 2 Vecs of 8 Dracula palette colours
+    , palette = ExtendedPalette draculaNormal draculaBright
+    }
+  where
+    draculaNormal :: List8 (AlphaColour Double)
+    draculaNormal = fromMaybe defaultStandardColours $ mkList8
+      [ createColour  40  42  54 -- black.0
+      , createColour 255  85  85 -- red.1
+      , createColour  80 250 123 -- green.2
+      , createColour 241 250 140 -- yellow.3
+      , createColour 189 147 249 -- blue.4
+      , createColour 255 121 198 -- magenta.5
+      , createColour 139 233 253 -- cyan.6
+      , createColour 191 191 191 -- white.7
+      ]
+
+    draculaBright :: List8 (AlphaColour Double)
+    draculaBright = fromMaybe defaultStandardColours $ mkList8
+      [ createColour  77  77  77 -- black.8
+      , createColour 255 110 103 -- red.9
+      , createColour  90 247 142 -- green.10
+      , createColour 244 249 157 -- yellow.11
+      , createColour 202 169 250 -- blue.12
+      , createColour 255 146 208 -- magenta.13
+      , createColour 154 237 254 -- cyan.14
+      , createColour 230 230 230 -- white.15
+      ]
+
+fontConf =
+  defaultFontConfig
+    { fontFamily = "Monospace"
+    , fontSize = FontSizePoints 12
+    }
+
+main :: IO ()
+main = do
+  -- First, create the colour extension based on either PaperColor modules.
+  myColourExt <- createColourExtension dracula
+
+  -- Update 'myTMConfig' with our colour extension.
+  let newTMConfig = addColourExtension myTMConfig myColourExt
+
+  -- Start Termonad with our updated 'TMConfig'.
+  start newTMConfig
diff --git a/flake.lock b/flake.lock
new file mode 100644
--- /dev/null
+++ b/flake.lock
@@ -0,0 +1,27 @@
+{
+  "nodes": {
+    "nixpkgs": {
+      "locked": {
+        "lastModified": 1645575067,
+        "narHash": "sha256-GoJYyj6eYv+NYODMj5ZHiunuRfj5dHsxBPafhjdZkDc=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "2b5c8147f5889b57f16de48015e18381ee65f63a",
+        "type": "github"
+      },
+      "original": {
+        "owner": "NixOS",
+        "ref": "haskell-updates",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "root": {
+      "inputs": {
+        "nixpkgs": "nixpkgs"
+      }
+    }
+  },
+  "root": "root",
+  "version": 7
+}
diff --git a/flake.nix b/flake.nix
new file mode 100644
--- /dev/null
+++ b/flake.nix
@@ -0,0 +1,100 @@
+{
+  description = "A VTE-based terminal emulator configurable in Haskell";
+
+  # Nixpkgs / NixOS version to use.
+  #
+  # TODO: Nixpkgs is switching to use GHC-9.0.2 as the default compiler as of
+  # 2022-02-21, but the switch has currently only happened on the
+  # haskell-updates branch.  This temporarily makes Termonad use that branch.
+  # When https://github.com/NixOS/nixpkgs/pull/160733 is merged into master,
+  # switch back to nixos-unstable.
+  inputs.nixpkgs.url = "github:NixOS/nixpkgs/haskell-updates";
+  # inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
+
+  outputs = { self, nixpkgs }:
+    let
+
+      # Generate a user-friendly version numer.
+      version = builtins.substring 0 8 self.lastModifiedDate;
+
+      # System types to support.
+      #
+      # TODO: Since callCabal2nix uses IFD, adding multiple systems to
+      # supportedSystems doesn't currently work with flakes.  Commands like
+      # `nix flake check` and `nix flake show` don't work.
+      #
+      # https://github.com/NixOS/nix/issues/4265
+      #
+      # Termonad is likely to also work aarch64-linux, but you'll have to edit
+      # this line to enable it.
+      supportedSystems = [ "x86_64-linux" ];
+
+      # Helper function to generate an attrset '{ x86_64-linux = f "x86_64-linux"; ... }'.
+      forAllSystems = f: nixpkgs.lib.genAttrs supportedSystems (system: f system);
+
+      # Nixpkgs instantiated for supported system types.
+      nixpkgsFor = forAllSystems (system: import nixpkgs { inherit system; overlays = [ self.overlay ]; });
+
+    in
+
+    {
+
+      # A Nixpkgs overlay that defines Termonad.
+      overlay = final: prev:
+        let
+          overlays = import ./.nix-helpers/overlays.nix;
+        in
+        prev.lib.composeManyExtensions overlays final prev;
+
+      # Provide some binary packages for selected system types.
+      packages = forAllSystems (system:
+        let
+          pkgs = nixpkgsFor.${system};
+        in {
+          termonad = pkgs.termonad-with-packages;
+        }
+      );
+
+      # The default package for 'nix build'. This makes sense if the
+      # flake provides only one package or there is a clear "main"
+      # package.
+      defaultPackage = forAllSystems (system: self.packages.${system}.termonad);
+
+      devShell = forAllSystems (system: nixpkgsFor.${system}.termonadShell);
+
+      defaultApp = forAllSystems (system: self.apps.${system}.termonad);
+
+      apps = forAllSystems (system: {
+        termonad = {
+          type = "app";
+          program = "${self.packages.${system}.termonad}/bin/termonad";
+        };
+      });
+
+      # Tests run by 'nix flake check' and by Hydra.
+      # checks = forAllSystems
+      #   (system:
+      #     with nixpkgsFor.${system};
+      #     {
+      #       inherit (self.packages.${system}) hello;
+
+      #       # Additional tests, if applicable.
+      #       test = stdenv.mkDerivation {
+      #         name = "hello-test-${version}";
+
+      #         buildInputs = [ hello ];
+
+      #         unpackPhase = "true";
+
+      #         buildPhase = ''
+      #           echo 'running some integration tests'
+      #           [[ $(hello) = 'Hello Nixers!' ]]
+      #         '';
+
+      #         installPhase = "mkdir -p $out";
+      #       };
+      #     }
+      #   );
+
+    };
+}
diff --git a/src/Termonad/Gtk.hs b/src/Termonad/Gtk.hs
--- a/src/Termonad/Gtk.hs
+++ b/src/Termonad/Gtk.hs
@@ -1,5 +1,3 @@
-{-# LANGUAGE CPP #-}
-
 module Termonad.Gtk where
 
 import Termonad.Prelude
diff --git a/src/Termonad/PreferencesFile.hs b/src/Termonad/PreferencesFile.hs
--- a/src/Termonad/PreferencesFile.hs
+++ b/src/Termonad/PreferencesFile.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 
 module Termonad.PreferencesFile where
 
@@ -5,6 +6,9 @@
 
 import Control.Monad.Trans.Except (ExceptT(..), runExceptT, throwE, withExceptT)
 import Data.Aeson (Result(..), fromJSON)
+#if MIN_VERSION_aeson(2, 0, 0)
+import qualified Data.Aeson.KeyMap as KeyMap
+#endif
 import qualified Data.HashMap.Strict as HashMap
 import Data.Yaml (ParseException, ToJSON (toJSON), decodeFileEither, encode, prettyPrintParseException)
 import Data.Yaml.Aeson (Value(..))
@@ -23,6 +27,10 @@
   , defaultConfigOptions
   )
 
+-- $setup
+--
+-- >>> import Data.Aeson(object, (.=))
+
 -- | Get the path to the preferences file @~\/.config\/termonad\/termonad.yaml@.
 getPreferencesFile :: IO FilePath
 getPreferencesFile = do
@@ -99,17 +107,17 @@
 --
 -- Note that 'Value's in 'Array's are not recursed into:
 --
--- >>> let obj1 = Object $ HashMap.singleton "hello" (Number 2)
--- >>> let obj2 = Object $ HashMap.singleton "hello" (String "bye")
+-- >>> let obj1 = object ["hello" .= Number 2]
+-- >>> let obj2 = object ["hello" .= String "bye"]
 -- >>> mergeObjVals (Array [obj1]) (Array [obj2])
 -- Array [Object (fromList [("hello",Number 2.0)])]
 --
 -- 'Object's are recursed into.  Unique keys from both Maps will be used.
 -- Keys that are in both Maps will be merged according to the rules above:
 --
--- >>> let hash1 = HashMap.fromList [("hello", Number 1), ("bye", Number 100)]
--- >>> let hash2 = HashMap.fromList [("hello", Number 2), ("goat", String "chicken")]
--- >>> mergeObjVals (Object hash1) (Object hash2)
+-- >>> let object1 = object ["hello" .= Number 1, "bye" .= Number 100]
+-- >>> let object2 = object ["hello" .= Number 2, "goat" .= String "chicken"]
+-- >>> mergeObjVals object1 object2
 -- Object (fromList [("bye",Number 100.0),("goat",String "chicken"),("hello",Number 1.0)])
 --
 -- 'Value's of different types will use the second 'Value':
@@ -133,8 +141,22 @@
   case (optsFromFile, optsDefault) of
     -- Both the options from the file and the default options are an Object
     -- here.  Recursively merge the keys and values.
-    (Object optsFromFileHashMap, Object optsDefaultHashMap) ->
-      Object $ HashMap.unionWith mergeObjVals optsFromFileHashMap optsDefaultHashMap
+    (Object optsFromFileKeyMap, Object optsDefaultKeyMap) ->
+      let
+#if MIN_VERSION_aeson(2, 0, 0)
+          hashMapFromKeyMap = KeyMap.toHashMap
+          keyMapFromHashMap = KeyMap.fromHashMap
+#else
+          hashMapFromKeyMap = id
+          keyMapFromHashMap = id
+#endif
+          optsFromFileHashMap = hashMapFromKeyMap optsFromFileKeyMap
+          optsDefaultHashMap = hashMapFromKeyMap optsDefaultKeyMap
+          optsResultHashMap = HashMap.unionWith mergeObjVals
+                                optsFromFileHashMap
+                                optsDefaultHashMap
+          optsResultKeyMap = keyMapFromHashMap optsResultHashMap
+      in Object optsResultKeyMap
     -- Both the value from the file and the default value are the same type.
     -- Use the value from the file.
     --
diff --git a/termonad.cabal b/termonad.cabal
--- a/termonad.cabal
+++ b/termonad.cabal
@@ -1,5 +1,5 @@
 name:                termonad
-version:             4.2.0.0
+version:             4.2.0.1
 synopsis:            Terminal emulator configurable in Haskell
 description:
   Termonad is a terminal emulator configurable in Haskell.  It is extremely
@@ -23,11 +23,14 @@
 extra-source-files:  README.md
                    , CHANGELOG.md
                    , default.nix
+                   , flake.nix
+                   , flake.lock
                    , glade/preferences.glade
                    , glade/README.md
                    , img/termonad.png
                    , .nix-helpers/nixops.nix
                    , .nix-helpers/nixpkgs.nix
+                   , .nix-helpers/overlays.nix
                    , .nix-helpers/stack-shell.nix
                    , .nix-helpers/termonad-with-packages.nix
                    , shell.nix
@@ -207,6 +210,19 @@
 
 executable termonad-example-colour-extension
   main-is:             example-config/ExampleColourExtension.hs
+  build-depends:       base
+                     , termonad
+                     , colour
+  default-language:    Haskell2010
+  ghc-options:         -Wall -Wincomplete-uni-patterns -Wincomplete-record-updates -threaded -rtsopts -with-rtsopts=-N
+
+  if flag(buildexamples)
+    buildable:         True
+  else
+    buildable:         False
+
+executable termonad-example-colour-extension-dracula
+  main-is:             example-config/ExampleDraculaColourExtension.hs
   build-depends:       base
                      , termonad
                      , colour
diff --git a/test/readme/README.lhs b/test/readme/README.lhs
--- a/test/readme/README.lhs
+++ b/test/readme/README.lhs
@@ -63,7 +63,7 @@
 
 ### Arch Linux
 
-First, you must install the required GTK system libraries:
+First, you must install the required Gnome/GTK system libraries:
 
 ```sh
 $ pacman -S vte3 gobject-introspection
@@ -78,9 +78,30 @@
 $ stack install
 ```
 
+Note that Termonad depends on the [`haskell-gi`](https://github.com/haskell-gi/haskell-gi) family of Haskell libraries.  `haskell-gi` contains Haskell wrappers for for Gnome/GTK system libraries.  It uses the [GObject Introspection](https://gi.readthedocs.io/en/latest/) functionality from the Gnome libraries.
+
+One problem that Arch users often run into is that their system Gnome/GTK libraries are newer than what the `haskell-gi` dependencies from Stackage support.  If you run into this problem, there are a couple things you can try:
+
+- Manually switch to a newer Stackage resolver (probably Stackage Nightly).  Newer Stackage resolvers often have newer versions of the `haskell-gi` libraries.  Newer versions of the `haskell-gi` libraries are more likely to support your newer system Gnome/GTK libraries.  If you get something working like this, please open a PR.
+- Use `cabal` for building Termonad instead of `stack`.  Make sure `cabal`'s constraint solver picks the latest versions of the `haskell-gi` libraries on Hackage.
+- Use Nix for installing Termonad.
+
+My suggestion is to use Nix, since it is highly likely to "just work" (because with Nix, _all_ libraries are pinned to known working versions, even system libraries).
+
 ### Ubuntu / Debian
 
-First, you must install the required GTK system libraries:
+Termonad can be installed through `apt` on Debian and Ubuntu:
+
+```console
+$ sudo apt install termonad libghc-termonad-dev
+```
+
+Note that the `libghc-termonad-dev` package is necessary if you want to be able
+to compile the Haskell-based settings file, `termonad.hs`.
+
+#### Compiling from source on Ubuntu / Debian
+
+First, you must install the required Gnome/GTK system libraries:
 
 ```sh
 $ apt-get install gobject-introspection libgirepository1.0-dev libgtk-3-dev libvte-2.91-dev libpcre2-dev
