diff --git a/ChangeLog.md b/ChangeLog.md
deleted file mode 100644
index 26a2a1a9294076bcba354b833189edc594d2214d..0000000000000000000000000000000000000000
--- a/ChangeLog.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Changelog for qbar
-
-## Unreleased changes
diff --git a/cabal.project b/cabal.project
new file mode 100644
index 0000000000000000000000000000000000000000..f44a24c63747ed4eb654da9ca84338cf1e223380
--- /dev/null
+++ b/cabal.project
@@ -0,0 +1 @@
+packages: */*.cabal
diff --git a/flake.nix b/flake.nix
index 8d30d187145d2f92a5c3092a2848c6f16969a6f9..18bc0964bc94c17e0f867e04e2bc893d733c1f68 100644
--- a/flake.nix
+++ b/flake.nix
@@ -1,44 +1,65 @@
 {
-  outputs = { self, nixpkgs }: with nixpkgs.lib; let
+  inputs.nixpkgs.url = github:NixOS/nixpkgs/nixos-unstable;
 
+  outputs = { self, nixpkgs }:
+  with nixpkgs.lib;
+  let
     systems = platforms.unix;
-    forAllSystems = f: genAttrs systems (system: f system);
-
+    forAllSystems = fn: (genAttrs systems (system:
+      fn (import nixpkgs {
+        inherit system;
+        overlays = [
+          self.overlays.default
+        ];
+      })
+    ));
+    getHaskellPackages = pkgs: pattern: pipe pkgs.haskell.packages [
+      attrNames
+      (filter (x: !isNull (strings.match pattern x)))
+      (sort (x: y: x>y))
+      (map (x: pkgs.haskell.packages.${x}))
+      head
+    ];
   in {
+    packages = forAllSystems (pkgs: let
+      ghc92 = getHaskellPackages pkgs "ghc92.";
+    in rec {
+      default = qbar;
+      qbar = ghc92.qbar;
+    });
 
-    packages = forAllSystems (system:
-      let pkgs = import nixpkgs { inherit system; overlays = [ self.overlay ]; };
-      in rec {
-        default = qbar;
-        qbar = pkgs.haskellPackages.qbar;
-      }
-    );
-
-    defaultPackage = forAllSystems (system: self.packages.${system}.qbar);
+    overlays = {
+      default = final: prev: {
+        haskell = prev.haskell // {
+          packageOverrides = hfinal: hprev: prev.haskell.packageOverrides hfinal hprev // {
+            qbar = hfinal.callCabal2nix "qbar" ./qbar {};
 
-    overlay = final: prev: {
-      haskell = prev.haskell // {
-        packageOverrides = hfinal: hprev: prev.haskell.packageOverrides hfinal hprev // {
-          qbar = import ./. {
-            pkgs = final;
-            haskellPackages = hfinal;
+            # https://gitlab.haskell.org/ghc/ghc/-/issues/22425
+            ListLike = final.haskell.lib.dontCheck hprev.ListLike;
           };
         };
       };
     };
 
-    devShell = forAllSystems (system:
+    devShells = forAllSystems (pkgs:
       let
-        pkgs = nixpkgs.legacyPackages.${system};
-      in pkgs.mkShell {
-        inputsFrom = [ self.packages.${system}.default.env ];
-        packages = [
-          pkgs.cabal-install
-          pkgs.zsh
-          pkgs.entr
-          pkgs.ghcid
-          pkgs.haskell-language-server
-        ];
+        haskellPackages = getHaskellPackages pkgs "ghc92.";
+      in rec {
+        default = haskellPackages.shellFor {
+          packages = hpkgs: [
+            hpkgs.qbar
+          ];
+          nativeBuildInputs = [
+            haskellPackages.haskell-language-server
+            pkgs.cabal-install
+            pkgs.hlint
+
+            # in addition, for ghcid-wrapper
+            pkgs.zsh
+            pkgs.entr
+            pkgs.ghcid
+          ];
+        };
       }
     );
 
diff --git a/ghcid b/ghcid
deleted file mode 100755
index c3d50ccb6cab4f1a767993720c0832b6f8b6c2b5..0000000000000000000000000000000000000000
--- a/ghcid
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/env -S nix develop . -c zsh
-
-print -P %F{yellow}Cleaning repository%f
-nix develop -c cabal clean
-
-(git ls-files test; git ls-files '*.cabal'; git ls-files 'flake.*') | \
-  entr -r \
-    nix develop -c \
-      ghcid \
-        --warnings \
-        "--command=cabal repl lib:qbar" \
-        "--test=:! \
-          cabal test --disable-optimisation --enable-debug-info=2 --test-show-details=direct --ghc-option -fdiagnostics-color=always && \
-          cabal build --disable-optimisation --enable-debug-info=2 --ghc-option -fdiagnostics-color=always && \
-          zsh -c 'print -P %F{green}Build and tests passed%f' \
-        "
diff --git a/ghcid-wrapper b/ghcid-wrapper
new file mode 100755
index 0000000000000000000000000000000000000000..dbee7e5b31ad6fb1af93191ab2db846c6de3bb7f
--- /dev/null
+++ b/ghcid-wrapper
@@ -0,0 +1,38 @@
+#!/usr/bin/env -S nix develop -L -c zsh
+
+set -euo pipefail
+
+readonly target=${1:-lib:qbar}
+readonly executable=${2:-}
+
+if [[ -n $executable ]]
+then
+  run_executable="cabal run \
+    --disable-optimisation \
+    --ghc-option -fdiagnostics-color=always \
+    $executable \
+    "
+else
+  run_executable=true
+fi
+
+print -P %F{yellow}Cleaning repository%f
+cabal clean
+
+(
+  git ls-files 'examples/*' '*/test' '*/*.cabal' 'flake.*'
+  echo "ghcid-wrapper"
+) | \
+  entr -r \
+    nix develop -L -c \
+      ghcid \
+        --warnings \
+        "--command=cabal repl $target" \
+        "--test=:! \
+          cabal test \
+            --disable-optimisation \
+            --test-show-details=direct \
+            --ghc-option -fdiagnostics-color=always && \
+          $run_executable && \
+          zsh -c 'print -P %F{green}Build and tests passed%f' \
+        "
diff --git a/hie.yaml b/hie.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..04cd24395e4d108febbd22b6ce41a92f7fe0d065
--- /dev/null
+++ b/hie.yaml
@@ -0,0 +1,2 @@
+cradle:
+  cabal:
diff --git a/LICENSE b/qbar/LICENSE
similarity index 100%
rename from LICENSE
rename to qbar/LICENSE
diff --git a/app/Main.hs b/qbar/app/Main.hs
similarity index 100%
rename from app/Main.hs
rename to qbar/app/Main.hs
diff --git a/bin/install b/qbar/bin/install
similarity index 100%
rename from bin/install
rename to qbar/bin/install
diff --git a/bin/run b/qbar/bin/run
similarity index 100%
rename from bin/run
rename to qbar/bin/run
diff --git a/bin/run-sway b/qbar/bin/run-sway
similarity index 100%
rename from bin/run-sway
rename to qbar/bin/run-sway
diff --git a/qbar.cabal b/qbar/qbar.cabal
similarity index 61%
rename from qbar.cabal
rename to qbar/qbar.cabal
index a9b6227336070f7f5ba68af5456e7ac88f6b2c07..676c8e39bc8f5b4723b918e8b8528e1eb0f4fb8e 100644
--- a/qbar.cabal
+++ b/qbar/qbar.cabal
@@ -1,6 +1,7 @@
 cabal-version: 3.0
 
 name:           qbar
+
 version:        0.1.0.0
 author:         Jens Nolte
 maintainer:     Jens Nolte
@@ -14,67 +15,31 @@ extra-source-files:
 
 --source-repository head
 --  type: git
---  location: https://git.c3pb.de/jens/qbar.git
+--  location: https:////git.c3pb.de/jens/qbar.git
 
 common shared-properties
+  default-language: GHC2021
   default-extensions:
-    AllowAmbiguousTypes
-    BangPatterns
-    BlockArguments
-    ConstraintKinds
-    DataKinds
-    DefaultSignatures
-    DeriveAnyClass
-    DeriveGeneric
-    DerivingStrategies
-    DisambiguateRecordFields
+    ApplicativeDo
     DuplicateRecordFields
-    ExistentialQuantification
-    FlexibleContexts
-    FlexibleInstances
-    FunctionalDependencies
-    GADTs
-    GeneralizedNewtypeDeriving
-    ImportQualifiedPost
-    InstanceSigs
     LambdaCase
-    -- Enable once 9.0.1 is required
-    --LexicalNegation
-    MultiParamTypeClasses
-    NamedFieldPuns
+    MultiWayIf
     NoImplicitPrelude
-    NumericUnderscores
     OverloadedStrings
-    PolyKinds
-    RankNTypes
-    ScopedTypeVariables
-    StandaloneDeriving
-    TemplateHaskell
-    TupleSections
-    TypeApplications
-    TypeFamilies
-    TypeOperators
-    ViewPatterns
-  default-language: Haskell2010
   ghc-options:
     -Weverything
     -Wno-all-missed-specialisations
-    -Wno-missing-safe-haskell-mode
-    -Wno-missing-kind-signatures
+    -Wno-missing-deriving-strategies
+    -Wno-implicit-prelude
     -Wno-missing-import-lists
+    -Wno-missing-kind-signatures
+    -Wno-missing-safe-haskell-mode
     -Wno-unsafe
     -Werror=incomplete-patterns
     -Werror=missing-fields
     -Werror=missing-home-modules
     -Werror=missing-methods
 
-common shared-executable-properties
-  import: shared-properties
-  ghc-options:
-    -threaded
-    -rtsopts
-    "-with-rtsopts=-N -I0"
-
 library
   import: shared-properties
   build-depends:
@@ -138,56 +103,29 @@ library
     QBar.Theme
     QBar.Time
     QBar.Utils
+  other-modules:
   hs-source-dirs:
     src
-  default-extensions:
-    MultiWayIf
 
 executable qbar
-  import: shared-executable-properties
-  main-is: Main.hs
-  other-modules:
-    Paths_qbar
-  hs-source-dirs:
-    app
+  import: shared-properties
+  ghc-options:
+    -threaded
+    -rtsopts
+    "-with-rtsopts=-N -I0"
   build-depends:
-    aeson,
-    async,
-    attoparsec,
-    base >=4.7 && <5,
-    binary,
-    bytestring,
-    colour,
-    concurrent-extra,
-    containers,
-    dbus,
-    directory,
-    filepath,
-    gitrev,
-    hostname,
-    lens,
-    mtl,
-    network,
-    optparse-applicative,
-    pipes,
-    pipes-aeson,
-    pipes-concurrency,
-    pipes-network,
-    pipes-parse,
-    pipes-safe,
     qbar,
-    random,
-    sorted-list,
-    stm,
-    text,
-    time,
-    typed-process,
-    unix,
-    unordered-containers,
+  hs-source-dirs:
+    app
+  main-is: Main.hs
 
 test-suite qbar-test
-  import: shared-executable-properties
+  import: shared-properties
   type: exitcode-stdio-1.0
+  ghc-options:
+    -threaded
+    -rtsopts
+    "-with-rtsopts=-N -I0"
   main-is: Spec.hs
   other-modules:
     Paths_qbar
@@ -195,4 +133,3 @@ test-suite qbar-test
     test
   build-depends:
     base >=4.7 && <5,
-    qbar,
\ No newline at end of file
diff --git a/src/QBar/BlockHelper.hs b/qbar/src/QBar/BlockHelper.hs
similarity index 100%
rename from src/QBar/BlockHelper.hs
rename to qbar/src/QBar/BlockHelper.hs
diff --git a/src/QBar/BlockOutput.hs b/qbar/src/QBar/BlockOutput.hs
similarity index 100%
rename from src/QBar/BlockOutput.hs
rename to qbar/src/QBar/BlockOutput.hs
diff --git a/src/QBar/Blocks.hs b/qbar/src/QBar/Blocks.hs
similarity index 100%
rename from src/QBar/Blocks.hs
rename to qbar/src/QBar/Blocks.hs
diff --git a/src/QBar/Blocks/Battery.hs b/qbar/src/QBar/Blocks/Battery.hs
similarity index 100%
rename from src/QBar/Blocks/Battery.hs
rename to qbar/src/QBar/Blocks/Battery.hs
diff --git a/src/QBar/Blocks/CpuUsage.hs b/qbar/src/QBar/Blocks/CpuUsage.hs
similarity index 100%
rename from src/QBar/Blocks/CpuUsage.hs
rename to qbar/src/QBar/Blocks/CpuUsage.hs
diff --git a/src/QBar/Blocks/Date.hs b/qbar/src/QBar/Blocks/Date.hs
similarity index 100%
rename from src/QBar/Blocks/Date.hs
rename to qbar/src/QBar/Blocks/Date.hs
diff --git a/src/QBar/Blocks/DiskUsage.hs b/qbar/src/QBar/Blocks/DiskUsage.hs
similarity index 100%
rename from src/QBar/Blocks/DiskUsage.hs
rename to qbar/src/QBar/Blocks/DiskUsage.hs
diff --git a/src/QBar/Blocks/NetworkManager.hs b/qbar/src/QBar/Blocks/NetworkManager.hs
similarity index 100%
rename from src/QBar/Blocks/NetworkManager.hs
rename to qbar/src/QBar/Blocks/NetworkManager.hs
diff --git a/src/QBar/Blocks/Pipe.hs b/qbar/src/QBar/Blocks/Pipe.hs
similarity index 100%
rename from src/QBar/Blocks/Pipe.hs
rename to qbar/src/QBar/Blocks/Pipe.hs
diff --git a/src/QBar/Blocks/Qubes.hs b/qbar/src/QBar/Blocks/Qubes.hs
similarity index 100%
rename from src/QBar/Blocks/Qubes.hs
rename to qbar/src/QBar/Blocks/Qubes.hs
diff --git a/src/QBar/Blocks/Script.hs b/qbar/src/QBar/Blocks/Script.hs
similarity index 100%
rename from src/QBar/Blocks/Script.hs
rename to qbar/src/QBar/Blocks/Script.hs
diff --git a/src/QBar/Blocks/Squeekboard.hs b/qbar/src/QBar/Blocks/Squeekboard.hs
similarity index 100%
rename from src/QBar/Blocks/Squeekboard.hs
rename to qbar/src/QBar/Blocks/Squeekboard.hs
diff --git a/src/QBar/Blocks/Utils.hs b/qbar/src/QBar/Blocks/Utils.hs
similarity index 100%
rename from src/QBar/Blocks/Utils.hs
rename to qbar/src/QBar/Blocks/Utils.hs
diff --git a/src/QBar/Cli.hs b/qbar/src/QBar/Cli.hs
similarity index 100%
rename from src/QBar/Cli.hs
rename to qbar/src/QBar/Cli.hs
diff --git a/src/QBar/Color.hs b/qbar/src/QBar/Color.hs
similarity index 100%
rename from src/QBar/Color.hs
rename to qbar/src/QBar/Color.hs
diff --git a/src/QBar/ControlSocket.hs b/qbar/src/QBar/ControlSocket.hs
similarity index 100%
rename from src/QBar/ControlSocket.hs
rename to qbar/src/QBar/ControlSocket.hs
diff --git a/src/QBar/Core.hs b/qbar/src/QBar/Core.hs
similarity index 100%
rename from src/QBar/Core.hs
rename to qbar/src/QBar/Core.hs
diff --git a/src/QBar/DefaultConfig.hs b/qbar/src/QBar/DefaultConfig.hs
similarity index 100%
rename from src/QBar/DefaultConfig.hs
rename to qbar/src/QBar/DefaultConfig.hs
diff --git a/src/QBar/Host.hs b/qbar/src/QBar/Host.hs
similarity index 100%
rename from src/QBar/Host.hs
rename to qbar/src/QBar/Host.hs
diff --git a/src/QBar/Pango.hs b/qbar/src/QBar/Pango.hs
similarity index 100%
rename from src/QBar/Pango.hs
rename to qbar/src/QBar/Pango.hs
diff --git a/src/QBar/Prelude.hs b/qbar/src/QBar/Prelude.hs
similarity index 100%
rename from src/QBar/Prelude.hs
rename to qbar/src/QBar/Prelude.hs
diff --git a/src/QBar/Qubes/AdminAPI.hs b/qbar/src/QBar/Qubes/AdminAPI.hs
similarity index 100%
rename from src/QBar/Qubes/AdminAPI.hs
rename to qbar/src/QBar/Qubes/AdminAPI.hs
diff --git a/src/QBar/Server.hs b/qbar/src/QBar/Server.hs
similarity index 100%
rename from src/QBar/Server.hs
rename to qbar/src/QBar/Server.hs
diff --git a/src/QBar/TagParser.hs b/qbar/src/QBar/TagParser.hs
similarity index 100%
rename from src/QBar/TagParser.hs
rename to qbar/src/QBar/TagParser.hs
diff --git a/src/QBar/Theme.hs b/qbar/src/QBar/Theme.hs
similarity index 100%
rename from src/QBar/Theme.hs
rename to qbar/src/QBar/Theme.hs
diff --git a/src/QBar/Time.hs b/qbar/src/QBar/Time.hs
similarity index 100%
rename from src/QBar/Time.hs
rename to qbar/src/QBar/Time.hs
diff --git a/src/QBar/Utils.hs b/qbar/src/QBar/Utils.hs
similarity index 100%
rename from src/QBar/Utils.hs
rename to qbar/src/QBar/Utils.hs
diff --git a/test/Spec.hs b/qbar/test/Spec.hs
similarity index 100%
rename from test/Spec.hs
rename to qbar/test/Spec.hs