diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,76 @@
 `summoner` uses [PVP Versioning][1].
 The changelog is available [on GitHub][2].
 
+## 2.1.0.0 — Jan 6, 2026
+
+* Support GHC-9.12.3. Use GHC-9.12.3 as the default version for
+  generated projects with `nightly-2026-01-04` Stack resolver.
+* Support GHC-9.10.3 in generated projects with `lts-24.26`.
+* Update GHC-9.8 to GHC-9.8.4 with `lts-23.28`.
+* Update GHC-9.6 to GHC-9.6.7 with `lts-22.44`.
+* Update `base` upper bound to `< 4.22`.
+* Update GitHub Actions in generated projects: replace deprecated
+  `haskell/actions/setup` with `haskell-actions/setup`.
+* Update `optparse-applicative`, `shellmet`, `time`, `hedgehog`, `brick` upper bounds.
+* Add new GHC warnings for GHC >= 9.10:
+  `-Wincomplete-record-selectors`, `-Wdeprecated-type-abstractions`,
+  `-Wdata-kinds-tc`, `-Wdefaulted-exception-context`.
+* Add new GHC warning for GHC >= 9.12: `-Wview-pattern-signatures`.
+* Fix encoding issues when reading source files by using `readFileBS`
+  with `decodeUtf8` instead of `readFileText`.
+* Update Stack resolver to `lts-24.26`. Update Stack version in CI to 3.3.
+
+* [#564](https://github.com/kowainik/summoner/issues/564):
+  Upgrade `brick` to version `>=1.0`.
+* [#565](https://github.com/kowainik/summoner/issues/565):
+  Build Summoner with GHC-9.2.
+* [#539](https://github.com/kowainik/summoner/issues/539):
+  Use GHC-9.0 as default version for generated projects.
+* [#540](https://github.com/kowainik/summoner/issues/540):
+  Build Summoner with GHC-9.0.
+* [#520](https://github.com/kowainik/summoner/issues/520):
+  Output the link to the GitHub project at the end of the process.
+* [#476](https://github.com/kowainik/summoner/issues/476):
+  Switch from `aeson` to `microaeson`.
+* [#466](https://github.com/kowainik/summoner/issues/466):
+  Add ` --test-show-details=direct` to `cabal test` on CI.
+* [#444](https://github.com/kowainik/summoner/issues/444)
+  [#547](https://github.com/kowainik/summoner/issues/547):
+  Support GHC-8.10.1 in the generated projects.
+  Use GHC-8.10.1 by default in the generated projects.
+  Use `nightly-2020-06-29` for stack resolver.
+  UPD: Use GHC-8.10.3 and `lts-17.0` instead.
+  UPD: Use GHC-8.10.7 and `lts-18.10` instead.
+* [#445](https://github.com/kowainik/summoner/issues/445):
+  Add `-Wunused-packages` for GHC-8.10.
+* [#477](https://github.com/kowainik/summoner/issues/477):
+  Remove `neat-interpolation` from dependencies.
+  As a result, remove some trailing spaces from the generated files.
+* [#442](https://github.com/kowainik/summoner/issues/442):
+  Get current year with the respect to the current timezone.
+* [#446](https://github.com/kowainik/summoner/issues/446):
+  Add README link in the `.cabal` file's description field.
+* [#453](https://github.com/kowainik/summoner/issues/453):
+  Drop support of `GHC-7.10` in the generated projects.
+* [#482](https://github.com/kowainik/summoner/issues/482):
+  Include `.hie` related GHC options to the generated files:
+  `-fwrite-ide-info` and `-hiedir=.hie` for GHC >= 8.8.
+  Also add `.hie` folder in the `.gitignore`.
+* [#484](https://github.com/kowainik/summoner/issues/484):
+  Improve generated files content.
+* [#491](https://github.com/kowainik/summoner/issues/491):
+  Support GHC-8.8.4 in the project.
+* [#517](https://github.com/kowainik/summoner/issues/517):
+  Switch to `main` initial branch when creating project.
+* Require `git >= 2.28` for `--initial-branch=main` option.
+* [#340](https://github.com/kowainik/summoner/issues/340):
+  Use `cabal` version `3.0`.
+* [#495](https://github.com/kowainik/summoner/issues/495):
+  Generate `dependabot.yml` to update GitHub Actions automatically.
+* __#TUI__ Upgrade `brick` allowed version. Bump up lower
+  bound to `0.56` due to the new field `formFieldUpdate`
+  addition to the `FormFieldState` data type.
+
 ## 2.0.1.1 — May 29, 2020
 
 * [#467](https://github.com/kowainik/summoner/issues/467):
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,11 +1,13 @@
 # 🔮 Summoner
 
 ![wizard](https://user-images.githubusercontent.com/8126674/44388234-320aac00-a55a-11e8-879d-5dca68512031.png)
+
 [![GitHub CI](https://github.com/kowainik/summoner/workflows/CI/badge.svg)](https://github.com/kowainik/summoner/actions)
-[![Build](https://img.shields.io/travis/kowainik/summoner.svg?logo=travis)](http://travis-ci.org/kowainik/summoner)
-[![Windows build](https://ci.appveyor.com/api/projects/status/github/kowainik/summoner?branch=master&svg=true)](https://ci.appveyor.com/project/kowainik/summoner)
+
 [![Hackage](https://img.shields.io/hackage/v/summoner.svg?logo=haskell)](https://hackage.haskell.org/package/summoner)
-[![MPL-2.0 license](https://img.shields.io/badge/license-MPL--2.0-blue.svg)](https://github.com/kowainik/summoner/blob/master/LICENSE)
+[![Stackage Lts](http://stackage.org/package/summoner/badge/lts)](http://stackage.org/lts/package/summoner)
+[![Stackage Nightly](http://stackage.org/package/summoner/badge/nightly)](http://stackage.org/nightly/package/summoner)
+[![MPL-2.0 license](https://img.shields.io/badge/license-MPL--2.0-blue.svg)](https://github.com/kowainik/summoner/blob/main/LICENSE)
 
 > _So many of our dreams at first seem impossible, then they seem improbable, and
 > then, when we summon the will, they soon become inevitable._
@@ -35,13 +37,13 @@
           + [TUI: download binary](#tui-download-binary)
           + [TUI: Homebrew](#tui-homebrew)
           + [TUI: Ubuntu](#tui-ubuntu)
-          + [TUI: from Hackage/Stackage](#tui-from-hackagestackage)
+          + [TUI: from Hackage](#tui-from-hackage)
           + [TUI: from source](#tui-from-source)
         + [Summon-CLI](#summon-cli)
           + [CLI: download binary](#cli-download-binary)
           + [CLI: Homebrew](#cli-homebrew)
           + [CLI: Ubuntu](#cli-ubuntu)
-          + [CLI: from Hackage/Stackage](#cli-from-hackagestackage)
+          + [CLI: from Hackage](#cli-from-hackage)
           + [CLI: from source](#cli-from-source)
     + [Setup](#setup)
 * [Usage](#usage)
@@ -78,18 +80,18 @@
 
 You can also see complete examples in the following folder:
 
-* [`summon-cli/examples/`: Examples of scaffolded projects](https://github.com/kowainik/summoner/tree/master/summoner-cli/examples/)
+* [`summon-cli/examples/`: Examples of scaffolded projects](https://github.com/kowainik/summoner/tree/main/summoner-cli/examples/)
 
 The directory contains the following examples:
 
-* [`cabal-minimal`](https://github.com/kowainik/summoner/tree/master/summoner-cli/examples/cabal-minimal):
+* [`cabal-minimal`](https://github.com/kowainik/summoner/tree/main/summoner-cli/examples/cabal-minimal):
   Minimal Haskell project with the Cabal-only support, default
   settings and all of the integrations disabled.
-* [`cabal-full`](https://github.com/kowainik/summoner/tree/master/summoner-cli/examples/cabal-full):
+* [`cabal-full`](https://github.com/kowainik/summoner/tree/main/summoner-cli/examples/cabal-full):
    Cabal-only project with all integrations enabled.
-* [`stack-full`](https://github.com/kowainik/summoner/tree/master/summoner-cli/examples/stack-full):
+* [`stack-full`](https://github.com/kowainik/summoner/tree/main/summoner-cli/examples/stack-full):
   Stack-only project with all integrations enabled.
-* [`full-batteries`](https://github.com/kowainik/summoner/tree/master/summoner-cli/examples/full-batteries):
+* [`full-batteries`](https://github.com/kowainik/summoner/tree/main/summoner-cli/examples/full-batteries):
   All batteries-included project which supports both build tools and
   shows every Summoner feature.
 
@@ -130,11 +132,20 @@
   -Widentities
   -Wincomplete-uni-patterns
   -Wincomplete-record-updates
-  -Wredundant-constraints       (GHC ⩾ 8.0)
-  -fhide-source-paths           (GHC ⩾ 8.2)
-  -Wmissing-export-lists        (GHC ⩾ 8.4)
-  -Wpartial-fields              (GHC ⩾ 8.4)
-  -Wmissing-deriving-strategies (GHC ⩾ 8.8)
+  -Wredundant-constraints
+  -Wnoncanonical-monad-instances
+  -fhide-source-paths              (GHC ⩾ 8.2)
+  -Wmissing-export-lists           (GHC ⩾ 8.4)
+  -Wpartial-fields                 (GHC ⩾ 8.4)
+  -Wmissing-deriving-strategies    (GHC ⩾ 8.8)
+  -fwrite-ide-info                 (GHC ⩾ 8.8)
+  -hiedir=.hie                     (GHC ⩾ 8.8)
+  -Wunused-packages                (GHC ⩾ 8.10)
+  -Wincomplete-record-selectors    (GHC ⩾ 9.10)
+  -Wdeprecated-type-abstractions   (GHC ⩾ 9.10)
+  -Wdata-kinds-tc                  (GHC ⩾ 9.10)
+  -Wdefaulted-exception-context    (GHC ⩾ 9.10)
+  -Wview-pattern-signatures        (GHC ⩾ 9.12)
   ```
 
   Besides, the following GHC options are added to the executable, tests and benchmark stanzas:
@@ -223,13 +234,13 @@
 
 To start using Summoner make sure that you have the following tools installed on your machine:
 
-* [`git`](https://git-scm.com) – to initialize the GitHub repo.
+* [`git`](https://git-scm.com) ⩾ 2.28 – to initialize the GitHub repo.
 * [`hub`](https://github.com/github/hub) – to upload the project to GitHub.
 * [`curl`](https://curl.haxx.se) – to download licenses.
 
 We also have minimal version requirements for build tools:
 
-* [Cabal ⩾ 2.4](https://www.haskell.org/cabal/)
+* [Cabal ⩾ 3.0](https://www.haskell.org/cabal/)
 * [Stack ⩾ 2.1.3](http://haskellstack.org)
 
 However, it is always recommended to use the newest versions of build tools.
@@ -290,21 +301,15 @@
 $ sudo apt install summoner-tui
 ```
 
-##### TUI: from Hackage/Stackage
+##### TUI: from Hackage
 
 [[Back to the Table of Contents] ↑](#structure)
 
 Using `cabal`:
 
 ```shell
-cabal v2-update
-cabal v2-install summoner-tui
-```
-
-Using `stack`:
-
-```shell
-stack install summoner-tui
+cabal update
+cabal install summoner-tui
 ```
 
 ##### TUI: from source
@@ -332,7 +337,7 @@
 Build and install using `cabal`:
 
 ```shell
-cabal v2-install summoner-tui:exe:summon-tui
+cabal install summoner-tui:exe:summon-tui
 ```
 
 Build and install using `stack`:
@@ -384,21 +389,15 @@
 $ sudo apt install summoner-cli
 ```
 
-##### CLI: from Hackage/Stackage
+##### CLI: from Hackage
 
 [[Back to the Table of Contents] ↑](#structure)
 
 Using `cabal`:
 
 ```shell
-cabal v2-update
-cabal v2-install summoner
-```
-
-Using `stack`:
-
-```shell
-stack install summoner
+cabal update
+cabal install summoner
 ```
 
 ##### CLI: from source
@@ -426,7 +425,7 @@
 Build and install using `cabal`:
 
 ```shell
-cabal v2-install summoner-cli:exe:summon
+cabal install summoner-cli:exe:summon
 ```
 
 Build and install using `stack`:
@@ -476,7 +475,7 @@
 | `fullName`       | Text    | Full name.                                                                                                                                                           |
 | `email`          | Text    | E-mail address.                                                                                                                                                      |
 | `license`        | License | One of: `MIT`, `BSD2`, `BSD3`, `GPL-2`, `GPL-3`, `LGPL-2.1`, `LGPL-3`, `AGPL-3`, `Apache-2.0`, `MPL-2.0`, `None`.                                                    |
-| `ghcVersions`    | [GHC]   | `summoner` uses default `GHC-8.8.3`. However, additionally you can specify other versions. For each version `x.y.z` the `stack-x.y.z.yaml` will be created.          |
+| `ghcVersions`    | [GHC]   | `summoner` uses default `GHC-9.12.3`. However, additionally you can specify other versions. For each version `x.y.z` the `stack-x.y.z.yaml` will be created. Use `summon show ghc` to see all supported GHC versions. |
 | `github`         | Bool    | Turn on `GitHub` integration by default?                                                                                                                             |
 | `gitignore`      | [Text]  | List of files you want added to the default `.gitignore`. (Ignored if `github = false`)                                                                              |
 | `noUpload`       | Bool    | Do not upload to GitHub, but create all GitHub related files if specified (Ignored if `github = false`)                                                              |
@@ -498,7 +497,7 @@
 You can create default configuration using the `summon config`
 command. See [the default content here](summoner-cli/test/golden/summoner-default.toml).
 
-For a real-life example of the configuration, see [the configuration for projects of the `Kowainik` organization](https://github.com/kowainik/org/blob/master/.summoner.toml).
+For a real-life example of the configuration, see [the configuration for projects of the `Kowainik` organization](https://github.com/kowainik/org/blob/main/.summoner.toml).
 
 ### Command line arguments
 
@@ -631,7 +630,7 @@
 that can be used to scaffold future Haskell packages. It contains all
 options supported by Summoner with comments and examples. Though, all
 options would be turned off by default and to use them one will need
-to uncomment the correspoding lines.
+to uncomment the corresponding lines.
 See [the default content here](summoner-cli/test/golden/summoner-default.toml).
 
 Possible command usages:
@@ -716,7 +715,7 @@
 #!/usr/bin/env cabal
 {- cabal:
 build-depends:
-  , base ^>= 4.13.0.0
+  , base ^>= 4.21.1.0
 -}
 
 main :: IO ()
@@ -728,7 +727,7 @@
 ```haskell
 #!/usr/bin/env stack
 {- stack
-  --resolver lts-15.5
+  --resolver nightly-2026-01-04
   script
   --package base
 -}
@@ -793,8 +792,8 @@
 
 * Summoner is a multi-package project which has two packages inside: `summoner-cli` and `summoner-tui`. We are supporting the same functionality in both of them, so, if it's possible, you should add/change the code in both of the packages.
 * Summoner uses the custom prelude [`relude`](https://github.com/kowainik/relude).
-* We are using the [Kowainik style guide](https://github.com/kowainik/org/blob/master/style-guide.md#haskell-style-guide).
-* To sum up, [here is the Contributing guide](https://github.com/kowainik/.github/blob/master/CONTRIBUTING.md#contributing-to-the-kowainik-repositories) we use across the repositories.
+* We are using the [Kowainik style guide](https://kowainik.github.io/posts/2019-02-06-style-guide).
+* To sum up, [here is the Contributing guide](https://github.com/kowainik/.github/blob/main/CONTRIBUTING.md#contributing-to-the-kowainik-repositories) we use across the repositories.
 * This project is contributor-friendly, so be kind to other people working on the project.
 
 ### Dependencies
@@ -810,7 +809,7 @@
 To build the project you can use the following commands:
 
 ```shell=
-cabal v2-build all
+cabal build all
 ```
 
 for Cabal and
@@ -825,12 +824,12 @@
 
 [[Back to the Table of Contents] ↑](#structure)
 
-Summoner uses the golden tests technique for assuring the correctness of the generated files. For this purpose, we have [the `golden` folder](https://github.com/kowainik/summoner/tree/master/summoner-cli/test/golden) with two sample projects to test against.
+Summoner uses the golden tests technique for assuring the correctness of the generated files. For this purpose, we have [the `golden` folder](https://github.com/kowainik/summoner/tree/main/summoner-cli/test/golden) with two sample projects to test against.
 
 To actually run tests you need to run:
 
 ```shell
-cabal v2-test all
+cabal test all
 ```
 
 or, if using Stack
@@ -846,8 +845,8 @@
 Building Summoner with the recommended method creates two executables: `summon` and `summon-tui`. To run the compiled executable you can use the following commands:
 
 ```shell
-cabal v2-exec summon -- SOME_COMMAND
-cabal v2-exec summon-tui -- SOME_COMMAND
+cabal exec summon -- SOME_COMMAND
+cabal exec summon-tui -- SOME_COMMAND
 ```
 
 or, if using Stack
@@ -855,6 +854,14 @@
 ```shell
 stack exec summon -- SOME_COMMAND
 stack exec summon-tui -- SOME_COMMAND
+```
+
+### Generate golden tests
+
+To regenerate the content of all projects on disk, use the following command:
+
+```shell
+cabal run gg
 ```
 
 ## Acknowledgments
diff --git a/examples/cabal-full/.github/workflows/ci.yml b/examples/cabal-full/.github/workflows/ci.yml
--- a/examples/cabal-full/.github/workflows/ci.yml
+++ b/examples/cabal-full/.github/workflows/ci.yml
@@ -1,44 +1,113 @@
 name: CI
 
-# Trigger the workflow on push or pull request, but only for the master branch
 on:
   pull_request:
+    types: [synchronize, opened, reopened]
   push:
-    branches: [master]
+    branches: [main]
+  schedule:
+    # additionally run once per week (At 00:00 on Sunday) to maintain cache
+    - cron: '0 0 * * 0'
 
 jobs:
-  build:
-    name: ghc ${{ matrix.ghc }}
-    runs-on: ubuntu-16.04
+  cabal:
+    name: ${{ matrix.os }} / ghc ${{ matrix.ghc }}
+    runs-on: ${{ matrix.os }}
     strategy:
       matrix:
-        cabal: ["2.4"]
+        os: [ubuntu-latest, macOS-latest, windows-latest]
+        cabal: ["3.14.2.0"]
         ghc:
           - "8.4.4"
           - "8.6.5"
-          - "8.8.3"
+          - "8.8.4"
+          - "8.10.7"
+          - "9.0.2"
+          - "9.2.8"
+          - "9.4.8"
+          - "9.6.7"
+          - "9.8.4"
+          - "9.10.3"
+          - "9.12.3"
+        exclude:
+          - os: macOS-latest
+            ghc: 9.10.3
+          - os: macOS-latest
+            ghc: 9.8.4
+          - os: macOS-latest
+            ghc: 9.6.7
+          - os: macOS-latest
+            ghc: 9.4.8
+          - os: macOS-latest
+            ghc: 9.2.8
+          - os: macOS-latest
+            ghc: 9.0.2
+          - os: macOS-latest
+            ghc: 8.10.7
+          - os: macOS-latest
+            ghc: 8.8.4
+          - os: macOS-latest
+            ghc: 8.6.5
+          - os: macOS-latest
+            ghc: 8.4.4
+          - os: windows-latest
+            ghc: 9.10.3
+          - os: windows-latest
+            ghc: 9.8.4
+          - os: windows-latest
+            ghc: 9.6.7
+          - os: windows-latest
+            ghc: 9.4.8
+          - os: windows-latest
+            ghc: 9.2.8
+          - os: windows-latest
+            ghc: 9.0.2
+          - os: windows-latest
+            ghc: 8.10.7
+          - os: windows-latest
+            ghc: 8.8.4
+          - os: windows-latest
+            ghc: 8.6.5
+          - os: windows-latest
+            ghc: 8.4.4
 
     steps:
-    - uses: actions/checkout@v2
-      if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/master'
+    - uses: actions/checkout@v4
 
-    - uses: actions/setup-haskell@v1
+    - uses: haskell-actions/setup@v2
+      id: setup-haskell-cabal
       name: Setup Haskell
       with:
         ghc-version: ${{ matrix.ghc }}
         cabal-version: ${{ matrix.cabal }}
 
-    - uses: actions/cache@v1
+    - name: Configure
+      run: |
+        cabal configure --enable-tests --enable-benchmarks --enable-documentation --test-show-details=direct --write-ghc-environment-files=always
+
+    - name: Freeze
+      run: |
+        cabal freeze
+
+    - uses: actions/cache@v4
       name: Cache ~/.cabal/store
       with:
-        path: ~/.cabal/store
-        key: ${{ runner.os }}-${{ matrix.ghc }}-cabal
+        path: ${{ steps.setup-haskell-cabal.outputs.cabal-store }}
+        key: ${{ runner.os }}-${{ matrix.ghc }}-${{ hashFiles('cabal.project.freeze') }}
 
+    - name: Install dependencies
+      run: |
+        cabal build all --only-dependencies
+
     - name: Build
       run: |
-        cabal v2-update
-        cabal v2-build --enable-tests --enable-benchmarks
+        cabal build all
 
     - name: Test
       run: |
-        cabal v2-test --enable-tests
+        cabal test all
+
+    - name: Documentation
+      run: |
+        cabal haddock
+
diff --git a/examples/cabal-full/.gitignore b/examples/cabal-full/.gitignore
--- a/examples/cabal-full/.gitignore
+++ b/examples/cabal-full/.gitignore
@@ -21,6 +21,7 @@
 cabal.project.local
 .ghc.environment.*
 .HTF/
+.hie/
 # Stack
 .stack-work/
 stack.yaml.lock
diff --git a/examples/cabal-full/.travis.yml b/examples/cabal-full/.travis.yml
--- a/examples/cabal-full/.travis.yml
+++ b/examples/cabal-full/.travis.yml
@@ -1,33 +1,38 @@
-sudo: true
 language: haskell
 
 git:
   depth: 5
 
-cabal: "2.4"
+cabal: "3.14.2.0"
 
 cache:
   directories:
   - "$HOME/.cabal/store"
-  
 
-matrix:
+jobs:
   include:
   - ghc: 8.4.4
   - ghc: 8.6.5
-  - ghc: 8.8.3
-  
-  
+  - ghc: 8.8.4
+  - ghc: 8.10.7
+  - ghc: 9.0.2
+  - ghc: 9.2.8
+  - ghc: 9.4.8
+  - ghc: 9.6.7
+  - ghc: 9.8.4
+  - ghc: 9.10.3
+  - ghc: 9.12.3
 
 install:
   # HLint check
   - curl -sSL https://raw.github.com/ndmitchell/neil/master/misc/travis.sh | sh -s -- hlint .
 
-  - cabal v2-update
-  - cabal v2-build --enable-tests --enable-benchmarks
+  - cabal update
+  - cabal configure --enable-tests --enable-benchmarks --enable-documentation --test-show-details=direct --write-ghc-environment-files=always
+  - cabal build all
 
 script:
-  - cabal v2-test --enable-tests
+  - cabal test all
 
 notifications:
   email: false
diff --git a/examples/cabal-full/LICENSE b/examples/cabal-full/LICENSE
--- a/examples/cabal-full/LICENSE
+++ b/examples/cabal-full/LICENSE
@@ -1,6 +1,6 @@
 BSD 3-Clause License
 
-Copyright (c) 2020, Kowainik
+Copyright (c) 2022, Kowainik
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/examples/cabal-full/README.md b/examples/cabal-full/README.md
--- a/examples/cabal-full/README.md
+++ b/examples/cabal-full/README.md
@@ -1,8 +1,8 @@
 # cabal-full
 
 [![GitHub CI](https://github.com/kowainik/cabal-full/workflows/CI/badge.svg)](https://github.com/kowainik/cabal-full/actions)
-[![Build status](https://img.shields.io/travis/kowainik/cabal-full.svg?logo=travis)](https://travis-ci.org/kowainik/cabal-full)
-[![Windows build status](https://ci.appveyor.com/api/projects/status/github/kowainik/cabal-full?branch=master&svg=true)](https://ci.appveyor.com/project/kowainik/cabal-full)
+[![Build status](https://img.shields.io/travis/kowainik/cabal-full.svg?logo=travis)](https://travis-ci.com/kowainik/cabal-full)
+[![Windows build status](https://ci.appveyor.com/api/projects/status/github/kowainik/cabal-full?branch=main&svg=true)](https://ci.appveyor.com/project/kowainik/cabal-full)
 [![Hackage](https://img.shields.io/hackage/v/cabal-full.svg?logo=haskell)](https://hackage.haskell.org/package/cabal-full)
 [![BSD-3-Clause license](https://img.shields.io/badge/license-BSD--3--Clause-blue.svg)](LICENSE)
 
diff --git a/examples/cabal-full/app/Main.hs b/examples/cabal-full/app/Main.hs
--- a/examples/cabal-full/app/Main.hs
+++ b/examples/cabal-full/app/Main.hs
@@ -1,7 +1,7 @@
 module Main (main) where
 
-import CabalFull (someFunc)
+import CabalFull (projectName)
 
 
 main :: IO ()
-main = someFunc
+main = putStrLn ("Executable for " ++ projectName)
diff --git a/examples/cabal-full/appveyor.yml b/examples/cabal-full/appveyor.yml
--- a/examples/cabal-full/appveyor.yml
+++ b/examples/cabal-full/appveyor.yml
@@ -4,6 +4,11 @@
 # Do not build feature branch with open Pull Requests
 skip_branch_with_pr: true
 
+# build only main branch
+branches:
+  only:
+    - main
+
 platform:
   - x86_64
 
@@ -16,19 +21,20 @@
     CABOPTS: --store-dir=C:\\SR
 
   matrix:
-    - GHCVER: 8.8.3
+    - GHCVER: 9.12.3
 
 install:
   - choco source add -n mistuke -s https://www.myget.org/F/mistuke/api/v2
-  - choco install -y cabal --version 2.4.1.0
-  - choco install -y ghc   --version 8.8.3
+  - choco install -y cabal --version 3.6.2.0
+  - choco install -y ghc   --version 9.12.3
   - refreshenv
 
 before_build:
   - cabal --version
   - ghc   --version
-  - cabal %CABOPTS% v2-update
+  - cabal %CABOPTS% update
 
 build_script:
-  - cabal %CABOPTS% v2-build --enable-tests
-  - cabal %CABOPTS% v2-test  --enable-tests
+  - cabal %CABOPTS% configure --enable-tests --enable-benchmarks --enable-documentation --test-show-details=direct --write-ghc-environment-files=always
+  - cabal %CABOPTS% build all
+  - cabal %CABOPTS% test  all
diff --git a/examples/cabal-full/benchmark/Main.hs b/examples/cabal-full/benchmark/Main.hs
--- a/examples/cabal-full/benchmark/Main.hs
+++ b/examples/cabal-full/benchmark/Main.hs
@@ -1,7 +1,7 @@
 module Main (main) where
 
-import Gauge.Main
+import CabalFull (projectName)
 
 
 main :: IO ()
-main = defaultMain [bench "const" (whnf const ())]
+main = putStrLn ("Benchmarks for " ++ projectName)
diff --git a/examples/cabal-full/cabal-full.cabal b/examples/cabal-full/cabal-full.cabal
--- a/examples/cabal-full/cabal-full.cabal
+++ b/examples/cabal-full/cabal-full.cabal
@@ -1,41 +1,51 @@
-cabal-version:       2.4
+cabal-version:       3.0
 name:                cabal-full
 version:             0.0.0.0
 synopsis:            Cabal-only example with all integrations
-description:         Cabal-only example with all integrations
+description:
+    Cabal-only example with all integrations.
+    See [README.md](https://github.com/kowainik/cabal-full#cabal-full) for more details.
 homepage:            https://github.com/kowainik/cabal-full
 bug-reports:         https://github.com/kowainik/cabal-full/issues
 license:             BSD-3-Clause
 license-file:        LICENSE
 author:              Kowainik
 maintainer:          Kowainik <xrom.xkov@gmail.com>
-copyright:           2020 Kowainik
+copyright:           2022 Kowainik
 category:            Testing
 build-type:          Simple
 extra-doc-files:     README.md
                      CHANGELOG.md
 tested-with:         GHC == 8.4.4
                      GHC == 8.6.5
-                     GHC == 8.8.3
+                     GHC == 8.8.4
+                     GHC == 8.10.7
+                     GHC == 9.0.2
+                     GHC == 9.2.8
+                     GHC == 9.4.8
+                     GHC == 9.6.7
+                     GHC == 9.8.4
+                     GHC == 9.10.3
+                     GHC == 9.12.3
 
 source-repository head
   type:                git
   location:            https://github.com/kowainik/cabal-full.git
 
 common common-options
-  build-depends:       base >= 4.11.1.0 && < 4.14
+  build-depends:       base >= 4.11.1.0 && < 4.22
                      , relude
-  
+
   mixins:              base hiding (Prelude)
                      , relude (Relude as Prelude)
-  
+
   ghc-options:         -Wall
                        -Wcompat
                        -Widentities
                        -Wincomplete-uni-patterns
                        -Wincomplete-record-updates
-  if impl(ghc >= 8.0)
-    ghc-options:       -Wredundant-constraints
+                       -Wredundant-constraints
+                       -Wnoncanonical-monad-instances
   if impl(ghc >= 8.2)
     ghc-options:       -fhide-source-paths
   if impl(ghc >= 8.4)
@@ -43,6 +53,29 @@
                        -Wpartial-fields
   if impl(ghc >= 8.8)
     ghc-options:       -Wmissing-deriving-strategies
+                       -fwrite-ide-info
+                       -hiedir=.hie
+  if impl(ghc >= 8.10)
+    ghc-options:       -Wunused-packages
+  if impl(ghc >= 9.0)
+    ghc-options:       -Winvalid-haddock
+  if impl(ghc >= 9.2)
+    ghc-options:       -Wredundant-bang-patterns
+                       -Woperator-whitespace
+  if impl(ghc >= 9.4  && < 9.10)
+    ghc-options:       -Wforall-identifier
+  if impl(ghc >= 9.4)
+    ghc-options:       -Wredundant-strictness-flags
+  if impl(ghc >= 9.8)
+    ghc-options:       -Wterm-variable-capture
+                       -Winconsistent-flags
+  if impl(ghc >= 9.10)
+    ghc-options:       -Wincomplete-record-selectors
+                       -Wdeprecated-type-abstractions
+                       -Wdata-kinds-tc
+                       -Wdefaulted-exception-context
+  if impl(ghc >= 9.12)
+    ghc-options:       -Wview-pattern-signatures
 
   default-language:    Haskell2010
   default-extensions:  DeriveGeneric
@@ -77,8 +110,7 @@
   type:                exitcode-stdio-1.0
   hs-source-dirs:      benchmark
   main-is:             Main.hs
-  build-depends:       gauge
-                     , cabal-full
+  build-depends:       cabal-full
   ghc-options:         -threaded
                        -rtsopts
                        -with-rtsopts=-N
diff --git a/examples/cabal-full/src/CabalFull.hs b/examples/cabal-full/src/CabalFull.hs
--- a/examples/cabal-full/src/CabalFull.hs
+++ b/examples/cabal-full/src/CabalFull.hs
@@ -1,5 +1,5 @@
 {- |
-Copyright: (c) 2020 Kowainik
+Copyright: (c) 2022 Kowainik
 SPDX-License-Identifier: BSD-3-Clause
 Maintainer: Kowainik <xrom.xkov@gmail.com>
 
@@ -7,9 +7,9 @@
 -}
 
 module CabalFull
-       ( someFunc
-       ) where
+    ( projectName
+    ) where
 
 
-someFunc :: IO ()
-someFunc = putStrLn ("someFunc" :: String)
+projectName :: String
+projectName = "cabal-full"
diff --git a/examples/cabal-full/test/Spec.hs b/examples/cabal-full/test/Spec.hs
--- a/examples/cabal-full/test/Spec.hs
+++ b/examples/cabal-full/test/Spec.hs
@@ -1,5 +1,7 @@
 module Main (main) where
 
+import CabalFull (projectName)
 
+
 main :: IO ()
-main = putStrLn ("Test suite is not implemented" :: String)
+main = putStrLn ("Tests for " ++ projectName)
diff --git a/examples/cabal-minimal/app/Main.hs b/examples/cabal-minimal/app/Main.hs
--- a/examples/cabal-minimal/app/Main.hs
+++ b/examples/cabal-minimal/app/Main.hs
@@ -2,4 +2,4 @@
 
 
 main :: IO ()
-main = putStrLn ("Hello, world!" :: String)
+main = putStrLn ("Executable not implemented" :: String)
diff --git a/examples/cabal-minimal/cabal-minimal.cabal b/examples/cabal-minimal/cabal-minimal.cabal
--- a/examples/cabal-minimal/cabal-minimal.cabal
+++ b/examples/cabal-minimal/cabal-minimal.cabal
@@ -1,27 +1,29 @@
-cabal-version:       2.4
+cabal-version:       3.0
 name:                cabal-minimal
 version:             0.0.0.0
 synopsis:            Minimal cabal-only test project
-description:         Minimal cabal-only test project
+description:
+    Minimal cabal-only test project.
+    See README.md for more details.
 license:             NONE
 author:              Kowainik
 maintainer:          Kowainik <xrom.xkov@gmail.com>
-copyright:           2020 Kowainik
+copyright:           2022 Kowainik
 build-type:          Simple
 extra-doc-files:     README.md
                      CHANGELOG.md
-tested-with:         GHC == 8.8.3
+tested-with:         GHC == 9.12.3
 
 common common-options
-  build-depends:       base ^>= 4.13.0.0
-  
+  build-depends:       base ^>= 4.21.1.0
+
   ghc-options:         -Wall
                        -Wcompat
                        -Widentities
                        -Wincomplete-uni-patterns
                        -Wincomplete-record-updates
-  if impl(ghc >= 8.0)
-    ghc-options:       -Wredundant-constraints
+                       -Wredundant-constraints
+                       -Wnoncanonical-monad-instances
   if impl(ghc >= 8.2)
     ghc-options:       -fhide-source-paths
   if impl(ghc >= 8.4)
@@ -29,6 +31,29 @@
                        -Wpartial-fields
   if impl(ghc >= 8.8)
     ghc-options:       -Wmissing-deriving-strategies
+                       -fwrite-ide-info
+                       -hiedir=.hie
+  if impl(ghc >= 8.10)
+    ghc-options:       -Wunused-packages
+  if impl(ghc >= 9.0)
+    ghc-options:       -Winvalid-haddock
+  if impl(ghc >= 9.2)
+    ghc-options:       -Wredundant-bang-patterns
+                       -Woperator-whitespace
+  if impl(ghc >= 9.4  && < 9.10)
+    ghc-options:       -Wforall-identifier
+  if impl(ghc >= 9.4)
+    ghc-options:       -Wredundant-strictness-flags
+  if impl(ghc >= 9.8)
+    ghc-options:       -Wterm-variable-capture
+                       -Winconsistent-flags
+  if impl(ghc >= 9.10)
+    ghc-options:       -Wincomplete-record-selectors
+                       -Wdeprecated-type-abstractions
+                       -Wdata-kinds-tc
+                       -Wdefaulted-exception-context
+  if impl(ghc >= 9.12)
+    ghc-options:       -Wview-pattern-signatures
 
   default-language:    Haskell2010
 
@@ -36,7 +61,6 @@
   import:              common-options
   hs-source-dirs:      app
   main-is:             Main.hs
-  
   ghc-options:         -threaded
                        -rtsopts
                        -with-rtsopts=-N
diff --git a/examples/full-batteries/.github/CODEOWNERS b/examples/full-batteries/.github/CODEOWNERS
--- a/examples/full-batteries/.github/CODEOWNERS
+++ b/examples/full-batteries/.github/CODEOWNERS
@@ -1,1 +1,1 @@
-*  @chshersh @vrom911
+*  @vrom911
diff --git a/examples/full-batteries/.github/workflows/ci.yml b/examples/full-batteries/.github/workflows/ci.yml
--- a/examples/full-batteries/.github/workflows/ci.yml
+++ b/examples/full-batteries/.github/workflows/ci.yml
@@ -1,46 +1,168 @@
 name: CI
 
-# Trigger the workflow on push or pull request, but only for the master branch
 on:
   pull_request:
+    types: [synchronize, opened, reopened]
   push:
-    branches: [master]
+    branches: [main]
+  schedule:
+    # additionally run once per week (At 00:00 on Sunday) to maintain cache
+    - cron: '0 0 * * 0'
 
 jobs:
-  build:
-    name: ghc ${{ matrix.ghc }}
-    runs-on: ubuntu-16.04
+  cabal:
+    name: ${{ matrix.os }} / ghc ${{ matrix.ghc }}
+    runs-on: ${{ matrix.os }}
     strategy:
       matrix:
-        cabal: ["2.4"]
+        os: [ubuntu-latest, macOS-latest, windows-latest]
+        cabal: ["3.14.2.0"]
         ghc:
           - "8.0.2"
           - "8.2.2"
           - "8.4.4"
           - "8.6.5"
-          - "8.8.3"
+          - "8.8.4"
+          - "8.10.7"
+          - "9.0.2"
+          - "9.2.8"
+          - "9.4.8"
+          - "9.6.7"
+          - "9.8.4"
+          - "9.10.3"
+          - "9.12.3"
+        exclude:
+          - os: macOS-latest
+            ghc: 9.10.3
+          - os: macOS-latest
+            ghc: 9.8.4
+          - os: macOS-latest
+            ghc: 9.6.7
+          - os: macOS-latest
+            ghc: 9.4.8
+          - os: macOS-latest
+            ghc: 9.2.8
+          - os: macOS-latest
+            ghc: 9.0.2
+          - os: macOS-latest
+            ghc: 8.10.7
+          - os: macOS-latest
+            ghc: 8.8.4
+          - os: macOS-latest
+            ghc: 8.6.5
+          - os: macOS-latest
+            ghc: 8.4.4
+          - os: macOS-latest
+            ghc: 8.2.2
+          - os: macOS-latest
+            ghc: 8.0.2
+          - os: windows-latest
+            ghc: 9.10.3
+          - os: windows-latest
+            ghc: 9.8.4
+          - os: windows-latest
+            ghc: 9.6.7
+          - os: windows-latest
+            ghc: 9.4.8
+          - os: windows-latest
+            ghc: 9.2.8
+          - os: windows-latest
+            ghc: 9.0.2
+          - os: windows-latest
+            ghc: 8.10.7
+          - os: windows-latest
+            ghc: 8.8.4
+          - os: windows-latest
+            ghc: 8.6.5
+          - os: windows-latest
+            ghc: 8.4.4
+          - os: windows-latest
+            ghc: 8.2.2
+          - os: windows-latest
+            ghc: 8.0.2
 
     steps:
-    - uses: actions/checkout@v2
-      if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/master'
+    - uses: actions/checkout@v4
 
-    - uses: actions/setup-haskell@v1
+    - uses: haskell-actions/setup@v2
+      id: setup-haskell-cabal
       name: Setup Haskell
       with:
         ghc-version: ${{ matrix.ghc }}
         cabal-version: ${{ matrix.cabal }}
 
-    - uses: actions/cache@v1
+    - name: Configure
+      run: |
+        cabal configure --enable-tests --enable-benchmarks --enable-documentation --test-show-details=direct --write-ghc-environment-files=always
+
+    - name: Freeze
+      run: |
+        cabal freeze
+
+    - uses: actions/cache@v4
       name: Cache ~/.cabal/store
       with:
-        path: ~/.cabal/store
-        key: ${{ runner.os }}-${{ matrix.ghc }}-cabal
+        path: ${{ steps.setup-haskell-cabal.outputs.cabal-store }}
+        key: ${{ runner.os }}-${{ matrix.ghc }}-${{ hashFiles('cabal.project.freeze') }}
 
+    - name: Install dependencies
+      run: |
+        cabal build all --only-dependencies
+
     - name: Build
       run: |
-        cabal v2-update
-        cabal v2-build --enable-tests --enable-benchmarks
+        cabal build all
 
     - name: Test
       run: |
-        cabal v2-test --enable-tests
+        cabal test all
+
+    - name: Documentation
+      run: |
+        cabal haddock
+
+
+  stack:
+    name: stack / ghc ${{ matrix.ghc }}
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        stack: ["3.3.1"]
+        ghc:
+          - "8.0.2"
+          - "8.2.2"
+          - "8.4.4"
+          - "8.6.5"
+          - "8.8.4"
+          - "8.10.7"
+          - "9.0.2"
+          - "9.2.8"
+          - "9.4.8"
+          - "9.6.7"
+          - "9.8.4"
+          - "9.10.3"
+          - "9.12.3"
+
+    steps:
+    - uses: actions/checkout@v4
+      if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/main'
+
+    - uses: haskell-actions/setup@v2
+      name: Setup Haskell Stack
+      with:
+        ghc-version: ${{ matrix.ghc }}
+        stack-version: ${{ matrix.stack }}
+
+    - uses: actions/cache@v4
+      name: Cache ~/.stack
+      with:
+        path: ~/.stack
+        key: ${{ runner.os }}-${{ matrix.ghc }}-stack
+
+    - name: Build
+      run: |
+        stack build --system-ghc --test --bench --no-run-tests --no-run-benchmarks --ghc-options=-Werror
+
+    - name: Test
+      run: |
+        stack test --system-ghc
diff --git a/examples/full-batteries/.gitignore b/examples/full-batteries/.gitignore
--- a/examples/full-batteries/.gitignore
+++ b/examples/full-batteries/.gitignore
@@ -21,6 +21,7 @@
 cabal.project.local
 .ghc.environment.*
 .HTF/
+.hie/
 # Stack
 .stack-work/
 stack.yaml.lock
diff --git a/examples/full-batteries/.travis.yml b/examples/full-batteries/.travis.yml
--- a/examples/full-batteries/.travis.yml
+++ b/examples/full-batteries/.travis.yml
@@ -1,10 +1,9 @@
-sudo: true
 language: haskell
 
 git:
   depth: 5
 
-cabal: "2.4"
+cabal: "3.14.2.0"
 
 cache:
   directories:
@@ -12,37 +11,69 @@
   - "$HOME/.stack"
   - "$TRAVIS_BUILD_DIR/.stack-work"
 
-matrix:
+jobs:
   include:
   - ghc: 8.0.2
   - ghc: 8.2.2
   - ghc: 8.4.4
   - ghc: 8.6.5
-  - ghc: 8.8.3
-  
+  - ghc: 8.8.4
+  - ghc: 8.10.7
+  - ghc: 9.0.2
+  - ghc: 9.2.8
+  - ghc: 9.4.8
+  - ghc: 9.6.7
+  - ghc: 9.8.4
+  - ghc: 9.10.3
+  - ghc: 9.12.3
+
   - ghc: 8.0.2
     env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.0.2.yaml"
-  
+
   - ghc: 8.2.2
     env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.2.2.yaml"
-  
+
   - ghc: 8.4.4
     env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.4.4.yaml"
-  
+
   - ghc: 8.6.5
     env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.6.5.yaml"
-  
-  - ghc: 8.8.3
+
+  - ghc: 8.8.4
+    env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.8.4.yaml"
+
+  - ghc: 8.10.7
+    env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.10.7.yaml"
+
+  - ghc: 9.0.2
+    env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-9.0.2.yaml"
+
+  - ghc: 9.2.8
+    env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-9.2.8.yaml"
+
+  - ghc: 9.4.8
+    env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-9.4.8.yaml"
+
+  - ghc: 9.6.7
+    env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-9.6.7.yaml"
+
+  - ghc: 9.8.4
+    env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-9.8.4.yaml"
+
+  - ghc: 9.10.3
+    env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-9.10.3.yaml"
+
+  - ghc: 9.12.3
     env: STACK_YAML="$TRAVIS_BUILD_DIR/stack.yaml"
-  
+
   allow_failures:
-  
+
   - ghc: 8.0.2
     env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.0.2.yaml"
-  
+
   - ghc: 8.2.2
     env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.2.2.yaml"
-  
+
   - ghc: 8.4.4
     env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.4.4.yaml"
 
@@ -52,8 +83,9 @@
 
   - |
     if [ -z "$STACK_YAML" ]; then
-      cabal v2-update
-      cabal v2-build --enable-tests --enable-benchmarks
+      cabal update
+      cabal configure --enable-tests --enable-benchmarks --enable-documentation --test-show-details=direct --write-ghc-environment-files=always
+      cabal build all
     else
       curl -sSL https://get.haskellstack.org/ | sh
       stack --version
@@ -63,7 +95,7 @@
 script:
   - |
     if [ -z "$STACK_YAML" ]; then
-      cabal v2-test --enable-tests
+      cabal test all
     else
       stack test --system-ghc
     fi
diff --git a/examples/full-batteries/LICENSE b/examples/full-batteries/LICENSE
--- a/examples/full-batteries/LICENSE
+++ b/examples/full-batteries/LICENSE
@@ -1,6 +1,6 @@
 MIT License
 
-Copyright (c) 2018 Kowainik
+Copyright (c) 2022 Kowainik
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/examples/full-batteries/README.md b/examples/full-batteries/README.md
--- a/examples/full-batteries/README.md
+++ b/examples/full-batteries/README.md
@@ -1,8 +1,8 @@
 # full-batteries
 
 [![GitHub CI](https://github.com/kowainik/full-batteries/workflows/CI/badge.svg)](https://github.com/kowainik/full-batteries/actions)
-[![Build status](https://img.shields.io/travis/kowainik/full-batteries.svg?logo=travis)](https://travis-ci.org/kowainik/full-batteries)
-[![Windows build status](https://ci.appveyor.com/api/projects/status/github/kowainik/full-batteries?branch=master&svg=true)](https://ci.appveyor.com/project/kowainik/full-batteries)
+[![Build status](https://img.shields.io/travis/kowainik/full-batteries.svg?logo=travis)](https://travis-ci.com/kowainik/full-batteries)
+[![Windows build status](https://ci.appveyor.com/api/projects/status/github/kowainik/full-batteries?branch=main&svg=true)](https://ci.appveyor.com/project/kowainik/full-batteries)
 [![Hackage](https://img.shields.io/hackage/v/full-batteries.svg?logo=haskell)](https://hackage.haskell.org/package/full-batteries)
 [![Stackage Lts](http://stackage.org/package/full-batteries/badge/lts)](http://stackage.org/lts/package/full-batteries)
 [![Stackage Nightly](http://stackage.org/package/full-batteries/badge/nightly)](http://stackage.org/nightly/package/full-batteries)
diff --git a/examples/full-batteries/app/Main.hs b/examples/full-batteries/app/Main.hs
--- a/examples/full-batteries/app/Main.hs
+++ b/examples/full-batteries/app/Main.hs
@@ -1,7 +1,7 @@
 module Main (main) where
 
-import FullBatteries (someFunc)
+import FullBatteries (projectName)
 
 
 main :: IO ()
-main = someFunc
+main = putStrLn ("Executable for " ++ projectName)
diff --git a/examples/full-batteries/appveyor.yml b/examples/full-batteries/appveyor.yml
--- a/examples/full-batteries/appveyor.yml
+++ b/examples/full-batteries/appveyor.yml
@@ -4,6 +4,11 @@
 # Do not build feature branch with open Pull Requests
 skip_branch_with_pr: true
 
+# build only main branch
+branches:
+  only:
+    - main
+
 platform:
   - x86_64
 
@@ -16,19 +21,20 @@
     CABOPTS: --store-dir=C:\\SR
 
   matrix:
-    - GHCVER: 8.8.3
+    - GHCVER: 9.12.3
 
 install:
   - choco source add -n mistuke -s https://www.myget.org/F/mistuke/api/v2
-  - choco install -y cabal --version 2.4.1.0
-  - choco install -y ghc   --version 8.8.3
+  - choco install -y cabal --version 3.6.2.0
+  - choco install -y ghc   --version 9.12.3
   - refreshenv
 
 before_build:
   - cabal --version
   - ghc   --version
-  - cabal %CABOPTS% v2-update
+  - cabal %CABOPTS% update
 
 build_script:
-  - cabal %CABOPTS% v2-build --enable-tests
-  - cabal %CABOPTS% v2-test  --enable-tests
+  - cabal %CABOPTS% configure --enable-tests --enable-benchmarks --enable-documentation --test-show-details=direct --write-ghc-environment-files=always
+  - cabal %CABOPTS% build all
+  - cabal %CABOPTS% test  all
diff --git a/examples/full-batteries/benchmark/Main.hs b/examples/full-batteries/benchmark/Main.hs
--- a/examples/full-batteries/benchmark/Main.hs
+++ b/examples/full-batteries/benchmark/Main.hs
@@ -1,7 +1,7 @@
 module Main (main) where
 
-import Gauge.Main
+import FullBatteries (projectName)
 
 
 main :: IO ()
-main = defaultMain [bench "const" (whnf const ())]
+main = putStrLn ("Benchmarks for " ++ projectName)
diff --git a/examples/full-batteries/full-batteries.cabal b/examples/full-batteries/full-batteries.cabal
--- a/examples/full-batteries/full-batteries.cabal
+++ b/examples/full-batteries/full-batteries.cabal
@@ -1,15 +1,17 @@
-cabal-version:       2.4
+cabal-version:       3.0
 name:                full-batteries
 version:             0.0.0.0
 synopsis:            Full-featured test project
-description:         Full-featured test project
+description:
+    Full-featured test project.
+    See [README.md](https://github.com/kowainik/full-batteries#full-batteries) for more details.
 homepage:            https://github.com/kowainik/full-batteries
 bug-reports:         https://github.com/kowainik/full-batteries/issues
 license:             MIT
 license-file:        LICENSE
 author:              Kowainik
 maintainer:          Kowainik <xrom.xkov@gmail.com>
-copyright:           2020 Kowainik
+copyright:           2022 Kowainik
 category:            Testing
 build-type:          Simple
 extra-doc-files:     README.md
@@ -18,19 +20,27 @@
                      GHC == 8.2.2
                      GHC == 8.4.4
                      GHC == 8.6.5
-                     GHC == 8.8.3
+                     GHC == 8.8.4
+                     GHC == 8.10.7
+                     GHC == 9.0.2
+                     GHC == 9.2.8
+                     GHC == 9.4.8
+                     GHC == 9.6.7
+                     GHC == 9.8.4
+                     GHC == 9.10.3
+                     GHC == 9.12.3
 
 source-repository head
   type:                git
   location:            https://github.com/kowainik/full-batteries.git
 
 common common-options
-  build-depends:       base >= 4.9.1.0 && < 4.14
+  build-depends:       base >= 4.9.1.0 && < 4.22
                      , relude
-  
+
   mixins:              base hiding (Prelude)
                      , relude (Relude as Prelude)
-  
+
   ghc-options:         -Wcompat
                        -Widentities
 
@@ -68,8 +78,7 @@
   type:                exitcode-stdio-1.0
   hs-source-dirs:      benchmark
   main-is:             Main.hs
-  build-depends:       gauge
-                     , full-batteries
+  build-depends:       full-batteries
   ghc-options:         -threaded
                        -rtsopts
                        -with-rtsopts=-N
diff --git a/examples/full-batteries/src/FullBatteries.hs b/examples/full-batteries/src/FullBatteries.hs
--- a/examples/full-batteries/src/FullBatteries.hs
+++ b/examples/full-batteries/src/FullBatteries.hs
@@ -1,5 +1,5 @@
 {- |
-Copyright: (c) 2020 Kowainik
+Copyright: (c) 2022 Kowainik
 SPDX-License-Identifier: MIT
 Maintainer: Kowainik <xrom.xkov@gmail.com>
 
@@ -7,9 +7,9 @@
 -}
 
 module FullBatteries
-       ( someFunc
-       ) where
+    ( projectName
+    ) where
 
 
-someFunc :: IO ()
-someFunc = putStrLn ("someFunc" :: String)
+projectName :: String
+projectName = "full-batteries"
diff --git a/examples/full-batteries/stack-8.10.7.yaml b/examples/full-batteries/stack-8.10.7.yaml
new file mode 100644
--- /dev/null
+++ b/examples/full-batteries/stack-8.10.7.yaml
@@ -0,0 +1,1 @@
+resolver: lts-18.28
diff --git a/examples/full-batteries/stack-8.8.4.yaml b/examples/full-batteries/stack-8.8.4.yaml
new file mode 100644
--- /dev/null
+++ b/examples/full-batteries/stack-8.8.4.yaml
@@ -0,0 +1,1 @@
+resolver: lts-16.31
diff --git a/examples/full-batteries/stack-9.0.2.yaml b/examples/full-batteries/stack-9.0.2.yaml
new file mode 100644
--- /dev/null
+++ b/examples/full-batteries/stack-9.0.2.yaml
@@ -0,0 +1,1 @@
+resolver: lts-19.33
diff --git a/examples/full-batteries/stack-9.10.3.yaml b/examples/full-batteries/stack-9.10.3.yaml
new file mode 100644
--- /dev/null
+++ b/examples/full-batteries/stack-9.10.3.yaml
@@ -0,0 +1,1 @@
+resolver: lts-24.26
diff --git a/examples/full-batteries/stack-9.2.8.yaml b/examples/full-batteries/stack-9.2.8.yaml
new file mode 100644
--- /dev/null
+++ b/examples/full-batteries/stack-9.2.8.yaml
@@ -0,0 +1,1 @@
+resolver: lts-20.26
diff --git a/examples/full-batteries/stack-9.4.8.yaml b/examples/full-batteries/stack-9.4.8.yaml
new file mode 100644
--- /dev/null
+++ b/examples/full-batteries/stack-9.4.8.yaml
@@ -0,0 +1,1 @@
+resolver: lts-21.25
diff --git a/examples/full-batteries/stack-9.6.7.yaml b/examples/full-batteries/stack-9.6.7.yaml
new file mode 100644
--- /dev/null
+++ b/examples/full-batteries/stack-9.6.7.yaml
@@ -0,0 +1,1 @@
+resolver: lts-22.44
diff --git a/examples/full-batteries/stack-9.8.4.yaml b/examples/full-batteries/stack-9.8.4.yaml
new file mode 100644
--- /dev/null
+++ b/examples/full-batteries/stack-9.8.4.yaml
@@ -0,0 +1,1 @@
+resolver: lts-23.28
diff --git a/examples/full-batteries/stack.yaml b/examples/full-batteries/stack.yaml
--- a/examples/full-batteries/stack.yaml
+++ b/examples/full-batteries/stack.yaml
@@ -1,1 +1,1 @@
-resolver: lts-15.5
+resolver: nightly-2026-01-04
diff --git a/examples/full-batteries/test/Spec.hs b/examples/full-batteries/test/Spec.hs
--- a/examples/full-batteries/test/Spec.hs
+++ b/examples/full-batteries/test/Spec.hs
@@ -1,5 +1,7 @@
 module Main (main) where
 
+import FullBatteries (projectName)
 
+
 main :: IO ()
-main = putStrLn ("Test suite is not implemented" :: String)
+main = putStrLn ("Tests for " ++ projectName)
diff --git a/examples/stack-full/.gitignore b/examples/stack-full/.gitignore
--- a/examples/stack-full/.gitignore
+++ b/examples/stack-full/.gitignore
@@ -21,6 +21,7 @@
 cabal.project.local
 .ghc.environment.*
 .HTF/
+.hie/
 # Stack
 .stack-work/
 stack.yaml.lock
diff --git a/examples/stack-full/.travis.yml b/examples/stack-full/.travis.yml
--- a/examples/stack-full/.travis.yml
+++ b/examples/stack-full/.travis.yml
@@ -1,32 +1,53 @@
-sudo: true
 language: haskell
 
 git:
   depth: 5
 
-cabal: "2.4"
+cabal: "3.14.2.0"
 
 cache:
   directories:
-  
   - "$HOME/.stack"
   - "$TRAVIS_BUILD_DIR/.stack-work"
 
-matrix:
+jobs:
   include:
-  
-  
+
   - ghc: 8.4.4
     env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.4.4.yaml"
-  
+
   - ghc: 8.6.5
     env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.6.5.yaml"
-  
-  - ghc: 8.8.3
+
+  - ghc: 8.8.4
+    env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.8.4.yaml"
+
+  - ghc: 8.10.7
+    env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.10.7.yaml"
+
+  - ghc: 9.0.2
+    env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-9.0.2.yaml"
+
+  - ghc: 9.2.8
+    env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-9.2.8.yaml"
+
+  - ghc: 9.4.8
+    env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-9.4.8.yaml"
+
+  - ghc: 9.6.7
+    env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-9.6.7.yaml"
+
+  - ghc: 9.8.4
+    env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-9.8.4.yaml"
+
+  - ghc: 9.10.3
+    env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-9.10.3.yaml"
+
+  - ghc: 9.12.3
     env: STACK_YAML="$TRAVIS_BUILD_DIR/stack.yaml"
-  
+
   allow_failures:
-  
+
   - ghc: 8.4.4
     env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.4.4.yaml"
 
diff --git a/examples/stack-full/LICENSE b/examples/stack-full/LICENSE
--- a/examples/stack-full/LICENSE
+++ b/examples/stack-full/LICENSE
@@ -1,6 +1,6 @@
 BSD 3-Clause License
 
-Copyright (c) 2020, Kowainik
+Copyright (c) 2022, Kowainik
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/examples/stack-full/README.md b/examples/stack-full/README.md
--- a/examples/stack-full/README.md
+++ b/examples/stack-full/README.md
@@ -1,7 +1,8 @@
 # stack-full
 
-[![Build status](https://img.shields.io/travis/kowainik/stack-full.svg?logo=travis)](https://travis-ci.org/kowainik/stack-full)
-[![Windows build status](https://ci.appveyor.com/api/projects/status/github/kowainik/stack-full?branch=master&svg=true)](https://ci.appveyor.com/project/kowainik/stack-full)
+[![GitHub CI](https://github.com/kowainik/stack-full/workflows/CI/badge.svg)](https://github.com/kowainik/stack-full/actions)
+[![Build status](https://img.shields.io/travis/kowainik/stack-full.svg?logo=travis)](https://travis-ci.com/kowainik/stack-full)
+[![Windows build status](https://ci.appveyor.com/api/projects/status/github/kowainik/stack-full?branch=main&svg=true)](https://ci.appveyor.com/project/kowainik/stack-full)
 [![Hackage](https://img.shields.io/hackage/v/stack-full.svg?logo=haskell)](https://hackage.haskell.org/package/stack-full)
 [![Stackage Lts](http://stackage.org/package/stack-full/badge/lts)](http://stackage.org/lts/package/stack-full)
 [![Stackage Nightly](http://stackage.org/package/stack-full/badge/nightly)](http://stackage.org/nightly/package/stack-full)
diff --git a/examples/stack-full/app/Main.hs b/examples/stack-full/app/Main.hs
--- a/examples/stack-full/app/Main.hs
+++ b/examples/stack-full/app/Main.hs
@@ -1,7 +1,7 @@
 module Main (main) where
 
-import StackFull (someFunc)
+import StackFull (projectName)
 
 
 main :: IO ()
-main = someFunc
+main = putStrLn ("Executable for " ++ projectName)
diff --git a/examples/stack-full/appveyor.yml b/examples/stack-full/appveyor.yml
--- a/examples/stack-full/appveyor.yml
+++ b/examples/stack-full/appveyor.yml
@@ -3,9 +3,14 @@
 # Do not build feature branch with open Pull Requests
 skip_branch_with_pr: true
 
+# build only main branch
+branches:
+  only:
+    - main
+
 environment:
   STACK_ROOT: C:\sr
-  STACK_VERSION: 2.1.1
+  STACK_VERSION: 3.3.1
 
   # Workaround a gnarly bug https://github.com/haskell/cabal/issues/5386
   # See: https://www.fpcomplete.com/blog/2018/06/sed-a-debugging-story
diff --git a/examples/stack-full/benchmark/Main.hs b/examples/stack-full/benchmark/Main.hs
--- a/examples/stack-full/benchmark/Main.hs
+++ b/examples/stack-full/benchmark/Main.hs
@@ -1,7 +1,7 @@
 module Main (main) where
 
-import Gauge.Main
+import StackFull (projectName)
 
 
 main :: IO ()
-main = defaultMain [bench "const" (whnf const ())]
+main = putStrLn ("Benchmarks for " ++ projectName)
diff --git a/examples/stack-full/src/StackFull.hs b/examples/stack-full/src/StackFull.hs
--- a/examples/stack-full/src/StackFull.hs
+++ b/examples/stack-full/src/StackFull.hs
@@ -1,5 +1,5 @@
 {- |
-Copyright: (c) 2020 Kowainik
+Copyright: (c) 2022 Kowainik
 SPDX-License-Identifier: BSD-3-Clause
 Maintainer: Kowainik <xrom.xkov@gmail.com>
 
@@ -7,9 +7,9 @@
 -}
 
 module StackFull
-       ( someFunc
-       ) where
+    ( projectName
+    ) where
 
 
-someFunc :: IO ()
-someFunc = putStrLn ("someFunc" :: String)
+projectName :: String
+projectName = "stack-full"
diff --git a/examples/stack-full/stack-8.10.7.yaml b/examples/stack-full/stack-8.10.7.yaml
new file mode 100644
--- /dev/null
+++ b/examples/stack-full/stack-8.10.7.yaml
@@ -0,0 +1,1 @@
+resolver: lts-18.28
diff --git a/examples/stack-full/stack-8.8.4.yaml b/examples/stack-full/stack-8.8.4.yaml
new file mode 100644
--- /dev/null
+++ b/examples/stack-full/stack-8.8.4.yaml
@@ -0,0 +1,1 @@
+resolver: lts-16.31
diff --git a/examples/stack-full/stack-9.0.2.yaml b/examples/stack-full/stack-9.0.2.yaml
new file mode 100644
--- /dev/null
+++ b/examples/stack-full/stack-9.0.2.yaml
@@ -0,0 +1,1 @@
+resolver: lts-19.33
diff --git a/examples/stack-full/stack-9.10.3.yaml b/examples/stack-full/stack-9.10.3.yaml
new file mode 100644
--- /dev/null
+++ b/examples/stack-full/stack-9.10.3.yaml
@@ -0,0 +1,1 @@
+resolver: lts-24.26
diff --git a/examples/stack-full/stack-9.2.8.yaml b/examples/stack-full/stack-9.2.8.yaml
new file mode 100644
--- /dev/null
+++ b/examples/stack-full/stack-9.2.8.yaml
@@ -0,0 +1,1 @@
+resolver: lts-20.26
diff --git a/examples/stack-full/stack-9.4.8.yaml b/examples/stack-full/stack-9.4.8.yaml
new file mode 100644
--- /dev/null
+++ b/examples/stack-full/stack-9.4.8.yaml
@@ -0,0 +1,1 @@
+resolver: lts-21.25
diff --git a/examples/stack-full/stack-9.6.7.yaml b/examples/stack-full/stack-9.6.7.yaml
new file mode 100644
--- /dev/null
+++ b/examples/stack-full/stack-9.6.7.yaml
@@ -0,0 +1,1 @@
+resolver: lts-22.44
diff --git a/examples/stack-full/stack-9.8.4.yaml b/examples/stack-full/stack-9.8.4.yaml
new file mode 100644
--- /dev/null
+++ b/examples/stack-full/stack-9.8.4.yaml
@@ -0,0 +1,1 @@
+resolver: lts-23.28
diff --git a/examples/stack-full/stack-full.cabal b/examples/stack-full/stack-full.cabal
--- a/examples/stack-full/stack-full.cabal
+++ b/examples/stack-full/stack-full.cabal
@@ -1,41 +1,51 @@
-cabal-version:       2.4
+cabal-version:       3.0
 name:                stack-full
 version:             0.0.0.0
 synopsis:            Stack-only example with all integrations
-description:         Stack-only example with all integrations
+description:
+    Stack-only example with all integrations.
+    See [README.md](https://github.com/kowainik/stack-full#stack-full) for more details.
 homepage:            https://github.com/kowainik/stack-full
 bug-reports:         https://github.com/kowainik/stack-full/issues
 license:             BSD-3-Clause
 license-file:        LICENSE
 author:              Kowainik
 maintainer:          Kowainik <xrom.xkov@gmail.com>
-copyright:           2020 Kowainik
+copyright:           2022 Kowainik
 category:            Testing
 build-type:          Simple
 extra-doc-files:     README.md
                      CHANGELOG.md
 tested-with:         GHC == 8.4.4
                      GHC == 8.6.5
-                     GHC == 8.8.3
+                     GHC == 8.8.4
+                     GHC == 8.10.7
+                     GHC == 9.0.2
+                     GHC == 9.2.8
+                     GHC == 9.4.8
+                     GHC == 9.6.7
+                     GHC == 9.8.4
+                     GHC == 9.10.3
+                     GHC == 9.12.3
 
 source-repository head
   type:                git
   location:            https://github.com/kowainik/stack-full.git
 
 common common-options
-  build-depends:       base >= 4.11.1.0 && < 4.14
+  build-depends:       base >= 4.11.1.0 && < 4.22
                      , relude
-  
+
   mixins:              base hiding (Prelude)
                      , relude (Relude as Prelude)
-  
+
   ghc-options:         -Wall
                        -Wcompat
                        -Widentities
                        -Wincomplete-uni-patterns
                        -Wincomplete-record-updates
-  if impl(ghc >= 8.0)
-    ghc-options:       -Wredundant-constraints
+                       -Wredundant-constraints
+                       -Wnoncanonical-monad-instances
   if impl(ghc >= 8.2)
     ghc-options:       -fhide-source-paths
   if impl(ghc >= 8.4)
@@ -43,6 +53,29 @@
                        -Wpartial-fields
   if impl(ghc >= 8.8)
     ghc-options:       -Wmissing-deriving-strategies
+                       -fwrite-ide-info
+                       -hiedir=.hie
+  if impl(ghc >= 8.10)
+    ghc-options:       -Wunused-packages
+  if impl(ghc >= 9.0)
+    ghc-options:       -Winvalid-haddock
+  if impl(ghc >= 9.2)
+    ghc-options:       -Wredundant-bang-patterns
+                       -Woperator-whitespace
+  if impl(ghc >= 9.4  && < 9.10)
+    ghc-options:       -Wforall-identifier
+  if impl(ghc >= 9.4)
+    ghc-options:       -Wredundant-strictness-flags
+  if impl(ghc >= 9.8)
+    ghc-options:       -Wterm-variable-capture
+                       -Winconsistent-flags
+  if impl(ghc >= 9.10)
+    ghc-options:       -Wincomplete-record-selectors
+                       -Wdeprecated-type-abstractions
+                       -Wdata-kinds-tc
+                       -Wdefaulted-exception-context
+  if impl(ghc >= 9.12)
+    ghc-options:       -Wview-pattern-signatures
 
   default-language:    Haskell2010
   default-extensions:  DeriveGeneric
@@ -77,8 +110,7 @@
   type:                exitcode-stdio-1.0
   hs-source-dirs:      benchmark
   main-is:             Main.hs
-  build-depends:       gauge
-                     , stack-full
+  build-depends:       stack-full
   ghc-options:         -threaded
                        -rtsopts
                        -with-rtsopts=-N
diff --git a/examples/stack-full/stack.yaml b/examples/stack-full/stack.yaml
--- a/examples/stack-full/stack.yaml
+++ b/examples/stack-full/stack.yaml
@@ -1,1 +1,1 @@
-resolver: lts-15.5
+resolver: nightly-2026-01-04
diff --git a/examples/stack-full/test/Spec.hs b/examples/stack-full/test/Spec.hs
--- a/examples/stack-full/test/Spec.hs
+++ b/examples/stack-full/test/Spec.hs
@@ -1,5 +1,7 @@
 module Main (main) where
 
+import StackFull (projectName)
 
+
 main :: IO ()
-main = putStrLn ("Test suite is not implemented" :: String)
+main = putStrLn ("Tests for " ++ projectName)
diff --git a/examples/summoner-default.toml b/examples/summoner-default.toml
--- a/examples/summoner-default.toml
+++ b/examples/summoner-default.toml
@@ -48,9 +48,9 @@
 # travis = true         # Travis CI
 # appveyor = true       # AppVeyor CI
 
-# List of additional GHC versions to support besides 8.8.3.
+# List of additional GHC versions to support besides 9.12.3.
 # Run the 'summon show ghc' command to see the list of all supported GHC versions.
-# ghcVersions = ["8.4.4", "8.6.5"]
+# ghcVersions = ["9.8.4", "9.10.3"]
 
 # List of default-extensions in the .cabal file
 # extensions = [ "ConstraintKinds"
@@ -71,7 +71,7 @@
 # List of additional files to add after creating the project
 # files =
 #     [ { path = ".stylish-haskell.yaml"
-#       , url  = "https://raw.githubusercontent.com/kowainik/org/master/.stylish-haskell.yaml"
+#       , url  = "https://raw.githubusercontent.com/kowainik/org/main/.stylish-haskell.yaml"
 #       }
 #     , { path = ".github/CODEOWNERS"
 #       , raw  = "*  @kowainik"
diff --git a/golden/Main.hs b/golden/Main.hs
new file mode 100644
--- /dev/null
+++ b/golden/Main.hs
@@ -0,0 +1,9 @@
+module Main (main) where
+
+import Summoner.Golden (generateProjects, generateScripts, generateTomlConfig)
+
+main :: IO ()
+main = do
+    generateScripts
+    generateTomlConfig
+    generateProjects
diff --git a/src/Summoner.hs b/src/Summoner.hs
--- a/src/Summoner.hs
+++ b/src/Summoner.hs
@@ -1,7 +1,10 @@
 {- |
-Copyright: (c) 2017-2019 Kowainik
-SPDX-License-Identifier: MPL-2.0
-Maintainer: Kowainik <xrom.xkov@gmail.com>
+Module                  : Summoner
+Copyright               : (c) 2017-2026 Kowainik
+SPDX-License-Identifier : MPL-2.0
+Maintainer              : Kowainik <xrom.xkov@gmail.com>
+Stability               : Stable
+Portability             : Portable
 
 Main module that reexports all library components of the @summoner@.
 -}
diff --git a/src/Summoner/CLI.hs b/src/Summoner/CLI.hs
--- a/src/Summoner/CLI.hs
+++ b/src/Summoner/CLI.hs
@@ -1,47 +1,47 @@
 {-# LANGUAGE ApplicativeDo   #-}
-{-# LANGUAGE QuasiQuotes     #-}
 {-# LANGUAGE TemplateHaskell #-}
 {-# LANGUAGE TupleSections   #-}
 
 {- |
-Copyright: (c) 2017-2019 Kowainik
-SPDX-License-Identifier: MPL-2.0
-Maintainer: Kowainik <xrom.xkov@gmail.com>
+Module                  : Summoner.CLI
+Copyright               : (c) 2017-2026 Kowainik
+SPDX-License-Identifier : MPL-2.0
+Maintainer              : Kowainik <xrom.xkov@gmail.com>
+Stability               : Stable
+Portability             : Portable
 
 This module contains functions and data types to parse CLI inputs.
 -}
 
 module Summoner.CLI
-       ( -- * CLI data types
-         Command (..)
-       , NewOpts (..)
-       , ShowOpts (..)
+    ( -- * CLI data types
+      Command (..)
+    , NewOpts (..)
+    , ShowOpts (..)
 
-         -- * Functions to parse CLI arguments and run @summoner@
-       , summon
-       , summonCli
+      -- * Functions to parse CLI arguments and run @summoner@
+    , summon
+    , summonCli
 
-         -- * Runners
-       , runConfig
-       , runScript
+      -- * Runners
+    , runConfig
+    , runScript
 
-         -- * Common helper functions
-       , getFinalConfig
-       , getCustomLicenseText
-       ) where
+      -- * Common helper functions
+    , getFinalConfig
+    , getCustomLicenseText
+    ) where
 
 import Colourista (blue, bold, errorMessage, formatWith, infoMessage, successMessage,
                    warningMessage)
 import Data.Version (Version, showVersion)
 import Development.GitRev (gitCommitDate, gitHash)
-import NeatInterpolation (text)
 import Options.Applicative (Parser, ParserInfo, ParserPrefs, argument, command, customExecParser,
                             flag, fullDesc, help, helpLongEquals, helper, info, infoFooter,
                             infoHeader, infoOption, long, maybeReader, metavar, option, prefs,
                             progDesc, short, showDefault, showHelpOnEmpty, strArgument, strOption,
                             subparser, subparserInline, switch, value)
 import Options.Applicative.Help.Chunk (stringChunk)
-import Relude.Extra.Enum (universe)
 import System.Directory (doesFileExist)
 import System.Info (os)
 import Validation (Validation (..))
@@ -58,7 +58,6 @@
 import Summoner.Project (generateProject)
 import Summoner.Settings (Tool, parseTool)
 import Summoner.Template.Script (scriptFile)
-import Summoner.Text (endLine)
 
 import qualified Data.Text as T
 import qualified Paths_summoner as Meta (version)
@@ -84,10 +83,10 @@
 -- | Run 'summoner' with @CLI@ command
 runCliCommand :: Command -> IO ()
 runCliCommand = \case
-    New opts -> runNew opts
-    Script opts -> runScript opts
+    New opts      -> runNew opts
+    Script opts   -> runScript opts
     ShowInfo opts -> runShow opts
-    Config opts -> runConfig opts
+    Config opts   -> runConfig opts
 
 
 {- | Runs @config@ command
@@ -254,13 +253,13 @@
 -- | Represent all available commands
 data Command
     -- | @new@ command creates a new project
-    = New NewOpts
+    = New !NewOpts
     -- | @script@ command creates Haskell script
-    | Script ScriptOpts
+    | Script !ScriptOpts
     -- | @show@ command shows supported licenses or GHC versions
-    | ShowInfo ShowOpts
+    | ShowInfo !ShowOpts
     -- | @config@ command creates the TOML configuration file
-    | Config ConfigOpts
+    | Config !ConfigOpts
 
 -- | Options parsed with the @new@ command
 data NewOpts = NewOpts
@@ -282,7 +281,7 @@
 -- | Commands parsed with @show@ command
 data ShowOpts
     = GhcList
-    | LicenseList (Maybe String)
+    | LicenseList !(Maybe String)
 
 -- | Options parsed with the @config@ command
 newtype ConfigOpts = ConfigOpts
@@ -424,7 +423,7 @@
     cExe       <- execP      d
     cTest      <- testP      d
     cBench     <- benchmarkP d
-    pure mempty
+    pure (mempty :: PartialConfig)
         { cGitHub    = cGitHub
         , cGhActions = cGhActions
         , cTravis    = cTravis
@@ -583,39 +582,39 @@
 modifyFooter p = p {infoFooter = stringChunk $ toString artFooter}
 
 artHeader :: Text
-artHeader = [text|
-$endLine
-                                                   ___
-                                                 ╱  .  ╲
-                                                │╲_/│   │
-                                                │   │  ╱│
-  ___________________________________________________-' │
- ╱                                                      │
-╱   .-.                                                 │
-│  ╱   ╲                                                │
-│ │\_.  │ Summoner — tool for creating Haskell projects │
-│\│  │ ╱│                                               │
-│ `-_-' │                                              ╱
-│       │_____________________________________________╱
-│       │
- ╲     ╱
-  `-_-'
-|]
+artHeader = unlines
+    [ ""
+    , "                                                   ___"
+    , "                                                 ╱  .  ╲"
+    , "                                                │╲_/│   │"
+    , "                                                │   │  ╱│"
+    , "  ___________________________________________________-' │"
+    , " ╱                                                      │"
+    , "╱   .-.                                                 │"
+    , "│  ╱   ╲                                                │"
+    , "│ │\\_.  │ Summoner — tool for creating Haskell projects │"
+    , "│\\│  │ ╱│                                               │"
+    , "│ `-_-' │                                              ╱"
+    , "│       │_____________________________________________╱"
+    , "│       │"
+    , " ╲     ╱"
+    , "  `-_-'"
+    ]
 
 artFooter :: Text
-artFooter = [text|
-$endLine
-              , *   +
-           +      o   *             ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
-            * @ ╭─╮  .      ________┃                                 ┃_______
-           ╱| . │λ│ @   '   ╲       ┃   λ Haskell's summon scroll λ   ┃      ╱
-         _╱ ╰─  ╰╥╯    O     ╲      ┃                                 ┃     ╱
-        .─╲"╱. * ║  +        ╱      ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛     ╲
-       ╱  ( ) ╲_ ║          ╱__________)                           (_________╲
-       ╲ ╲(')╲__(╱
-       ╱╱`)╱ `╮  ║
- `╲.  ╱╱  (   │  ║
-  ╲.╲╱        │  ║
-  `╰══════════╯
-$endLine
-|]
+artFooter = unlines
+    [ ""
+    , "              , *   +"
+    , "           +      o   *             ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓"
+    , "            * @ ╭─╮  .      ________┃                                 ┃_______"
+    , "           ╱| . │λ│ @   '   ╲       ┃   λ Haskell's summon scroll λ   ┃      ╱"
+    , "         _╱ ╰─  ╰╥╯    O     ╲      ┃                                 ┃     ╱"
+    , "        .─╲\"╱. * ║  +        ╱      ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛     ╲"
+    , "       ╱  ( ) ╲_ ║          ╱__________)                           (_________╲"
+    , "       ╲ ╲(')╲__(╱"
+    , "       ╱╱`)╱ `╮  ║"
+    , " `╲.  ╱╱  (   │  ║"
+    , "  ╲.╲╱        │  ║"
+    , "  `╰══════════╯"
+    , ""
+    ]
diff --git a/src/Summoner/Config.hs b/src/Summoner/Config.hs
--- a/src/Summoner/Config.hs
+++ b/src/Summoner/Config.hs
@@ -7,9 +7,12 @@
 {-# LANGUAGE UndecidableInstances #-}
 
 {- |
-Copyright: (c) 2017-2019 Kowainik
-SPDX-License-Identifier: MPL-2.0
-Maintainer: Kowainik <xrom.xkov@gmail.com>
+Module                  : Summoner.Config
+Copyright               : (c) 2017-2026 Kowainik
+SPDX-License-Identifier : MPL-2.0
+Maintainer              : Kowainik <xrom.xkov@gmail.com>
+Stability               : Stable
+Portability             : Portable
 
 Summoner configurations.
 -}
@@ -29,6 +32,7 @@
 
 import Data.List (lookup)
 import Generic.Data (gmappend, gmempty)
+import Generic.Data.Orphans ()
 import Shellmet (($?), ($|))
 import Toml (Key, TomlBiMap, TomlCodec, (.=))
 import Validation (Validation (..))
diff --git a/src/Summoner/CustomPrelude.hs b/src/Summoner/CustomPrelude.hs
--- a/src/Summoner/CustomPrelude.hs
+++ b/src/Summoner/CustomPrelude.hs
@@ -1,7 +1,10 @@
 {- |
-Copyright: (c) 2017-2019 Kowainik
-SPDX-License-Identifier: MPL-2.0
-Maintainer: Kowainik <xrom.xkov@gmail.com>
+Module                  : Summoner.CustomPrelude
+Copyright               : (c) 2017-2026 Kowainik
+SPDX-License-Identifier : MPL-2.0
+Maintainer              : Kowainik <xrom.xkov@gmail.com>
+Stability               : Stable
+Portability             : Portable
 
 This module implements data type for representing custom alternative preludes.
 -}
diff --git a/src/Summoner/Decision.hs b/src/Summoner/Decision.hs
--- a/src/Summoner/Decision.hs
+++ b/src/Summoner/Decision.hs
@@ -1,7 +1,10 @@
 {- |
-Copyright: (c) 2017-2019 Kowainik
-SPDX-License-Identifier: MPL-2.0
-Maintainer: Kowainik <xrom.xkov@gmail.com>
+Module                  : Summoner.Decision
+Copyright               : (c) 2017-2026 Kowainik
+SPDX-License-Identifier : MPL-2.0
+Maintainer              : Kowainik <xrom.xkov@gmail.com>
+Stability               : Stable
+Portability             : Portable
 
 Decision data type.
 -}
diff --git a/src/Summoner/Default.hs b/src/Summoner/Default.hs
--- a/src/Summoner/Default.hs
+++ b/src/Summoner/Default.hs
@@ -1,9 +1,10 @@
-{-# LANGUAGE QuasiQuotes #-}
-
 {- |
-Copyright: (c) 2017-2019 Kowainik
-SPDX-License-Identifier: MPL-2.0
-Maintainer: Kowainik <xrom.xkov@gmail.com>
+Module                  : Summoner.Default
+Copyright               : (c) 2017-2026 Kowainik
+SPDX-License-Identifier : MPL-2.0
+Maintainer              : Kowainik <xrom.xkov@gmail.com>
+Stability               : Stable
+Portability             : Portable
 
 This module contains some default values to use.
 -}
@@ -11,6 +12,8 @@
 module Summoner.Default
        ( defaultGHC
        , defaultCabal
+       , defaultCabalVersion
+       , defaultStack
        , defaultLicenseName
        , defaultOwner
        , defaultFullName
@@ -20,15 +23,22 @@
        , defaultConfigFileContent
        , defaultDescription
        , currentYear
+
+         -- * GitHub Actions defaults
+       , ghcActionsCacheVersion
+       , ghcActionsCheckoutVersion
+       , ghcActionsSetupHaskellVersion
        ) where
 
-import Data.Time (getCurrentTime, toGregorian, utctDay)
-import NeatInterpolation (text)
+import Relude.Extra.Enum (prev)
+
+import Data.Time (getCurrentTime, getCurrentTimeZone, localDay, toGregorian, utcToLocalTime)
 import System.Directory (getHomeDirectory)
 import System.FilePath ((</>))
 
 import Summoner.GhcVer (GhcVer, showGhcVer)
 import Summoner.License (LicenseName (MIT))
+import Summoner.Text (quote)
 
 
 -- | Default GHC version is the latest available.
@@ -37,8 +47,16 @@
 
 -- | Default version of the Cabal.
 defaultCabal :: Text
-defaultCabal = "2.4"
+defaultCabal = "3.14.2.0"
 
+-- | Default version of the Cabal specified in the *.cabal* file.
+defaultCabalVersion :: Text
+defaultCabalVersion = "3.0"
+
+-- | Default version of the Stack.
+defaultStack :: Text
+defaultStack = "3.3.1"
+
 defaultLicenseName :: LicenseName
 defaultLicenseName = MIT
 
@@ -60,108 +78,121 @@
 defaultDescription :: Text
 defaultDescription = "See README for more info"
 
+ghcActionsCheckoutVersion :: Text
+ghcActionsCheckoutVersion = "@v4"
+
+ghcActionsSetupHaskellVersion :: Text
+ghcActionsSetupHaskellVersion = "@v2"
+
+ghcActionsCacheVersion :: Text
+ghcActionsCacheVersion = "@v4"
+
 currentYear :: IO Text
 currentYear = do
     now <- getCurrentTime
-    let (year, _, _) = toGregorian $ utctDay now
+    zone <- getCurrentTimeZone
+    let localNow = utcToLocalTime zone now
+    let (year, _, _) = toGregorian $ localDay localNow
     pure $ show year
 
 {- | Default content of the @~/summoner.toml@ file to be generated by
 the @summon config@ command.
 -}
 defaultConfigFileContent :: Text
-defaultConfigFileContent = [text|
-    # This file is automatically generated by Summoner.
-    # Edit required fields, uncomment additional settings or delete irrelevant
-    # lines for the personalized configuration.
-
-    # GitHub user name
-    owner = "$defaultOwner"
-
-    # First and last name
-    fullName = "$defaultFullName"
-
-    # Email used at GitHub
-    email = "$defaultEmail"
-
-    # Default OSS license for your projects.
-    # Run the 'summon show license' command to see the list of supported licenses.
-    license = "$licenseName"
-
-    # Create projects with the Cabal support
-    # cabal = true
-
-    # Create projects with the Stack support
-    # stack = true
-
-    # Should your projects have the library stanza by default?
-    # lib = true
-
-    # Should your projects have an executable stanza by default?
-    # exe = true
-
-    # Should your projects have the test-suite stanza by default?
-    # test = true
-
-    # Should your projects have the benchmark stanza by default?
-    # bench = true
-
-    # Summoner suports 'git' version control system and GitHub as a platform for
-    # hosting 'git' repos. The following set of flags controls integration with GitHub.
-    # github = true    # enabled GitHub integration
-    # noUpload = true  # Init git repo, but don't create it on GitHub
-    # private = true  # create private repos by default
-    # gitignore =      # list of additional entries to be added in .gitignore
-    #     [ "build"
-    #     , "result"
-    #     ]
-
-    # Summoner supports various CI services. Uncomment those you want to use by default.
-    # githubActions = true  # GitHub Actions CI
-    # travis = true         # Travis CI
-    # appveyor = true       # AppVeyor CI
-
-    # List of additional GHC versions to support besides $defaultGhcVer.
-    # Run the 'summon show ghc' command to see the list of all supported GHC versions.
-    # ghcVersions = ["8.4.4", "8.6.5"]
-
-    # List of default-extensions in the .cabal file
-    # extensions = [ "ConstraintKinds"
-    #              , "DeriveGeneric"
-    #              , "GeneralizedNewtypeDeriving"
-    #              , "InstanceSigs"
-    #              , "KindSignatures"
-    #              , "LambdaCase"
-    #              , "OverloadedStrings"
-    #              , "RecordWildCards"
-    #              , "ScopedTypeVariables"
-    #              , "StandaloneDeriving"
-    #              , "TupleSections"
-    #              , "TypeApplications"
-    #              , "ViewPatterns"
-    #              ]
-
-    # List of additional files to add after creating the project
-    # files =
-    #     [ { path = ".stylish-haskell.yaml"
-    #       , url  = "https://raw.githubusercontent.com/kowainik/org/master/.stylish-haskell.yaml"
-    #       }
-    #     , { path = ".github/CODEOWNERS"
-    #       , raw  = "*  @$defaultOwner"
-    #       }
-    #     , { path  = "src/Foo.hs"
-    #       , local = "/home/user/.default/Foo.hs"
-    #       }
-    #     ]
-
-    # Alternative Prelude to be used instead of the default one if you prefer
-    # [prelude]
-    #     package = "relude"
-    #     module  = "Relude"
-|]
+defaultConfigFileContent = unlines
+    [ "# This file is automatically generated by Summoner."
+    , "# Edit required fields, uncomment additional settings or delete irrelevant"
+    , "# lines for the personalized configuration."
+    , ""
+    , "# GitHub user name"
+    , "owner = " <> quote defaultOwner
+    , ""
+    , "# First and last name"
+    , "fullName = " <> quote defaultFullName
+    , ""
+    , "# Email used at GitHub"
+    , "email = " <> quote defaultEmail
+    , ""
+    , "# Default OSS license for your projects."
+    , "# Run the 'summon show license' command to see the list of supported licenses."
+    , "license = " <> quote licenseName
+    , ""
+    , "# Create projects with the Cabal support"
+    , "# cabal = true"
+    , ""
+    , "# Create projects with the Stack support"
+    , "# stack = true"
+    , ""
+    , "# Should your projects have the library stanza by default?"
+    , "# lib = true"
+    , ""
+    , "# Should your projects have an executable stanza by default?"
+    , "# exe = true"
+    , ""
+    , "# Should your projects have the test-suite stanza by default?"
+    , "# test = true"
+    , ""
+    , "# Should your projects have the benchmark stanza by default?"
+    , "# bench = true"
+    , ""
+    , "# Summoner suports 'git' version control system and GitHub as a platform for"
+    , "# hosting 'git' repos. The following set of flags controls integration with GitHub."
+    , "# github = true    # enabled GitHub integration"
+    , "# noUpload = true  # Init git repo, but don't create it on GitHub"
+    , "# private = true  # create private repos by default"
+    , "# gitignore =      # list of additional entries to be added in .gitignore"
+    , "#     [ " <> quote "build"
+    , "#     , " <> quote "result"
+    , "#     ]"
+    , ""
+    , "# Summoner supports various CI services. Uncomment those you want to use by default."
+    , "# githubActions = true  # GitHub Actions CI"
+    , "# travis = true         # Travis CI"
+    , "# appveyor = true       # AppVeyor CI"
+    , ""
+    , "# List of additional GHC versions to support besides " <> defaultGhcVer <> "."
+    , "# Run the 'summon show ghc' command to see the list of all supported GHC versions."
+    , "# ghcVersions = [" <> quote defaultGhcPrevPrev <> ", " <> quote defaultGhcPrev <> "]"
+    , ""
+    , "# List of default-extensions in the .cabal file"
+    , "# extensions = [ " <> quote "ConstraintKinds"
+    , "#              , " <> quote "DeriveGeneric"
+    , "#              , " <> quote "GeneralizedNewtypeDeriving"
+    , "#              , " <> quote "InstanceSigs"
+    , "#              , " <> quote "KindSignatures"
+    , "#              , " <> quote "LambdaCase"
+    , "#              , " <> quote "OverloadedStrings"
+    , "#              , " <> quote "RecordWildCards"
+    , "#              , " <> quote "ScopedTypeVariables"
+    , "#              , " <> quote "StandaloneDeriving"
+    , "#              , " <> quote "TupleSections"
+    , "#              , " <> quote "TypeApplications"
+    , "#              , " <> quote "ViewPatterns"
+    , "#              ]"
+    , ""
+    , "# List of additional files to add after creating the project"
+    , "# files ="
+    , "#     [ { path = " <> quote ".stylish-haskell.yaml"
+    , "#       , url  = " <> quote "https://raw.githubusercontent.com/kowainik/org/main/.stylish-haskell.yaml"
+    , "#       }"
+    , "#     , { path = " <> quote ".github/CODEOWNERS"
+    , "#       , raw  = " <> quote ("*  @" <> defaultOwner)
+    , "#       }"
+    , "#     , { path  = " <> quote "src/Foo.hs"
+    , "#       , local = " <> quote "/home/user/.default/Foo.hs"
+    , "#       }"
+    , "#     ]"
+    , ""
+    , "# Alternative Prelude to be used instead of the default one if you prefer"
+    , "# [prelude]"
+    , "#     package = " <> quote "relude"
+    , "#     module  = " <> quote "Relude"
+    ]
   where
     licenseName :: Text
     licenseName = show defaultLicenseName
 
-    defaultGhcVer :: Text
+    defaultGhcVer, defaultGhcPrev, defaultGhcPrevPrev :: Text
     defaultGhcVer = showGhcVer defaultGHC
+    defaultGhcPrev = showGhcVer $ prev defaultGHC
+    defaultGhcPrevPrev = showGhcVer $ prev $ prev defaultGHC
diff --git a/src/Summoner/GhcVer.hs b/src/Summoner/GhcVer.hs
--- a/src/Summoner/GhcVer.hs
+++ b/src/Summoner/GhcVer.hs
@@ -1,28 +1,28 @@
 {- |
-Copyright: (c) 2017-2019 Kowainik
-SPDX-License-Identifier: MPL-2.0
-Maintainer: Kowainik <xrom.xkov@gmail.com>
+Module                  : Summoner.GhcVer
+Copyright               : (c) 2017-2026 Kowainik
+SPDX-License-Identifier : MPL-2.0
+Maintainer              : Kowainik <xrom.xkov@gmail.com>
+Stability               : Stable
+Portability             : Portable
 
 Contains data type for GHC versions supported by Summoner
 and some useful functions for manipulation with them.
 -}
 
 module Summoner.GhcVer
-       ( GhcVer (..)
-       , GhcMeta (..)
-       , Pvp (..)
-       , showGhcVer
-       , parseGhcVer
-       , latestLts
-       , baseVer
-       , cabalBaseVersions
-       , ghcTable
-
-       , oldGhcs
-       ) where
+    ( GhcVer (..)
+    , GhcMeta (..)
+    , Pvp (..)
+    , showGhcVer
+    , parseGhcVer
+    , latestLts
+    , baseVer
+    , cabalBaseVersions
+    , ghcTable
 
-import Data.List (maximum, minimum)
-import Relude.Extra.Enum (inverseMap, universe)
+    , oldGhcs
+    ) where
 
 import qualified Data.Text as T
 import qualified Text.Show as Show
@@ -30,23 +30,37 @@
 
 -- | Represents some selected set of GHC versions.
 data GhcVer
-    = Ghc7103
-    | Ghc802
+    = Ghc802
     | Ghc822
     | Ghc844
     | Ghc865
-    | Ghc883
+    | Ghc884
+    | Ghc8107
+    | Ghc902
+    | Ghc928
+    | Ghc948
+    | Ghc967
+    | Ghc984
+    | Ghc9103
+    | Ghc9123
     deriving stock (Eq, Ord, Show, Enum, Bounded)
 
 -- | Converts 'GhcVer' into dot-separated string.
 showGhcVer :: GhcVer -> Text
 showGhcVer = \case
-    Ghc7103 -> "7.10.3"
     Ghc802  -> "8.0.2"
     Ghc822  -> "8.2.2"
     Ghc844  -> "8.4.4"
     Ghc865  -> "8.6.5"
-    Ghc883  -> "8.8.3"
+    Ghc884  -> "8.8.4"
+    Ghc8107 -> "8.10.7"
+    Ghc902  -> "9.0.2"
+    Ghc928  -> "9.2.8"
+    Ghc948  -> "9.4.8"
+    Ghc967  -> "9.6.7"
+    Ghc984  -> "9.8.4"
+    Ghc9103 -> "9.10.3"
+    Ghc9123 -> "9.12.3"
 
 {- | These are old GHC versions that are not working with default GHC versions
 when using Stack.
@@ -60,19 +74,26 @@
 -- | Returns latest known LTS resolver for all GHC versions except default one.
 latestLts :: GhcVer -> Text
 latestLts = \case
-    Ghc7103 -> "lts-6.35"
     Ghc802  -> "lts-9.21"
     Ghc822  -> "lts-11.22"
     Ghc844  -> "lts-12.26"
     Ghc865  -> "lts-14.27"
-    Ghc883  -> "lts-15.5"
+    Ghc884  -> "lts-16.31"
+    Ghc8107 -> "lts-18.28"
+    Ghc902  -> "lts-19.33"
+    Ghc928  -> "lts-20.26"
+    Ghc948  -> "lts-21.25"
+    Ghc967  -> "lts-22.44"
+    Ghc984  -> "lts-23.28"
+    Ghc9103 -> "lts-24.26"
+    Ghc9123 -> "nightly-2026-01-04"
 
 -- | Represents PVP versioning (4 numbers).
 data Pvp = Pvp
-    { pvpFirst  :: Int
-    , pvpSecond :: Int
-    , pvpThird  :: Int
-    , pvpFourth :: Int
+    { pvpFirst  :: !Int
+    , pvpSecond :: !Int
+    , pvpThird  :: !Int
+    , pvpFourth :: !Int
     }
 
 -- | Show PVP version in a standard way: @1.2.3.4@
@@ -82,12 +103,19 @@
 -- | Returns base version by 'GhcVer' as 'Pvp'.
 baseVerPvp :: GhcVer -> Pvp
 baseVerPvp = \case
-    Ghc7103 -> Pvp 4 8 0 2
     Ghc802  -> Pvp 4 9 1 0
     Ghc822  -> Pvp 4 10 1 0
     Ghc844  -> Pvp 4 11 1 0
     Ghc865  -> Pvp 4 12 0 0
-    Ghc883  -> Pvp 4 13 0 0
+    Ghc884  -> Pvp 4 13 0 0
+    Ghc8107 -> Pvp 4 14 3 0
+    Ghc902  -> Pvp 4 15 1 0
+    Ghc928  -> Pvp 4 16 4 0
+    Ghc948  -> Pvp 4 17 2 1
+    Ghc967  -> Pvp 4 18 3 1
+    Ghc984  -> Pvp 4 19 2 0
+    Ghc9103 -> Pvp 4 20 2 0
+    Ghc9123 -> Pvp 4 21 1 0
 
 -- | Returns corresponding @base@ version of the given GHC version.
 baseVer :: GhcVer -> Text
@@ -103,12 +131,13 @@
 
 -}
 cabalBaseVersions :: [GhcVer] -> Text
-cabalBaseVersions []   = ""
-cabalBaseVersions [v]  = "^>= " <> baseVer v
-cabalBaseVersions ghcs = ">= " <> baseVer (minimum ghcs) <> " && < " <> upperBound
+cabalBaseVersions ghcVers = case sort ghcVers of
+    []          -> ""
+    [v]         -> "^>= " <> baseVer v
+    minGhc:x:xs -> ">= " <> baseVer minGhc <> " && < " <> upperBound (x :| xs)
   where
-    upperBound :: Text
-    upperBound = let Pvp{..} = baseVerPvp $ maximum ghcs in
+    upperBound :: NonEmpty GhcVer -> Text
+    upperBound ghcs = let Pvp{..} = baseVerPvp $ last ghcs in
         show pvpFirst <> "." <> show (pvpSecond + 1)
 
 -- | Data type to keep meta information for every 'GhcVer'.
diff --git a/src/Summoner/Golden.hs b/src/Summoner/Golden.hs
new file mode 100644
--- /dev/null
+++ b/src/Summoner/Golden.hs
@@ -0,0 +1,270 @@
+{- |
+Module                  : Summoner.Golden
+Copyright               : (c) 2021-2026 Kowainik
+SPDX-License-Identifier : MPL-2.0
+Maintainer              : Kowainik <xrom.xkov@gmail.com>
+Stability               : Stable
+Portability             : Portable
+
+This module contains test data for golden examples.
+It is used for both purposes:
+
+  * To test new implementation against the old one
+  * In the @gg@ executable to generate new golden examples boilerplate
+-}
+
+module Summoner.Golden
+    ( -- * Executable scripts
+      generateScripts
+      -- * Default TOML config
+    , generateTomlConfig
+      -- * Projects
+      -- ** Generator
+    , generateProjects
+      -- ** Project settings
+    , cabalMinimal
+    , cabalFull
+    , stackFull
+    , fullBatteries
+    ) where
+
+import Colourista (infoMessage)
+import Colourista.Short (b)
+import System.Directory (withCurrentDirectory)
+
+import Summoner.CustomPrelude (CustomPrelude (..))
+import Summoner.Default (defaultConfigFileContent, defaultGHC)
+import Summoner.GhcVer (GhcVer (..))
+import Summoner.License (License (..), LicenseName (..))
+import Summoner.Settings (Settings (..), Tool (..))
+import Summoner.Template (createProjectTemplate)
+import Summoner.Template.Script (scriptFile)
+import Summoner.Text (quote)
+import Summoner.Tree (TreeFs (..), traverseTree)
+
+
+generateScripts :: IO ()
+generateScripts = do
+    generateCabalScript
+    generateStackScript
+
+generateCabalScript :: IO ()
+generateCabalScript = do
+    let path = "summoner-cli/examples/cabalScript.hs"
+    infoMessage $ "Writing Cabal script to: " <> toText path
+    writeFileText path $ scriptFile defaultGHC Cabal
+
+generateStackScript :: IO ()
+generateStackScript = do
+    let path = "summoner-cli/examples/stackScript.hs"
+    infoMessage $ "Writing Stack script to: " <> toText path
+    writeFileText path $ scriptFile defaultGHC Stack
+
+generateTomlConfig :: IO ()
+generateTomlConfig = do
+    let path = "summoner-cli/examples/summoner-default.toml"
+    infoMessage $ "Writing default TOML config to: " <> toText path
+    writeFileText path defaultConfigFileContent
+
+----------------------------------------------------------------------------
+-- Entire projects
+----------------------------------------------------------------------------
+
+generateProjects :: IO ()
+generateProjects = withCurrentDirectory "summoner-cli/examples" $ do
+    mkProject cabalMinimal
+    mkProject cabalFull
+    mkProject stackFull
+    mkProject fullBatteries
+
+mkProject :: Settings -> IO ()
+mkProject settings = do
+    infoMessage $ "Creating project: " <> b (settingsRepo settings)
+    traverseTree $ createProjectTemplate settings
+
+cabalMinimal :: Settings
+cabalMinimal = Settings
+    { settingsRepo           = "cabal-minimal"
+    , settingsOwner          = "kowainik"
+    , settingsDescription    = "Minimal cabal-only test project"
+    , settingsFullName       = "Kowainik"
+    , settingsEmail          = "xrom.xkov@gmail.com"
+    , settingsYear           = "2022"
+    , settingsCategories     = ""
+    , settingsLicenseName    = NONE
+    , settingsLicenseText    = ""
+    , settingsGitHub         = False
+    , settingsGhActions      = False
+    , settingsPrivate        = False
+    , settingsTravis         = False
+    , settingsAppVeyor       = False
+    , settingsIsLib          = False
+    , settingsIsExe          = True
+    , settingsTest           = False
+    , settingsBench          = False
+    , settingsTestedVersions = [defaultGHC]
+    , settingsPrelude        = Nothing
+    , settingsExtensions     = []
+    , settingsGhcOptions     = []
+    , settingsGitignore      = []
+    , settingsCabal          = True
+    , settingsStack          = False
+    , settingsNoUpload       = True
+    , settingsFiles          = mempty
+    }
+
+cabalFull :: Settings
+cabalFull = Settings
+    { settingsRepo           = "cabal-full"
+    , settingsOwner          = "kowainik"
+    , settingsDescription    = "Cabal-only example with all integrations"
+    , settingsFullName       = "Kowainik"
+    , settingsEmail          = "xrom.xkov@gmail.com"
+    , settingsYear           = "2022"
+    , settingsCategories     = "Testing"
+    , settingsLicenseName    = BSD3
+    , settingsLicenseText    = bsd3License
+    , settingsGitHub         = True
+    , settingsGhActions      = True
+    , settingsPrivate        = False
+    , settingsTravis         = True
+    , settingsAppVeyor       = True
+    , settingsIsLib          = True
+    , settingsIsExe          = True
+    , settingsTest           = True
+    , settingsBench          = True
+    , settingsTestedVersions = [Ghc844 .. defaultGHC]
+    , settingsPrelude        = Just $ CustomPrelude "relude" "Relude"
+    , settingsExtensions     = ["DeriveGeneric", "TypeApplications"]
+    , settingsGitignore      = []
+    , settingsGhcOptions     = []
+    , settingsCabal          = True
+    , settingsStack          = False
+    , settingsNoUpload       = False
+    , settingsFiles          = []
+    }
+
+stackFull :: Settings
+stackFull = Settings
+    { settingsRepo           = "stack-full"
+    , settingsOwner          = "kowainik"
+    , settingsDescription    = "Stack-only example with all integrations"
+    , settingsFullName       = "Kowainik"
+    , settingsEmail          = "xrom.xkov@gmail.com"
+    , settingsYear           = "2022"
+    , settingsCategories     = "Testing"
+    , settingsLicenseName    = BSD3
+    , settingsLicenseText    = bsd3License
+    , settingsGitHub         = True
+    , settingsGhActions      = True
+    , settingsPrivate        = False
+    , settingsTravis         = True
+    , settingsAppVeyor       = True
+    , settingsIsLib          = True
+    , settingsIsExe          = True
+    , settingsTest           = True
+    , settingsBench          = True
+    , settingsTestedVersions = [Ghc844 .. defaultGHC]
+    , settingsPrelude        = Just $ CustomPrelude "relude" "Relude"
+    , settingsExtensions     = ["DeriveGeneric", "TypeApplications"]
+    , settingsGitignore      = []
+    , settingsGhcOptions     = []
+    , settingsCabal          = False
+    , settingsStack          = True
+    , settingsNoUpload       = False
+    , settingsFiles          = []
+    }
+
+fullBatteries :: Settings
+fullBatteries = Settings
+    { settingsRepo           = "full-batteries"
+    , settingsOwner          = "kowainik"
+    , settingsDescription    = "Full-featured test project"
+    , settingsFullName       = "Kowainik"
+    , settingsEmail          = "xrom.xkov@gmail.com"
+    , settingsYear           = "2022"
+    , settingsCategories     = "Testing"
+    , settingsLicenseName    = MIT
+    , settingsLicenseText    = mitLicense
+    , settingsGitHub         = True
+    , settingsGhActions      = True
+    , settingsPrivate        = True
+    , settingsTravis         = True
+    , settingsAppVeyor       = True
+    , settingsIsLib          = True
+    , settingsIsExe          = True
+    , settingsTest           = True
+    , settingsBench          = True
+    , settingsTestedVersions = [minBound .. defaultGHC]
+    , settingsPrelude        = Just $ CustomPrelude "relude" "Relude"
+    , settingsExtensions     = ["ConstraintKinds", "LambdaCase", "OverloadedStrings"]
+    , settingsGitignore      = [".secret"]
+    , settingsGhcOptions     = ["-Wcompat", "-Widentities"]
+    , settingsCabal          = True
+    , settingsStack          = True
+    , settingsNoUpload       = True
+    , settingsFiles          =
+        [ File "extra.txt" "See full content of the file [here](@github)\n"
+        , Dir ".github" [File "CODEOWNERS" "*  @vrom911\n"]
+        , File ".stylish-haskell.yaml" "This is stylish-haskell.yaml\n"
+        , File "CONTRIBUTING.md" "This is contributing guide\n"
+        ]
+    }
+  where
+    mitLicense :: License
+    mitLicense = License  $ unlines
+        [ "MIT License"
+        , ""
+        , "Copyright (c) 2022 Kowainik"
+        , ""
+        , "Permission is hereby granted, free of charge, to any person obtaining a copy"
+        , "of this software and associated documentation files (the " <> quote "Software" <> "), to deal"
+        , "in the Software without restriction, including without limitation the rights"
+        , "to use, copy, modify, merge, publish, distribute, sublicense, and/or sell"
+        , "copies of the Software, and to permit persons to whom the Software is"
+        , "furnished to do so, subject to the following conditions:"
+        , ""
+        , "The above copyright notice and this permission notice shall be included in all"
+        , "copies or substantial portions of the Software."
+        , ""
+        , "THE SOFTWARE IS PROVIDED " <> quote "AS IS" <> ", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR"
+        , "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,"
+        , "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE"
+        , "AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER"
+        , "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,"
+        , "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE"
+        , "SOFTWARE."
+        ]
+
+bsd3License :: License
+bsd3License = License $ unlines
+    [ "BSD 3-Clause License"
+    , ""
+    , "Copyright (c) 2022, Kowainik"
+    , "All rights reserved."
+    , ""
+    , "Redistribution and use in source and binary forms, with or without"
+    , "modification, are permitted provided that the following conditions are met:"
+    , ""
+    , "1. Redistributions of source code must retain the above copyright notice, this"
+    , "   list of conditions and the following disclaimer."
+    , ""
+    , "2. Redistributions in binary form must reproduce the above copyright notice,"
+    , "   this list of conditions and the following disclaimer in the documentation"
+    , "   and/or other materials provided with the distribution."
+    , ""
+    , "3. Neither the name of the copyright holder nor the names of its"
+    , "   contributors may be used to endorse or promote products derived from"
+    , "   this software without specific prior written permission."
+    , ""
+    , "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS " <> quote "AS IS"
+    , "AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"
+    , "IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE"
+    , "DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE"
+    , "FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"
+    , "DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR"
+    , "SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER"
+    , "CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,"
+    , "OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE"
+    , "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+    ]
diff --git a/src/Summoner/License.hs b/src/Summoner/License.hs
--- a/src/Summoner/License.hs
+++ b/src/Summoner/License.hs
@@ -1,27 +1,29 @@
 {- |
-Copyright: (c) 2017-2020 Kowainik
-SPDX-License-Identifier: MPL-2.0
-Maintainer: Kowainik <xrom.xkov@gmail.com>
+Module                  : Summoner.License
+Copyright               : (c) 2017-2026 Kowainik
+SPDX-License-Identifier : MPL-2.0
+Maintainer              : Kowainik <xrom.xkov@gmail.com>
+Stability               : Stable
+Portability             : Portable
 
 Data types that represent license names and license content and functions
 to work with them.
 -}
 
 module Summoner.License
-       ( LicenseName(..)
-       , License(..)
-       , customizeLicense
-       , githubLicenseQueryNames
-       , parseLicenseName
-       , fetchLicense
-       , fetchLicenseCustom
-       , licenseShortDesc
-       , showLicenseWithDesc
-       ) where
+    ( LicenseName (..)
+    , License (..)
+    , customizeLicense
+    , githubLicenseQueryNames
+    , parseLicenseName
+    , fetchLicense
+    , fetchLicenseCustom
+    , licenseShortDesc
+    , showLicenseWithDesc
+    ) where
 
 import Colourista (errorMessage)
-import Data.Aeson (FromJSON (..), decodeStrict, withObject, (.:))
-import Relude.Extra.Enum (inverseMap)
+import Data.Aeson.Micro (FromJSON (..), decodeStrict, withObject, (.:))
 import Shellmet (($|))
 
 import qualified Data.Text as T
diff --git a/src/Summoner/Mode.hs b/src/Summoner/Mode.hs
--- a/src/Summoner/Mode.hs
+++ b/src/Summoner/Mode.hs
@@ -1,7 +1,10 @@
 {- |
-Copyright: (c) 2020 Kowainik
-SPDX-License-Identifier: MPL-2.0
-Maintainer: Kowainik <xrom.xkov@gmail.com>
+Module                  : Summoner.Mode
+Copyright               : (c) 2020-2026 Kowainik
+SPDX-License-Identifier : MPL-2.0
+Maintainer              : Kowainik <xrom.xkov@gmail.com>
+Stability               : Stable
+Portability             : Portable
 
 This module introduces different modes in which the command-line interface
 could be.
diff --git a/src/Summoner/Project.hs b/src/Summoner/Project.hs
--- a/src/Summoner/Project.hs
+++ b/src/Summoner/Project.hs
@@ -1,15 +1,16 @@
-{-# LANGUAGE QuasiQuotes #-}
-
-{- HLINT ignore "Reduce duplication" -}
-
 {- |
-Copyright: (c) 2017-2019 Kowainik
-SPDX-License-Identifier: MPL-2.0
-Maintainer: Kowainik <xrom.xkov@gmail.com>
+Module                  : Summoner.Project
+Copyright               : (c) 2017-2026 Kowainik
+SPDX-License-Identifier : MPL-2.0
+Maintainer              : Kowainik <xrom.xkov@gmail.com>
+Stability               : Stable
+Portability             : Portable
 
 This module introduces functions for the project creation.
 -}
 
+{- HLINT ignore "Reduce duplication" -}
+
 module Summoner.Project
        ( generateProject
        , generateProjectInteractive
@@ -20,8 +21,6 @@
 import Colourista (bold, errorMessage, formattedMessage, green, infoMessage, skipMessage,
                    successMessage, warningMessage)
 import Data.List.NonEmpty ((<|))
-import NeatInterpolation (text)
-import Relude.Extra.Enum (universe, universeNonEmpty)
 import Shellmet (($?))
 import System.Directory (findExecutable, setCurrentDirectory)
 
@@ -98,7 +97,7 @@
         (settingsGitHub && not settingsNoUpload)
         (YesNoPrompt "private repository" "Create as a private repository (Requires a GitHub private repo plan)?")
         cPrivate
-    settingsGhActions <- decisionIf (settingsCabal && settingsGitHub) (mkDefaultYesNoPrompt "GitHub Actions CI integration") cGhActions
+    settingsGhActions <- decisionIf settingsGitHub (mkDefaultYesNoPrompt "GitHub Actions CI integration") cGhActions
     settingsTravis    <- decisionIf settingsGitHub (mkDefaultYesNoPrompt "Travis CI integration") cTravis
     settingsAppVeyor  <- decisionIf settingsGitHub (mkDefaultYesNoPrompt "AppVeyor CI integration") cAppVey
     settingsIsLib     <- promptDecisionToBool cLib (mkDefaultYesNoPrompt "library target")
@@ -137,24 +136,23 @@
         else falseMessage (yesNoTarget ynPrompt)
 
     categoryText :: Text
-    categoryText =
-        [text|
-        List of categories to choose from:
-
-          * Control                    * Concurrency
-          * Codec                      * Graphics
-          * Data                       * Sound
-          * Math                       * System
-          * Parsing                    * Network
-          * Text
-
-          * Application                * Development
-          * Compilers/Interpreters     * Testing
-          * Web
-          * Game
-          * Utility
-
-        |]
+    categoryText = unlines
+        [ "List of categories to choose from:"
+        , ""
+        , "  * Control                    * Concurrency"
+        , "  * Codec                      * Graphics"
+        , "  * Data                       * Sound"
+        , "  * Math                       * System"
+        , "  * Parsing                    * Network"
+        , "  * Text"
+        , ""
+        , "  * Application                * Development"
+        , "  * Compilers/Interpreters     * Testing"
+        , "  * Web"
+        , "  * Game"
+        , "  * Utility"
+        , ""
+        ]
 
     licenseText :: Text
     licenseText = "List of licenses to choose from:\n\n"
@@ -287,7 +285,7 @@
 doGithubCommands :: Settings -> IO ()
 doGithubCommands Settings{..} = do
     -- Create git repostitory and do a commit.
-    "git" ["init"]
+    "git" ["init", "--initial-branch=main"]
     "git" ["add", "."]
     "git" ["commit", "-m", "Create the project"]
     unless settingsNoUpload $ do
@@ -297,7 +295,11 @@
             Just _ -> do
                 isHubSuccess <- runHub repo
                 if isHubSuccess
-                then "git" ["push", "-u", "origin", "master"]
+                then do
+                    "git" ["push", "-u", "origin", "main"]
+                    "git" ["remote", "set-head", "origin", "-a"]
+                    successMessage "Project created:"
+                    infoMessage $ "    https://github.com/" <> repo
                 else do
                     warningMessage "Error running 'hub'. Possible reason: incorrect password."
                     hubHelp repo
diff --git a/src/Summoner/Question.hs b/src/Summoner/Question.hs
--- a/src/Summoner/Question.hs
+++ b/src/Summoner/Question.hs
@@ -3,9 +3,12 @@
 {-# LANGUAGE ViewPatterns #-}
 
 {- |
-Copyright: (c) 2017-2019 Kowainik
-SPDX-License-Identifier: MPL-2.0
-Maintainer: Kowainik <xrom.xkov@gmail.com>
+Module                  : Summoner.Question
+Copyright               : (c) 2017-2026 Kowainik
+SPDX-License-Identifier : MPL-2.0
+Maintainer              : Kowainik <xrom.xkov@gmail.com>
+Stability               : Stable
+Portability             : Portable
 
 This module contains function to proper questioning in terminal.
 -}
@@ -40,7 +43,6 @@
                    warningMessage)
 import System.Directory (doesPathExist, getCurrentDirectory)
 import System.FilePath ((</>))
-import System.IO (hFlush)
 
 import Summoner.Text (headToUpper, intercalateMap)
 
diff --git a/src/Summoner/Settings.hs b/src/Summoner/Settings.hs
--- a/src/Summoner/Settings.hs
+++ b/src/Summoner/Settings.hs
@@ -1,7 +1,10 @@
 {- |
-Copyright: (c) 2017-2019 Kowainik
-SPDX-License-Identifier: MPL-2.0
-Maintainer: Kowainik <xrom.xkov@gmail.com>
+Module                  : Summoner.Settings
+Copyright               : (c) 2017-2026 Kowainik
+SPDX-License-Identifier : MPL-2.0
+Maintainer              : Kowainik <xrom.xkov@gmail.com>
+Stability               : Stable
+Portability             : Portable
 
 Complete settings required for the project creation.
 -}
@@ -13,8 +16,6 @@
        , showTool
        , parseTool
        ) where
-
-import Relude.Extra.Enum (inverseMap)
 
 import Summoner.CustomPrelude (CustomPrelude)
 import Summoner.GhcVer (GhcVer)
diff --git a/src/Summoner/Source.hs b/src/Summoner/Source.hs
--- a/src/Summoner/Source.hs
+++ b/src/Summoner/Source.hs
@@ -1,7 +1,10 @@
 {- |
-Copyright: (c) 2017-2019 Kowainik
-SPDX-License-Identifier: MPL-2.0
-Maintainer: Kowainik <xrom.xkov@gmail.com>
+Module                  : Summoner.Source
+Copyright               : (c) 2017-2026 Kowainik
+SPDX-License-Identifier : MPL-2.0
+Maintainer              : Kowainik <xrom.xkov@gmail.com>
+Stability               : Stable
+Portability             : Portable
 
 This module contains the 'Source' data that describes how to fetch custom files.
 -}
@@ -89,7 +92,7 @@
 -}
 fetchSource :: ConnectMode -> Source -> IO (Maybe Text)
 fetchSource connectMode = \case
-    Local path -> catch (Just <$> readFileText path) (localError path)
+    Local path -> catch (Just . decodeUtf8 <$> readFileBS path) (localError path)
     Url url -> if isOffline connectMode
         then Nothing <$ infoMessage ("Ignoring fetching from URL in offline mode from source: " <> url)
         else fetchUrl url `catch` urlError url
diff --git a/src/Summoner/Template.hs b/src/Summoner/Template.hs
--- a/src/Summoner/Template.hs
+++ b/src/Summoner/Template.hs
@@ -1,7 +1,10 @@
 {- |
-Copyright: (c) 2017-2019 Kowainik
-SPDX-License-Identifier: MPL-2.0
-Maintainer: Kowainik <xrom.xkov@gmail.com>
+Module                  : Summoner.Template
+Copyright               : (c) 2017-2026 Kowainik
+SPDX-License-Identifier : MPL-2.0
+Maintainer              : Kowainik <xrom.xkov@gmail.com>
+Stability               : Stable
+Portability             : Portable
 
 This module contains functions for the Haskell project template creation.
 -}
diff --git a/src/Summoner/Template/Cabal.hs b/src/Summoner/Template/Cabal.hs
--- a/src/Summoner/Template/Cabal.hs
+++ b/src/Summoner/Template/Cabal.hs
@@ -1,9 +1,10 @@
-{-# LANGUAGE QuasiQuotes #-}
-
 {- |
-Copyright: (c) 2017-2019 Kowainik
-SPDX-License-Identifier: MPL-2.0
-Maintainer: Kowainik <xrom.xkov@gmail.com>
+Module                  : Summoner.Template.Cabal
+Copyright               : (c) 2017-2026 Kowainik
+SPDX-License-Identifier : MPL-2.0
+Maintainer              : Kowainik <xrom.xkov@gmail.com>
+Stability               : Stable
+Portability             : Portable
 
 @.cabal@ file template.
 -}
@@ -12,14 +13,14 @@
        ( cabalFile
        ) where
 
-import NeatInterpolation (text)
+import Colourista (indent)
 
 import Summoner.CustomPrelude (CustomPrelude (..))
-import Summoner.Default (defaultCabal)
+import Summoner.Default (defaultCabalVersion)
 import Summoner.GhcVer (cabalBaseVersions, showGhcVer)
 import Summoner.License (LicenseName (..))
 import Summoner.Settings (Settings (..))
-import Summoner.Text (endLine, intercalateMap, packageToModule)
+import Summoner.Text (intercalateMap, packageToModule)
 import Summoner.Tree (TreeFs (..))
 
 import qualified Data.Text as T
@@ -37,17 +38,17 @@
         , memptyIfFalse settingsIsLib libraryStanza
         , memptyIfFalse settingsIsExe executableStanza
         , memptyIfFalse settingsTest  testSuiteStanza
-        , memptyIfFalse settingsBench $ benchmarkStanza $ memptyIfFalse settingsIsLib $ ", " <> settingsRepo
+        , memptyIfFalse settingsBench benchmarkStanza
         ]
 
-    -- TODO: do something to not have empty lines
     cabalHeader :: Text
     cabalHeader = unlines $
-        [ "cabal-version:       " <> defaultCabal
+        [ "cabal-version:       " <> defaultCabalVersion
         , "name:                " <> settingsRepo
         , "version:             0.0.0.0"
         , "synopsis:            " <> settingsDescription
-        , "description:         " <> settingsDescription ] ++
+        , "description:"
+        ] <> fullDescription <>
         [ "homepage:            " <> githubUrl        | settingsGitHub ] ++
         [ "bug-reports:         " <> githubBugReports | settingsGitHub ] ++
         ( "license:             " <> licenseName) :
@@ -62,6 +63,23 @@
         , "tested-with:         " <> testedGhcs
         ]
 
+    fullDescription :: [Text]
+    fullDescription =
+        [ "    " <> addDot settingsDescription
+        , "    See " <> readme <> " for more details."
+        ]
+      where
+        readme :: Text
+        readme = if settingsGitHub
+           then "[README.md](" <> githubUrl <> "#" <> settingsRepo <> ")"
+           else "README.md"
+
+        addDot :: Text -> Text
+        addDot "" = ""
+        addDot txt = case T.last txt of
+            '.'        -> txt
+            _otherChar -> txt <> "."
+
     githubUrl, githubBugReports :: Text
     githubUrl        = "https://github.com/" <> settingsOwner <> "/" <> settingsRepo
     githubBugReports = githubUrl <> "/issues"
@@ -77,136 +95,145 @@
         settingsTestedVersions
 
     sourceRepository :: Text
-    sourceRepository =
-        [text|
-        $endLine
-        source-repository head
-          type:                git
-          location:            ${githubUrl}.git
-        |]
+    sourceRepository = unlines
+        [ ""
+        , "source-repository head"
+        , "  type:                git"
+        , "  location:            " <> githubUrl <> ".git"
+        ]
 
     commonStanza :: Text
-    commonStanza =
-        [text|
-        $endLine
-        common common-options
-          build-depends:       base $baseBounds
-          $customPrelude
-          $ghcOptions
-
-          default-language:    Haskell2010
-    |] <> defaultExtensions
+    commonStanza = unlines $
+        [ ""
+        , "common common-options"
+        , "  build-depends:       base " <> baseBounds
+        ]
+        <> customPrelude
+        <> ghcOptions
+        <>
+        ( ""
+        : "  default-language:    Haskell2010"
+        : defaultExtensions
+        )
 
     baseBounds :: Text
     baseBounds = cabalBaseVersions settingsTestedVersions
 
-    ghcOptions :: Text
-    ghcOptions = case settingsGhcOptions of
-        [] -> defaultGhcOptions
-        x:xs ->
-            let customGhcOptions = T.intercalate "\n" $ x : map (T.replicate 21 " " <>) xs in
-            [text|
-            ghc-options:         $customGhcOptions
-            |]
+    ghcOptions :: [Text]
+    ghcOptions = "" : case settingsGhcOptions of
+        []   -> defaultGhcOptions
+        x:xs -> "  ghc-options:         " <> x : map (indent 23 <>) xs
 
-    defaultGhcOptions :: Text
+    defaultGhcOptions :: [Text]
     defaultGhcOptions =
-        [text|
-        ghc-options:         -Wall
-                             -Wcompat
-                             -Widentities
-                             -Wincomplete-uni-patterns
-                             -Wincomplete-record-updates
-        if impl(ghc >= 8.0)
-          ghc-options:       -Wredundant-constraints
-        if impl(ghc >= 8.2)
-          ghc-options:       -fhide-source-paths
-        if impl(ghc >= 8.4)
-          ghc-options:       -Wmissing-export-lists
-                             -Wpartial-fields
-        if impl(ghc >= 8.8)
-          ghc-options:       -Wmissing-deriving-strategies
-        |]
+        [ "  ghc-options:         -Wall"
+        , "                       -Wcompat"
+        , "                       -Widentities"
+        , "                       -Wincomplete-uni-patterns"
+        , "                       -Wincomplete-record-updates"
+        , "                       -Wredundant-constraints"
+        , "                       -Wnoncanonical-monad-instances"
+        , "  if impl(ghc >= 8.2)"
+        , "    ghc-options:       -fhide-source-paths"
+        , "  if impl(ghc >= 8.4)"
+        , "    ghc-options:       -Wmissing-export-lists"
+        , "                       -Wpartial-fields"
+        , "  if impl(ghc >= 8.8)"
+        , "    ghc-options:       -Wmissing-deriving-strategies"
+        , "                       -fwrite-ide-info"
+        , "                       -hiedir=.hie"
+        , "  if impl(ghc >= 8.10)"
+        , "    ghc-options:       -Wunused-packages"
+        , "  if impl(ghc >= 9.0)"
+        , "    ghc-options:       -Winvalid-haddock"
+        , "  if impl(ghc >= 9.2)"
+        , "    ghc-options:       -Wredundant-bang-patterns"
+        , "                       -Woperator-whitespace"
+        , "  if impl(ghc >= 9.4  && < 9.10)"
+        , "    ghc-options:       -Wforall-identifier"
+        , "  if impl(ghc >= 9.4)"
+        , "    ghc-options:       -Wredundant-strictness-flags"
+        , "  if impl(ghc >= 9.8)"
+        , "    ghc-options:       -Wterm-variable-capture"
+        , "                       -Winconsistent-flags"
+        , "  if impl(ghc >= 9.10)"
+        , "    ghc-options:       -Wincomplete-record-selectors"
+        , "                       -Wdeprecated-type-abstractions"
+        , "                       -Wdata-kinds-tc"
+        , "                       -Wdefaulted-exception-context"
+        , "  if impl(ghc >= 9.12)"
+        , "    ghc-options:       -Wview-pattern-signatures"
+        ]
 
     libraryStanza :: Text
-    libraryStanza =
-        [text|
-        $endLine
-        library
-          import:              common-options
-          hs-source-dirs:      src
-          exposed-modules:     $libModuleName
-        |]
+    libraryStanza = unlines
+        [ ""
+        , "library"
+        , "  import:              common-options"
+        , "  hs-source-dirs:      src"
+        , "  exposed-modules:     " <> libModuleName
+        ]
 
     executableStanza :: Text
-    executableStanza =
-        [text|
-        $endLine
-        executable $settingsRepo
-          import:              common-options
-          hs-source-dirs:      app
-          main-is:             Main.hs
-          $buildDepends
-          $rtsOptions
-        |]
+    executableStanza = unlines $
+        [ ""
+        , "executable " <> settingsRepo
+        , "  import:              common-options"
+        , "  hs-source-dirs:      app"
+        , "  main-is:             Main.hs"
+        ]
+        <> buildDepends
+        <> rtsOptions
 
     testSuiteStanza :: Text
-    testSuiteStanza =
-        [text|
-        $endLine
-        test-suite ${settingsRepo}-test
-          import:              common-options
-          type:                exitcode-stdio-1.0
-          hs-source-dirs:      test
-          main-is:             Spec.hs
-          $buildDepends
-          $rtsOptions
-        |]
+    testSuiteStanza = unlines $
+        [ ""
+        , "test-suite " <> settingsRepo <> "-test"
+        , "  import:              common-options"
+        , "  type:                exitcode-stdio-1.0"
+        , "  hs-source-dirs:      test"
+        , "  main-is:             Spec.hs"
+        ]
+        <> buildDepends
+        <> rtsOptions
 
-    benchmarkStanza :: Text -> Text
-    benchmarkStanza commaRepo =
-        [text|
-        $endLine
-        benchmark ${settingsRepo}-benchmark
-          import:              common-options
-          type:                exitcode-stdio-1.0
-          hs-source-dirs:      benchmark
-          main-is:             Main.hs
-          build-depends:       gauge
-                             $commaRepo
-          $rtsOptions
-          |]
+    benchmarkStanza :: Text
+    benchmarkStanza = unlines $
+        [ ""
+        , "benchmark " <> settingsRepo <> "-benchmark"
+        , "  import:              common-options"
+        , "  type:                exitcode-stdio-1.0"
+        , "  hs-source-dirs:      benchmark"
+        , "  main-is:             Main.hs"
+        ]
+        <> buildDepends
+        <> rtsOptions
 
     -- | @build-depends@ for the repo, only if the library is on.
-    buildDepends :: Text
-    buildDepends =
-        if settingsIsLib
-        then "build-depends:       " <> settingsRepo
-        else ""
+    buildDepends :: [Text]
+    buildDepends = memptyIfFalse settingsIsLib
+        ["  build-depends:       " <> settingsRepo]
 
-    rtsOptions :: Text
+    rtsOptions :: [Text]
     rtsOptions =
-        [text|
-        ghc-options:         -threaded
-                             -rtsopts
-                             -with-rtsopts=-N
-        |]
+        [ "  ghc-options:         -threaded"
+        , "                       -rtsopts"
+        , "                       -with-rtsopts=-N"
+        ]
 
-    customPrelude :: Text
+    customPrelude :: [Text]
     customPrelude = case settingsPrelude of
-        Nothing -> ""
+        Nothing -> []
         Just CustomPrelude{..} ->
-            "                   , " <> cpPackage <> "\n" <>
-            [text|
-            $endLine
-            mixins:              base hiding (Prelude)
-                               , $cpPackage ($cpModule as Prelude)
-            $endLine
-            |]
+            [ "                     , " <> cpPackage
+            , ""
+            , "  mixins:              base hiding (Prelude)"
+            , "                     , " <> cpPackage <> " (" <> cpModule <> " as Prelude)"
+            ]
 
-    defaultExtensions :: Text
+    defaultExtensions :: [Text]
     defaultExtensions = case settingsExtensions of
-        [] -> ""
-        xs -> "  default-extensions:  "
-           <> T.intercalate "\n                       " xs
-           <> "\n"
+        [] -> []
+        x:xs ->
+             "  default-extensions:  " <> x
+           : map (indent 23 <>) xs
diff --git a/src/Summoner/Template/Doc.hs b/src/Summoner/Template/Doc.hs
--- a/src/Summoner/Template/Doc.hs
+++ b/src/Summoner/Template/Doc.hs
@@ -1,7 +1,10 @@
 {- |
-Copyright: (c) 2017-2019 Kowainik
-SPDX-License-Identifier: MPL-2.0
-Maintainer: Kowainik <xrom.xkov@gmail.com>
+Module                  : Summoner.Template.Doc
+Copyright               : (c) 2017-2026 Kowainik
+SPDX-License-Identifier : MPL-2.0
+Maintainer              : Kowainik <xrom.xkov@gmail.com>
+Stability               : Stable
+Portability             : Portable
 
 Templates for various documentation files:
 
@@ -79,12 +82,12 @@
 
         travisShield, travisLink, travisBadge :: Text
         travisShield = shieldsIo <> "travis/" <> ownerRepo <> ".svg?logo=travis"
-        travisLink   = "https://travis-ci.org/" <> ownerRepo
+        travisLink   = "https://travis-ci.com/" <> ownerRepo
         travisBadge  = makeBadge "Build status" travisShield travisLink
 
         appVeyorCom, appVeyorShield, appVeyorLink, appVeyorBadge :: Text
         appVeyorCom    = "https://ci.appveyor.com/"
-        appVeyorShield = appVeyorCom <> "api/projects/status/github/" <> ownerRepo <> "?branch=master&svg=true"
+        appVeyorShield = appVeyorCom <> "api/projects/status/github/" <> ownerRepo <> "?branch=main&svg=true"
         appVeyorLink   = appVeyorCom <> "project/" <> ownerRepo
         appVeyorBadge  = makeBadge "Windows build status" appVeyorShield appVeyorLink
 
diff --git a/src/Summoner/Template/GitHub.hs b/src/Summoner/Template/GitHub.hs
--- a/src/Summoner/Template/GitHub.hs
+++ b/src/Summoner/Template/GitHub.hs
@@ -1,10 +1,12 @@
-{-# LANGUAGE QuasiQuotes  #-}
 {-# LANGUAGE ViewPatterns #-}
 
-{-|
-Copyright: (c) 2017-2019 Kowainik
-SPDX-License-Identifier: MPL-2.0
-Maintainer: Kowainik <xrom.xkov@gmail.com>
+{- |
+Module                  : Summoner.Template.GitHub
+Copyright               : (c) 2017-2026 Kowainik
+SPDX-License-Identifier : MPL-2.0
+Maintainer              : Kowainik <xrom.xkov@gmail.com>
+Stability               : Stable
+Portability             : Portable
 
 This module contains template for GitHub related docs:
 
@@ -21,86 +23,92 @@
 -}
 
 module Summoner.Template.GitHub
-       ( gitHubFiles
-       ) where
+    ( gitHubFiles
+    ) where
 
+import Colourista (indent)
 import Data.List (delete, intersect)
-import NeatInterpolation (text)
 
-import Summoner.Default (defaultCabal, defaultGHC)
+import Summoner.Default (defaultCabal, defaultGHC, defaultStack, ghcActionsCacheVersion,
+                         ghcActionsCheckoutVersion, ghcActionsSetupHaskellVersion)
 import Summoner.GhcVer (GhcVer (..), oldGhcs, showGhcVer)
 import Summoner.Settings (Settings (..))
-import Summoner.Text (endLine, intercalateMap, tconcatMap)
+import Summoner.Text (quote)
 import Summoner.Tree (TreeFs (..))
 
 
 gitHubFiles :: Settings -> [TreeFs]
 gitHubFiles Settings{..} = concat
     [ [File ".gitignore" (gitignoreDefault <> gitignoreCustom) | settingsGitHub]
-    , [Dir ".github" [ Dir "workflows" [ File "ci.yml" ghActionsYml ]] | settingsGhActions ]
+    , [ Dir ".github"
+          [ Dir "workflows" [ File "ci.yml" ghActionsYml ]
+          , File "dependabot.yml" dependabotYml
+          ]
+      | settingsGhActions
+      ]
     , [File ".travis.yml" travisYml    | settingsTravis]
     , [File "appveyor.yml" appVeyorYml | settingsAppVeyor]
     ]
   where
     -- default .gitignore template
     gitignoreDefault :: Text
-    gitignoreDefault =
-        [text|
-        ### Haskell
-        dist
-        dist-*
-        cabal-dev
-        *.o
-        *.hi
-        *.chi
-        *.chs.h
-        *.dyn_o
-        *.dyn_hi
-        *.prof
-        *.aux
-        *.hp
-        *.eventlog
-        .virtualenv
-        .hsenv
-        .hpc
-        .cabal-sandbox/
-        cabal.sandbox.config
-        cabal.config
-        cabal.project.local
-        .ghc.environment.*
-        .HTF/
-        # Stack
-        .stack-work/
-        stack.yaml.lock
-
-        ### IDE/support
-        # Vim
-        [._]*.s[a-v][a-z]
-        [._]*.sw[a-p]
-        [._]s[a-v][a-z]
-        [._]sw[a-p]
-        *~
-        tags
-
-        # IntellijIDEA
-        .idea/
-        .ideaHaskellLib/
-        *.iml
-
-        # Atom
-        .haskell-ghc-mod.json
-
-        # VS
-        .vscode/
-
-        # Emacs
-        *#
-        .dir-locals.el
-        TAGS
-
-        # other
-        .DS_Store
-        |]
+    gitignoreDefault = unlines
+        [ "### Haskell"
+        , "dist"
+        , "dist-*"
+        , "cabal-dev"
+        , "*.o"
+        , "*.hi"
+        , "*.chi"
+        , "*.chs.h"
+        , "*.dyn_o"
+        , "*.dyn_hi"
+        , "*.prof"
+        , "*.aux"
+        , "*.hp"
+        , "*.eventlog"
+        , ".virtualenv"
+        , ".hsenv"
+        , ".hpc"
+        , ".cabal-sandbox/"
+        , "cabal.sandbox.config"
+        , "cabal.config"
+        , "cabal.project.local"
+        , ".ghc.environment.*"
+        , ".HTF/"
+        , ".hie/"
+        , "# Stack"
+        , ".stack-work/"
+        , "stack.yaml.lock"
+        , ""
+        , "### IDE/support"
+        , "# Vim"
+        , "[._]*.s[a-v][a-z]"
+        , "[._]*.sw[a-p]"
+        , "[._]s[a-v][a-z]"
+        , "[._]sw[a-p]"
+        , "*~"
+        , "tags"
+        , ""
+        , "# IntellijIDEA"
+        , ".idea/"
+        , ".ideaHaskellLib/"
+        , "*.iml"
+        , ""
+        , "# Atom"
+        , ".haskell-ghc-mod.json"
+        , ""
+        , "# VS"
+        , ".vscode/"
+        , ""
+        , "# Emacs"
+        , "*#"
+        , ".dir-locals.el"
+        , "TAGS"
+        , ""
+        , "# other"
+        , ".DS_Store"
+        ]
 
     -- additional .gitignore
     gitignoreCustom :: Text
@@ -109,303 +117,395 @@
         else unlines ("\n# User specific" : settingsGitignore)
 
     ghActionsYml :: Text
-    ghActionsYml = [text|
-        name: CI
-
-        # Trigger the workflow on push or pull request, but only for the master branch
-        on:
-          pull_request:
-          push:
-            branches: [master]
-
-        jobs:
-          build:
-            name: ghc ${{ matrix.ghc }}
-            runs-on: ubuntu-16.04
-            strategy:
-              matrix:
-                cabal: ["${defaultCabal}"]
-                ghc:
-                  ${ghActionsVersions}
-
-            steps:
-            - uses: actions/checkout@v2
-              if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/master'
-
-            - uses: actions/setup-haskell@v1
-              name: Setup Haskell
-              with:
-                ghc-version: ${{ matrix.ghc }}
-                cabal-version: ${{ matrix.cabal }}
-
-            - uses: actions/cache@v1
-              name: Cache ~/.cabal/store
-              with:
-                path: ~/.cabal/store
-                key: ${{ runner.os }}-${{ matrix.ghc }}-cabal
+    ghActionsYml = unlines $
+        [ "name: CI"
+        , ""
+        , "on:"
+        , "  pull_request:"
+        , "    types: [synchronize, opened, reopened]"
+        , "  push:"
+        , "    branches: [main]"
+        , "  schedule:"
+        , "    # additionally run once per week (At 00:00 on Sunday) to maintain cache"
+        , "    - cron: '0 0 * * 0'"
+        , ""
+        , "jobs:"
 
-            - name: Build
-              run: |
-                $cabalUpdate
-                $cabalBuild
+        ]
+        <> memptyIfFalse settingsCabal ghActionsCabal
+        <> memptyIfFalse (settingsCabal && settingsStack) [""]
+        <> memptyIfFalse settingsStack ghActionsStack
 
-            - name: Test
-              run: |
-                ${cabalTest}
-        |]
+    ghActionsCabal :: [Text]
+    ghActionsCabal =
+        [ "  cabal:"
+        , "    name: ${{ matrix.os }} / ghc ${{ matrix.ghc }}"
+        , "    runs-on: ${{ matrix.os }}"
+        , "    strategy:"
+        , "      matrix:"
+        , "        os: [ubuntu-latest, macOS-latest, windows-latest]"
+        , "        cabal: [" <> quote defaultCabal <> "]"
+        , "        ghc:"
+        ]
+        <> map (indent 10 <>) ghActionsVersions
+        <> ghActionsExcludes
+        <>
+        [ ""
+        , "    steps:"
+        , "    - uses: actions/checkout" <> ghcActionsCheckoutVersion
+        , ""
+        , "    - uses: haskell-actions/setup" <> ghcActionsSetupHaskellVersion
+        , "      id: setup-haskell-cabal"
+        , "      name: Setup Haskell"
+        , "      with:"
+        , "        ghc-version: ${{ matrix.ghc }}"
+        , "        cabal-version: ${{ matrix.cabal }}"
+        , ""
+        , "    - name: Configure"
+        , "      run: |"
+        , "        " <> cabalConfigure
+        , ""
+        , "    - name: Freeze"
+        , "      run: |"
+        , "        cabal freeze"
+        , ""
+        , "    - uses: actions/cache" <> ghcActionsCacheVersion
+        , "      name: Cache ~/.cabal/store"
+        , "      with:"
+        , "        path: ${{ steps.setup-haskell-cabal.outputs.cabal-store }}"
+        , "        key: ${{ runner.os }}-${{ matrix.ghc }}-${{ hashFiles('cabal.project.freeze') }}"
+        , ""
+        , "    - name: Install dependencies"
+        , "      run: |"
+        , "        " <> cabalBuild <> " --only-dependencies"
+        , ""
+        , "    - name: Build"
+        , "      run: |"
+        , "        " <> cabalBuild
+        , ""
+        , "    - name: Test"
+        , "      run: |"
+        , "        " <> cabalTest
+        , ""
+        , "    - name: Documentation"
+        , "      run: |"
+        , "        " <> cabalDocumentation
+        , ""
+        ]
 
+    ghActionsStack :: [Text]
+    ghActionsStack =
+        [ "  stack:"
+        , "    name: stack / ghc ${{ matrix.ghc }}"
+        , "    runs-on: ubuntu-latest"
+        , "    strategy:"
+        , "      matrix:"
+        , "        stack: [" <> quote defaultStack <> "]"
+        , "        ghc:"
+        ]
+        <> map (indent 10 <>) ghActionsVersions
+        <>
+        [ ""
+        , "    steps:"
+        , "    - uses: actions/checkout" <> ghcActionsCheckoutVersion
+        , "      if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/main'"
+        , ""
+        , "    - uses: haskell-actions/setup" <> ghcActionsSetupHaskellVersion
+        , "      name: Setup Haskell Stack"
+        , "      with:"
+        , "        ghc-version: ${{ matrix.ghc }}"
+        , "        stack-version: ${{ matrix.stack }}"
+        , ""
+        , "    - uses: actions/cache" <> ghcActionsCacheVersion
+        , "      name: Cache ~/.stack"
+        , "      with:"
+        , "        path: ~/.stack"
+        , "        key: ${{ runner.os }}-${{ matrix.ghc }}-stack"
+        , ""
+        , "    - name: Build"
+        , "      run: |"
+        , "        " <> stackBuild
+        , ""
+        , "    - name: Test"
+        , "      run: |"
+        , "        " <> stackTest
+        ]
 
-    ghActionsVersions :: Text
-    ghActionsVersions = intercalateMap
-        "\n"
-        (\ghc -> "- " <> ghActionsMatrixItem ghc)
+    ghActionsVersions :: [Text]
+    ghActionsVersions = map
+        (\ghc -> "- " <> quote (showGhcVer ghc))
         settingsTestedVersions
 
-    ghActionsMatrixItem :: GhcVer -> Text
-    ghActionsMatrixItem v = "\"" <> showGhcVer v <> "\""
+    ghActionsExcludes :: [Text]
+    ghActionsExcludes =
+        let versionsToExclude = -- all but the latest version
+                drop 1 $ sortWith Down settingsTestedVersions
+            osesToExclude = ["macOS-latest", "windows-latest"]
+            excludes = do
+                os <- osesToExclude
+                version <- versionsToExclude
+                [  "- os: " <> os
+                 , "  ghc: " <> showGhcVer version
+                 ]
+        in case excludes of
+            [] -> []
+            xs ->
+                "        exclude:"
+                : map (indent 10 <>) xs
 
+    dependabotYml :: Text
+    dependabotYml = unlines
+        [ "updates:"
+        , "  - package-ecosystem: \"github-actions\""
+        , "    directory: \"/\""
+        , "    schedule:"
+        , "      interval: \"daily\""
+        , "    commit-message:"
+        , "      prefix: \"GA\""
+        , "      include: \"scope\""
+        , "    labels:"
+        , "      - \"CI\""
+        , "      - \"dependencies\""
+        ]
+
     -- create travis.yml template
     travisYml :: Text
-    travisYml =
-        [text|
-        sudo: true
-        language: haskell
-
-        git:
-          depth: 5
-
-        cabal: "${defaultCabal}"
-
-        cache:
-          directories:
-          $travisCabalCache
-          $travisStackCache
-
-        matrix:
-          include:
-          $travisCabalMtr
-          $travisStackMtr
-          $travisStackAllowFailuresMtr
-
-        $installAndScript
-
-        notifications:
-          email: false
-        |]
+    travisYml = unlines $
+        [ "language: haskell"
+        , ""
+        , "git:"
+        , "  depth: 5"
+        , ""
+        , "cabal: " <> quote defaultCabal
+        , ""
+        , "cache:"
+        , "  directories:"
+        ]
+        <> travisCabalCache
+        <> travisStackCache
+        <>
+        [ ""
+        , "jobs:"
+        , "  include:"
+        ]
+        <> travisCabalMtr
+        <> travisStackMtr
+        <> travisStackAllowFailuresMtr
+        <> installAndScript
+        <>
+        [ ""
+        , "notifications:"
+        , "  email: false"
+        ]
 
-    travisCabalCache, travisStackCache :: Text
-    travisCabalCache = memptyIfFalse settingsCabal "- \"$HOME/.cabal/store\""
+    travisCabalCache, travisStackCache :: [Text]
+    travisCabalCache = memptyIfFalse settingsCabal ["  - " <> quote "$HOME/.cabal/store"]
     travisStackCache = memptyIfFalse settingsStack
-        [text|
-        - "$$HOME/.stack"
-        - "$$TRAVIS_BUILD_DIR/.stack-work"
-        |]
+        [ "  - " <> quote "$HOME/.stack"
+        , "  - " <> quote "$TRAVIS_BUILD_DIR/.stack-work"
+        ]
 
-    travisCabalMtr :: Text
+    travisCabalMtr :: [Text]
     travisCabalMtr = memptyIfFalse settingsCabal $
-        tconcatMap travisCabalMatrixItem settingsTestedVersions
+        map travisCabalMatrixItem settingsTestedVersions
 
     travisCabalMatrixItem :: GhcVer -> Text
-    travisCabalMatrixItem (showGhcVer -> ghcV) = [text|- ghc: $ghcV|]
+    travisCabalMatrixItem (showGhcVer -> ghcV) = "  - ghc: " <> ghcV
 
     -- Due to the Stack issues with newer Cabal versions TravisCI for 'oldGhcs'
     -- can fail. Possible failure jobs are added to the @allow-failures@ section.
-    travisStackMtr :: Text
-    travisStackMtr = memptyIfFalse settingsStack $ tconcatMap
-           travisStackMatrixItem (delete defaultGHC settingsTestedVersions)
+    travisStackMtr :: [Text]
+    travisStackMtr = memptyIfFalse settingsStack $
+        concatMap travisStackMatrixItem (delete defaultGHC settingsTestedVersions)
         <> travisStackMatrixDefaultItem
 
-    travisStackAllowFailuresMtr :: Text
-    travisStackAllowFailuresMtr = memptyIfFalse (settingsStack && not (null old))
-        [text|
-        $endLine
-        allow_failures:
-        $matrix
-        |]
+    travisStackAllowFailuresMtr :: [Text]
+    travisStackAllowFailuresMtr = memptyIfFalse (settingsStack && not (null old)) $
+        [ ""
+        , "  allow_failures:"
+        ]
+        <> concatMap travisStackMatrixItem old
       where
         old :: [GhcVer]
         old = settingsTestedVersions `intersect` oldGhcs
 
-        matrix :: Text
-        matrix = tconcatMap travisStackMatrixItem old
-
-    travisStackMatrixItem :: GhcVer -> Text
+    travisStackMatrixItem :: GhcVer -> [Text]
     travisStackMatrixItem (showGhcVer -> ghcV) =
-        [text|
-        $endLine
-        - ghc: ${ghcV}
-          env: STACK_YAML="$$TRAVIS_BUILD_DIR/stack-$ghcV.yaml"
-        |]
+        [ ""
+        , "  - ghc: " <> ghcV
+        , "    env: STACK_YAML=" <> quote ("$TRAVIS_BUILD_DIR/stack-" <> ghcV <> ".yaml")
+        ]
 
-    travisStackMatrixDefaultItem :: Text
-    travisStackMatrixDefaultItem = let defGhc = showGhcVer defaultGHC in
-        [text|
-        $endLine
-        - ghc: ${defGhc}
-          env: STACK_YAML="$$TRAVIS_BUILD_DIR/stack.yaml"
-        |]
+    travisStackMatrixDefaultItem :: [Text]
+    travisStackMatrixDefaultItem =
+        [ ""
+        , "  - ghc: " <> showGhcVer defaultGHC
+        , "    env: STACK_YAML=" <> quote "$TRAVIS_BUILD_DIR/stack.yaml"
+        ]
 
-    installAndScript :: Text
+    installAndScript :: [Text]
     installAndScript =
+        ""
+        : "install:"
+        : hlintCheck
+        <>
         if settingsCabal
         then if settingsStack
              then installScriptBoth
              else installScriptCabal
         else installScriptStack
 
-    installScriptBoth :: Text
+    installScriptBoth :: [Text]
     installScriptBoth =
-        [text|
-        install:
-          $hlintCheck
-
-          - |
-            if [ -z "$$STACK_YAML" ]; then
-              $cabalUpdate
-              $cabalBuild
-            else
-              curl -sSL https://get.haskellstack.org/ | sh
-              stack --version
-              $stackBuild
-            fi
-
-        script:
-          - |
-            if [ -z "$$STACK_YAML" ]; then
-              ${cabalTest}
-            else
-              $stackTest
-            fi
-        |]
+        [ "  - |"
+        , "    if [ -z " <> quote "$STACK_YAML" <> " ]; then"
+        , "      " <> cabalUpdate
+        , "      " <> cabalConfigure
+        , "      " <> cabalBuild
+        , "    else"
+        , "      curl -sSL https://get.haskellstack.org/ | sh"
+        , "      stack --version"
+        , "      " <> stackBuild
+        , "    fi"
+        , ""
+        , "script:"
+        , "  - |"
+        , "    if [ -z " <> quote "$STACK_YAML" <> " ]; then"
+        , "      " <> cabalTest
+        , "    else"
+        , "      " <> stackTest
+        , "    fi"
+        ]
 
-    installScriptCabal :: Text
+    installScriptCabal :: [Text]
     installScriptCabal =
-        [text|
-        install:
-          $hlintCheck
-
-          - $cabalUpdate
-          - $cabalBuild
-
-        script:
-          - ${cabalTest}
-        |]
+        [ "  - " <> cabalUpdate
+        , "  - " <> cabalConfigure
+        , "  - " <> cabalBuild
+        , ""
+        , "script:"
+        , "  - " <> cabalTest
+        ]
 
-    installScriptStack :: Text
+    installScriptStack :: [Text]
     installScriptStack =
-        [text|
-        install:
-          $hlintCheck
-
-          - curl -sSL https://get.haskellstack.org/ | sh
-          - stack --version
-          - $stackBuild
-
-        script:
-          - $stackTest
-        |]
+        [ "  - curl -sSL https://get.haskellstack.org/ | sh"
+        , "  - stack --version"
+        , "  - " <> stackBuild
+        , ""
+        , "script:"
+        , "  - " <> stackTest
+        ]
 
     cabalUpdate :: Text
-    cabalUpdate = "cabal v2-update"
+    cabalUpdate = "cabal update"
 
+    cabalConfigure :: Text
+    cabalConfigure = "cabal configure --enable-tests --enable-benchmarks --enable-documentation --test-show-details=direct --write-ghc-environment-files=always"
+
     cabalBuild :: Text
-    cabalBuild = "cabal v2-build --enable-tests --enable-benchmarks"
+    cabalBuild = "cabal build all"
 
     cabalTest :: Text
-    cabalTest = if settingsTest
-        then "cabal v2-test --enable-tests"
-        else "echo 'No tests'"
+    cabalTest = "cabal test all"
 
+    cabalDocumentation :: Text
+    cabalDocumentation = "cabal haddock"
+
     stackBuild :: Text
     stackBuild = "stack build --system-ghc --test --bench --no-run-tests --no-run-benchmarks --ghc-options=-Werror"
 
     stackTest :: Text
     stackTest = "stack test --system-ghc"
 
-    hlintCheck :: Text
+    hlintCheck :: [Text]
     hlintCheck =
-        [text|
-        # HLint check
-        - curl -sSL https://raw.github.com/ndmitchell/neil/master/misc/travis.sh | sh -s -- hlint .
-        |]
+        [ "  # HLint check"
+        , "  - curl -sSL https://raw.github.com/ndmitchell/neil/master/misc/travis.sh | sh -s -- hlint ."
+        , ""
+        ]
 
     appVeyorYml :: Text
-    appVeyorYml =
+    appVeyorYml = unlines $
         if settingsCabal
         then appVeyorYmlCabal
         else appVeyorYmlStack
 
-    appVeyorYmlCabal :: Text
-    appVeyorYmlCabal = let defGhc = showGhcVer defaultGHC in
-        [text|
-        clone_folder: "c:\\WORK"
-        clone_depth: 5
-
-        # Do not build feature branch with open Pull Requests
-        skip_branch_with_pr: true
-
-        platform:
-          - x86_64
-
-        cache:
-          - "C:\\SR"
-          - dist-newstyle
-
-        environment:
-          global:
-            CABOPTS: --store-dir=C:\\SR
-
-          matrix:
-            - GHCVER: $defGhc
-
-        install:
-          - choco source add -n mistuke -s https://www.myget.org/F/mistuke/api/v2
-          - choco install -y cabal --version 2.4.1.0
-          - choco install -y ghc   --version $defGhc
-          - refreshenv
-
-        before_build:
-          - cabal --version
-          - ghc   --version
-          - cabal %CABOPTS% v2-update
+    appVeyorYmlCommon :: [Text]
+    appVeyorYmlCommon =
+        [ "clone_depth: 5"
+        , ""
+        , "# Do not build feature branch with open Pull Requests"
+        , "skip_branch_with_pr: true"
+        , ""
+        , "# build only main branch"
+        , "branches:"
+        , "  only:"
+        , "    - main"
+        , ""
+        ]
 
-        build_script:
-          - cabal %CABOPTS% v2-build --enable-tests
-          - cabal %CABOPTS% v2-test  --enable-tests
-        |]
+    appVeyorYmlCabal :: [Text]
+    appVeyorYmlCabal = let defGhc = showGhcVer defaultGHC in
+        ( "clone_folder: " <> quote "c:\\\\WORK" )
+        : appVeyorYmlCommon ++
+        [ "platform:"
+        , "  - x86_64"
+        , ""
+        , "cache:"
+        , "  - " <> quote "C:\\\\SR"
+        , "  - dist-newstyle"
+        , ""
+        , "environment:"
+        , "  global:"
+        , "    CABOPTS: --store-dir=C:\\\\SR"
+        , ""
+        , "  matrix:"
+        , "    - GHCVER: " <> defGhc
+        , ""
+        , "install:"
+        , "  - choco source add -n mistuke -s https://www.myget.org/F/mistuke/api/v2"
+        , "  - choco install -y cabal --version 3.6.2.0"
+        , "  - choco install -y ghc   --version " <> defGhc
+        , "  - refreshenv"
+        , ""
+        , "before_build:"
+        , "  - cabal --version"
+        , "  - ghc   --version"
+        , "  - cabal %CABOPTS% update"
+        , ""
+        , "build_script:"
+        , "  - cabal %CABOPTS% configure --enable-tests --enable-benchmarks --enable-documentation --test-show-details=direct --write-ghc-environment-files=always"
+        , "  - cabal %CABOPTS% build all"
+        , "  - cabal %CABOPTS% test  all"
+        ]
 
     -- create appveyor.yml template
-    appVeyorYmlStack :: Text
-    appVeyorYmlStack =
-        [text|
-        clone_depth: 5
-
-        # Do not build feature branch with open Pull Requests
-        skip_branch_with_pr: true
-
-        environment:
-          STACK_ROOT: C:\sr
-          STACK_VERSION: 2.1.1
-
-          # Workaround a gnarly bug https://github.com/haskell/cabal/issues/5386
-          # See: https://www.fpcomplete.com/blog/2018/06/sed-a-debugging-story
-          # TODO: check if it's fixed once we switch to lst-13 and GHC 8.6
-          TMP: "c:\\tmp"
-
-          matrix:
-            - STACK_YAML: stack.yaml
-
-        cache:
-          - "%STACK_ROOT% -> %STACK_YAML%, appveyor.yml"
-          - ".stack-work -> %STACK_YAML%, appveyor.yml"
-
-        install:
-          - choco install -y haskell-stack --version %STACK_VERSION%
-          - stack setup > nul
-
-        build_script:
-          - stack build --test --bench --no-run-tests --no-run-benchmarks --ghc-options=-Werror
-
-        test_script:
-          - stack test
-        |]
+    appVeyorYmlStack :: [Text]
+    appVeyorYmlStack = appVeyorYmlCommon ++
+        [ "environment:"
+        , "  STACK_ROOT: C:\\sr"
+        , "  STACK_VERSION: " <> defaultStack
+        , ""
+        , "  # Workaround a gnarly bug https://github.com/haskell/cabal/issues/5386"
+        , "  # See: https://www.fpcomplete.com/blog/2018/06/sed-a-debugging-story"
+        , "  # TODO: check if it's fixed once we switch to lst-13 and GHC 8.6"
+        , "  TMP: " <> quote "c:\\\\tmp"
+        , ""
+        , "  matrix:"
+        , "    - STACK_YAML: stack.yaml"
+        , ""
+        , "cache:"
+        , "  - " <> quote "%STACK_ROOT% -> %STACK_YAML%, appveyor.yml"
+        , "  - " <> quote ".stack-work -> %STACK_YAML%, appveyor.yml"
+        , ""
+        , "install:"
+        , "  - choco install -y haskell-stack --version %STACK_VERSION%"
+        , "  - stack setup > nul"
+        , ""
+        , "build_script:"
+        , "  - stack build --test --bench --no-run-tests --no-run-benchmarks --ghc-options=-Werror"
+        , ""
+        , "test_script:"
+        , "  - stack test"
+        ]
diff --git a/src/Summoner/Template/Haskell.hs b/src/Summoner/Template/Haskell.hs
--- a/src/Summoner/Template/Haskell.hs
+++ b/src/Summoner/Template/Haskell.hs
@@ -1,9 +1,10 @@
-{-# LANGUAGE QuasiQuotes #-}
-
 {- |
-Copyright: (c) 2017-2019 Kowainik
-SPDX-License-Identifier: MPL-2.0
-Maintainer: Kowainik <xrom.xkov@gmail.com>
+Module                  : Summoner.Template.Haskell
+Copyright               : (c) 2017-2026 Kowainik
+SPDX-License-Identifier : MPL-2.0
+Maintainer              : Kowainik <xrom.xkov@gmail.com>
+Stability               : Stable
+Portability             : Portable
 
 Templates for generated Haskell source code files.
 -}
@@ -12,10 +13,8 @@
        ( haskellFiles
        ) where
 
-import NeatInterpolation (text)
-
 import Summoner.Settings (Settings (..))
-import Summoner.Text (packageToModule)
+import Summoner.Text (packageToModule, quote)
 import Summoner.Tree (TreeFs (..))
 
 
@@ -28,24 +27,23 @@
     ]
   where
     libFile :: TreeFs
-    libFile = File (toString libModuleName <> ".hs")
-        [text|
-        {- |
-        Copyright: (c) $settingsYear $settingsFullName
-        SPDX-License-Identifier: $licenseName
-        Maintainer: $settingsFullName <$settingsEmail>
-
-        $settingsDescription
-        -}
-
-        module $libModuleName
-               ( someFunc
-               ) where
-
-
-        someFunc :: IO ()
-        someFunc = putStrLn ("someFunc" :: String)
-        |]
+    libFile = File (toString libModuleName <> ".hs") $ unlines
+        [ "{- |"
+        , "Copyright: (c) " <> settingsYear <> " " <> settingsFullName
+        , "SPDX-License-Identifier: " <> licenseName
+        , "Maintainer: " <> settingsFullName <> " <" <> settingsEmail <> ">"
+        , ""
+        , settingsDescription
+        , "-}"
+        , ""
+        , "module " <> libModuleName
+        , "    ( projectName"
+        , "    ) where"
+        , ""
+        , ""
+        , "projectName :: String"
+        , "projectName = " <> quote settingsRepo
+        ]
 
     libModuleName :: Text
     libModuleName = packageToModule settingsRepo
@@ -54,48 +52,29 @@
     licenseName = show settingsLicenseName
 
     exeFile :: TreeFs
-    exeFile = File "Main.hs" $ if settingsIsLib then createExe else createOnlyExe
-
-    createOnlyExe :: Text
-    createOnlyExe =
-        [text|
-        module Main (main) where
-
-
-        main :: IO ()
-        main = putStrLn ("Hello, world!" :: String)
-        |]
-
-    createExe :: Text
-    createExe =
-        [text|
-        module Main (main) where
-
-        import $libModuleName (someFunc)
-
-
-        main :: IO ()
-        main = someFunc
-        |]
+    exeFile = File "Main.hs" $ stanza "Executable"
 
     testFile :: TreeFs
-    testFile = File "Spec.hs"
-        [text|
-        module Main (main) where
-
-
-        main :: IO ()
-        main = putStrLn ("Test suite is not implemented" :: String)
-        |]
+    testFile = File "Spec.hs" $ stanza "Tests"
 
     benchmarkFile :: TreeFs
-    benchmarkFile = File "Main.hs"
-        [text|
-        module Main (main) where
-
-        import Gauge.Main
-
+    benchmarkFile = File "Main.hs" $ stanza "Benchmarks"
 
-        main :: IO ()
-        main = defaultMain [bench "const" (whnf const ())]
-        |]
+    stanza :: Text -> Text
+    stanza st = unlines $
+          "module Main (main) where"
+        : memptyIfFalse settingsIsLib
+            [ ""
+            , "import " <> libModuleName <> " (projectName)"
+            ]
+        <>
+        [ ""
+        , ""
+        , "main :: IO ()"
+        , mainContent
+        ]
+      where
+        mainContent :: Text
+        mainContent = if settingsIsLib
+            then "main = putStrLn (" <> quote (st <> " for ") <> " ++ projectName)"
+            else "main = putStrLn (" <> quote (st <> " not implemented") <> " :: String)"
diff --git a/src/Summoner/Template/Script.hs b/src/Summoner/Template/Script.hs
--- a/src/Summoner/Template/Script.hs
+++ b/src/Summoner/Template/Script.hs
@@ -1,9 +1,10 @@
-{-# LANGUAGE QuasiQuotes #-}
-
 {- |
-Copyright: (c) 2017-2019 Kowainik
-SPDX-License-Identifier: MPL-2.0
-Maintainer: Kowainik <xrom.xkov@gmail.com>
+Module                  : Summoner.Template.Script
+Copyright               : (c) 2017-2026 Kowainik
+SPDX-License-Identifier : MPL-2.0
+Maintainer              : Kowainik <xrom.xkov@gmail.com>
+Stability               : Stable
+Portability             : Portable
 
 File templates for @cabal@ and @stack@ scripts.
 -}
@@ -12,38 +13,35 @@
        ( scriptFile
        ) where
 
-import NeatInterpolation (text)
-
 import Summoner.GhcVer (GhcVer, baseVer, latestLts)
 import Summoner.Settings (Tool (..))
+import Summoner.Text (quote)
 
 
 -- | 'Text' content for a single script file.
 scriptFile :: GhcVer -> Tool -> Text
 scriptFile ghcVer = \case
-    Cabal ->
-        [text|
-        #!/usr/bin/env cabal
-        {- cabal:
-        build-depends:
-          , base ^>= $baseVersion
-        -}
-
-        main :: IO ()
-        main = putStrLn "Hello, World!"
-        |]
-    Stack ->
-        [text|
-        #!/usr/bin/env stack
-        {- stack
-          --resolver ${ltsVersion}
-          script
-          --package base
-        -}
-
-        main :: IO ()
-        main = putStrLn "Hello, World!"
-        |]
+    Cabal -> unlines
+        [ "#!/usr/bin/env cabal"
+        , "{- cabal:"
+        , "build-depends:"
+        , "  , base ^>= " <> baseVersion
+        , "-}"
+        , ""
+        , "main :: IO ()"
+        , "main = putStrLn " <> quote "Hello, World!"
+        ]
+    Stack -> unlines
+        [ "#!/usr/bin/env stack"
+        , "{- stack"
+        , "  --resolver " <> ltsVersion
+        , "  script"
+        , "  --package base"
+        , "-}"
+        , ""
+        , "main :: IO ()"
+        , "main = putStrLn " <> quote "Hello, World!"
+        ]
   where
     baseVersion, ltsVersion :: Text
     baseVersion = baseVer ghcVer
diff --git a/src/Summoner/Template/Stack.hs b/src/Summoner/Template/Stack.hs
--- a/src/Summoner/Template/Stack.hs
+++ b/src/Summoner/Template/Stack.hs
@@ -1,7 +1,10 @@
 {- |
-Copyright: (c) 2017-2019 Kowainik
-SPDX-License-Identifier: MPL-2.0
-Maintainer: Kowainik <xrom.xkov@gmail.com>
+Module                  : Summoner.Template.Stack
+Copyright               : (c) 2017-2026 Kowainik
+SPDX-License-Identifier : MPL-2.0
+Maintainer              : Kowainik <xrom.xkov@gmail.com>
+Stability               : Stable
+Portability             : Portable
 
 Templates for @stack.yaml@ files.
 -}
diff --git a/src/Summoner/Text.hs b/src/Summoner/Text.hs
--- a/src/Summoner/Text.hs
+++ b/src/Summoner/Text.hs
@@ -1,29 +1,27 @@
 {- |
-Copyright: (c) 2017-2019 Kowainik
-SPDX-License-Identifier: MPL-2.0
-Maintainer: Kowainik <xrom.xkov@gmail.com>
+Module                  : Summoner.Text
+Copyright               : (c) 2017-2026 Kowainik
+SPDX-License-Identifier : MPL-2.0
+Maintainer              : Kowainik <xrom.xkov@gmail.com>
+Stability               : Stable
+Portability             : Portable
 
 Various helpful functions to work with 'Text'
 -}
 
 module Summoner.Text
-       ( endLine
-       , packageToModule
+       ( packageToModule
        , packageNameValid
        , moduleNameValid
        , intercalateMap
        , headToUpper
-       , tconcatMap
+       , quote
        ) where
 
 import qualified Data.Char as C
 import qualified Data.Text as T
 
 
--- | Endline symbol to use with @neat-interpolation@.
-endLine :: Text
-endLine = "\n"
-
 -- | Creates module name from the name of the package
 -- Ex: @my-lovely-project@ — @MyLovelyProject@
 packageToModule :: Text -> Text
@@ -63,3 +61,7 @@
 -- | Convert every element of a list into text, and squash the results
 tconcatMap :: (a -> Text) -> [a] -> Text
 tconcatMap f = T.concat . map f
+
+-- | Wrap the given text into quotes.
+quote :: Text -> Text
+quote t = "\"" <> t <> "\""
diff --git a/src/Summoner/Tree.hs b/src/Summoner/Tree.hs
--- a/src/Summoner/Tree.hs
+++ b/src/Summoner/Tree.hs
@@ -1,23 +1,26 @@
 {-# LANGUAGE ViewPatterns #-}
 
 {- |
-Copyright: (c) 2017-2019 Kowainik
-SPDX-License-Identifier: MPL-2.0
-Maintainer: Kowainik <xrom.xkov@gmail.com>
+Module                  : Summoner.Tree
+Copyright               : (c) 2017-2026 Kowainik
+SPDX-License-Identifier : MPL-2.0
+Maintainer              : Kowainik <xrom.xkov@gmail.com>
+Stability               : Stable
+Portability             : Portable
 
 Data type for representing filesystem structure via tree.
 -}
 
 module Summoner.Tree
-       ( TreeFs (..)
-       , traverseTree
-       , pathToTree
-       , insertTree
-       , showBoldTree
-       , showTree
-       ) where
+    ( TreeFs (..)
+    , traverseTree
+    , pathToTree
+    , insertTree
+    , showBoldTree
+    , showTree
+    ) where
 
-import Colourista (bold, reset)
+import Colourista.Short (b)
 import System.Directory (createDirectoryIfMissing, withCurrentDirectory)
 import System.FilePath (splitDirectories)
 
@@ -25,9 +28,9 @@
 -- | Describes simple structure of filesystem tree.
 data TreeFs
       -- | Name of directory (relative) and its containing entries
-    = Dir FilePath [TreeFs]
+    = Dir !FilePath ![TreeFs]
       -- | File name (relative) and file content
-    | File FilePath Text
+    | File !FilePath !Text
     deriving stock (Generic, Show, Eq, Ord)
 
 -- | Walks through directory tree and write file contents, creating all
@@ -100,10 +103,7 @@
         nodeRep = leader <> arm <> tie <> boldDir (fp <> "/")
           where
             boldDir :: FilePath -> Text
-            boldDir str = toText $
-                if isBold
-                then bold <> str <> reset
-                else str
+            boldDir str = toText $ if isBold then b str else str
 
         extension :: Text
         extension = case arm of ""  -> ""; "└" -> "    "; _   -> "│   "
diff --git a/summoner.cabal b/summoner.cabal
--- a/summoner.cabal
+++ b/summoner.cabal
@@ -1,6 +1,6 @@
-cabal-version:       2.4
+cabal-version:       3.4
 name:                summoner
-version:             2.0.1.1
+version:             2.1.0.0
 synopsis:            Tool for scaffolding fully configured batteries-included production-level Haskell projects.
 description:         Tool for scaffolding fully configured batteries-included production-level Haskell projects.
                      See [README.md](https://github.com/kowainik/summoner#-summoner) for details.
@@ -10,7 +10,7 @@
 license-file:        LICENSE
 author:              Veronika Romashkina, Dmitrii Kovanikov
 maintainer:          Kowainik <xrom.xkov@gmail.com>
-copyright:           2018-2020 Kowainik
+copyright:           2018-2026 Kowainik
 category:            CLI, CLI Tool, Development
 build-type:          Simple
 stability:           stable
@@ -18,8 +18,15 @@
                      CHANGELOG.md
 tested-with:         GHC == 8.4.4
                      GHC == 8.6.5
-                     GHC == 8.8.3
-                     GHC == 8.10.1
+                     GHC == 8.8.4
+                     GHC == 8.10.7
+                     GHC == 9.0.2
+                     GHC == 9.2.8
+                     GHC == 9.4.7
+                     GHC == 9.6.7
+                     GHC == 9.8.4
+                     GHC == 9.10.3
+                     GHC == 9.12.3
 extra-source-files:
     examples/summoner-default.toml
 
@@ -72,31 +79,49 @@
   location: git@github.com:kowainik/summoner.git
 
 common common-options
-  build-depends:       base >= 4.11 && < 4.15
-                     , relude ^>= 0.7.0.0
+  build-depends:       base >= 4.11 && < 4.22
+                     , relude >= 1.0.0.0 && < 1.3
 
   mixins:              base hiding (Prelude)
-                     , relude (Relude as Prelude
-                              , Relude.Extra.Enum
-                              )
+                     , relude (Relude as Prelude)
+                     , relude
 
   ghc-options:         -Wall
                        -Wcompat
                        -Widentities
                        -Wincomplete-uni-patterns
                        -Wincomplete-record-updates
-  if impl(ghc >= 8.0)
-    ghc-options:       -Wredundant-constraints
-  if impl(ghc >= 8.2)
-    ghc-options:       -fhide-source-paths
-  if impl(ghc >= 8.4)
-    ghc-options:       -Wmissing-export-lists
+                       -Wredundant-constraints
+                       -Wnoncanonical-monad-instances
+                       -fhide-source-paths
+                       -Wmissing-export-lists
                        -Wpartial-fields
   if impl(ghc >= 8.8)
     ghc-options:       -Wmissing-deriving-strategies
                        -Werror=missing-deriving-strategies
+                       -fwrite-ide-info
+                       -hiedir=../.hie
   if impl(ghc >= 8.10)
     ghc-options:       -Wunused-packages
+  if impl(ghc >= 9.0)
+    ghc-options:       -Winvalid-haddock
+  if impl(ghc >= 9.2)
+    ghc-options:       -Wredundant-bang-patterns
+                       -Woperator-whitespace
+  if impl(ghc >= 9.4  && < 9.10)
+    ghc-options:       -Wforall-identifier
+  if impl(ghc >= 9.4)
+    ghc-options:       -Wredundant-strictness-flags
+  if impl(ghc >= 9.8)
+    ghc-options:       -Wterm-variable-capture
+                       -Winconsistent-flags
+  if impl(ghc >= 9.10)
+    ghc-options:       -Wincomplete-record-selectors
+                       -Wdeprecated-type-abstractions
+                       -Wdata-kinds-tc
+                       -Wdefaulted-exception-context
+  if impl(ghc >= 9.12)
+    ghc-options:       -Wview-pattern-signatures
 
   default-extensions:  DeriveGeneric
                        DerivingStrategies
@@ -110,6 +135,11 @@
 
   default-language:    Haskell2010
 
+common exe-options
+  ghc-options:         -threaded
+                       -rtsopts
+                       -with-rtsopts=-N
+
 library
   import:              common-options
   hs-source-dirs:      src
@@ -120,6 +150,7 @@
                          Summoner.Decision
                          Summoner.Default
                          Summoner.GhcVer
+                         Summoner.Golden
                          Summoner.License
                          Summoner.Mode
                          Summoner.Project
@@ -139,34 +170,34 @@
   autogen-modules:     Paths_summoner
   other-modules:       Paths_summoner
 
-  build-depends:       aeson >= 1.2.4.0 && < 1.6
-                     , colourista ^>= 0.1
-                     , containers ^>= 0.6
+  build-depends:       colourista ^>= 0.1.0.1
                      , directory ^>= 1.3.0.2
-                     , filepath ^>= 1.4.1.2
-                     , generic-data ^>= 0.8.0.0
+                     , filepath >= 1.4.1.2 && < 1.6
+                     , generic-data >= 0.8.0.0 && < 1.2
                      , gitrev ^>= 1.3.1
-                     , neat-interpolation ^>= 0.3.2.2
-                     , optparse-applicative ^>= 0.15
+                     , microaeson ^>= 0.1.0.0
+                     , optparse-applicative >= 0.16 && < 0.20
                      , process ^>= 1.6.1.0
-                     , shellmet ^>= 0.0.3.0
-                     , text ^>= 1.2.3.0
-                     , time >= 1.8 && < 1.11
+                     , shellmet >= 0.0.3.0 && < 0.0.7
+                     , time >= 1.8 && < 1.16
                      , tomland ^>= 1.3.0.0
-                     , validation-selective >= 0.0.0.0 && < 0.2
+                     , validation-selective >= 0.1.0.0 && < 0.3
 
 executable summon
-  import:              common-options
+  import:              common-options, exe-options
   hs-source-dirs:      app
   main-is:             Cli.hs
   build-depends:       summoner
 
-  ghc-options:         -threaded
-                       -rtsopts
-                       -with-rtsopts=-N
+executable gg
+  import:              common-options, exe-options
+  hs-source-dirs:      golden
+  main-is:             Main.hs
+  build-depends:       summoner
 
+
 test-suite summoner-test
-  import:              common-options
+  import:              common-options, exe-options
   type:                exitcode-stdio-1.0
   hs-source-dirs:      test
 
@@ -181,16 +212,10 @@
 
   build-depends:       directory
                      , filepath
-                     , hedgehog >= 0.5.3 && < 1.1
+                     , hedgehog >= 0.5.3 && < 1.8
                      , hspec >= 2.4.8
-                     , hspec-hedgehog ^>= 0.0.1.1
-                     , neat-interpolation
-                     , text
+                     , hspec-hedgehog >= 0.0.1.1 && < 0.4
                      , tomland
-                     , tree-diff >= 0.0.2 && < 0.2
+                     , tree-diff >= 0.0.2 && < 0.4
                      , summoner
                      , validation-selective
-
-  ghc-options:         -threaded
-                       -rtsopts
-                       -with-rtsopts=-N
diff --git a/test/Test/Golden.hs b/test/Test/Golden.hs
--- a/test/Test/Golden.hs
+++ b/test/Test/Golden.hs
@@ -1,7 +1,5 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 
-{-# LANGUAGE QuasiQuotes #-}
-
 {- | Golden tests for @summoner@.
 
 In the @test/golden@ folder we now have two projects that are created by
@@ -20,17 +18,18 @@
        ) where
 
 import Data.TreeDiff (ToExpr, ansiWlEditExprCompact, ediff)
-import NeatInterpolation (text)
 import System.Directory (doesDirectoryExist, listDirectory)
 import System.FilePath (takeFileName, (</>))
 import Test.Hspec (Spec, describe, expectationFailure, it)
 
-import Summoner (CustomPrelude (..), GhcVer (..), License (..), LicenseName (..), Settings (..),
-                 defaultGHC)
+import Summoner (Settings)
+import Summoner.Golden (cabalFull, cabalMinimal, fullBatteries, stackFull)
 import Summoner.Template (createProjectTemplate)
 import Summoner.Tree (TreeFs (..))
 
+import qualified Data.Text as T
 
+
 goldenSpec :: Spec
 goldenSpec = describe "golden tests" $ do
     it "correctly scaffolds the 'cabal-minimal' project" $
@@ -56,201 +55,14 @@
         dirs <- listDirectory filePath
         Dir (takeFileName filePath) <$> traverse (\dir -> readTreeFs $ filePath </> dir) dirs
     False -> do
-        content <- readFileText filePath
+        -- Normalize line endings (CRLF -> LF) for cross-platform compatibility
+        content <- T.filter (/= '\r') . decodeUtf8 <$> readFileBS filePath
         pure $ File (takeFileName filePath) content
 
 sortTree :: TreeFs -> TreeFs
 sortTree = \case
     file@(File _ _) -> file
-    Dir path fs -> Dir path $ sort $ map sortTree fs
-
-
-fullBatteries :: Settings
-fullBatteries = Settings
-    { settingsRepo           = "full-batteries"
-    , settingsOwner          = "kowainik"
-    , settingsDescription    = "Full-featured test project"
-    , settingsFullName       = "Kowainik"
-    , settingsEmail          = "xrom.xkov@gmail.com"
-    , settingsYear           = "2020"
-    , settingsCategories     = "Testing"
-    , settingsLicenseName    = MIT
-    , settingsLicenseText    = mitLicense
-    , settingsGitHub         = True
-    , settingsGhActions      = True
-    , settingsPrivate        = True
-    , settingsTravis         = True
-    , settingsAppVeyor       = True
-    , settingsIsLib          = True
-    , settingsIsExe          = True
-    , settingsTest           = True
-    , settingsBench          = True
-    , settingsTestedVersions = [Ghc802 .. defaultGHC]
-    , settingsPrelude        = Just $ CustomPrelude "relude" "Relude"
-    , settingsExtensions     = ["ConstraintKinds", "LambdaCase", "OverloadedStrings"]
-    , settingsGitignore      = [".secret"]
-    , settingsGhcOptions     = ["-Wcompat", "-Widentities"]
-    , settingsCabal          = True
-    , settingsStack          = True
-    , settingsNoUpload       = True
-    , settingsFiles          =
-        [ File "extra.txt" "See full content of the file [here](@github)\n"
-        , Dir ".github" [File "CODEOWNERS" "*  @chshersh @vrom911\n"]
-        , File ".stylish-haskell.yaml" "This is stylish-haskell.yaml\n"
-        , File "CONTRIBUTING.md" "This is contributing guide\n"
-        ]
-    }
-  where
-    mitLicense :: License
-    mitLicense = License [text|
-MIT License
-
-Copyright (c) 2018 Kowainik
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-|]
-
-stackFull :: Settings
-stackFull = Settings
-    { settingsRepo           = "stack-full"
-    , settingsOwner          = "kowainik"
-    , settingsDescription    = "Stack-only example with all integrations"
-    , settingsFullName       = "Kowainik"
-    , settingsEmail          = "xrom.xkov@gmail.com"
-    , settingsYear           = "2020"
-    , settingsCategories     = "Testing"
-    , settingsLicenseName    = BSD3
-    , settingsLicenseText    = bsd3License
-    , settingsGitHub         = True
-    , settingsGhActions      = False
-    , settingsPrivate        = False
-    , settingsTravis         = True
-    , settingsAppVeyor       = True
-    , settingsIsLib          = True
-    , settingsIsExe          = True
-    , settingsTest           = True
-    , settingsBench          = True
-    , settingsTestedVersions = [Ghc844 .. defaultGHC]
-    , settingsPrelude        = Just $ CustomPrelude "relude" "Relude"
-    , settingsExtensions     = ["DeriveGeneric", "TypeApplications"]
-    , settingsGitignore      = []
-    , settingsGhcOptions     = []
-    , settingsCabal          = False
-    , settingsStack          = True
-    , settingsNoUpload       = False
-    , settingsFiles          = []
-    }
-
-cabalFull :: Settings
-cabalFull = Settings
-    { settingsRepo           = "cabal-full"
-    , settingsOwner          = "kowainik"
-    , settingsDescription    = "Cabal-only example with all integrations"
-    , settingsFullName       = "Kowainik"
-    , settingsEmail          = "xrom.xkov@gmail.com"
-    , settingsYear           = "2020"
-    , settingsCategories     = "Testing"
-    , settingsLicenseName    = BSD3
-    , settingsLicenseText    = bsd3License
-    , settingsGitHub         = True
-    , settingsGhActions      = True
-    , settingsPrivate        = False
-    , settingsTravis         = True
-    , settingsAppVeyor       = True
-    , settingsIsLib          = True
-    , settingsIsExe          = True
-    , settingsTest           = True
-    , settingsBench          = True
-    , settingsTestedVersions = [Ghc844 .. defaultGHC]
-    , settingsPrelude        = Just $ CustomPrelude "relude" "Relude"
-    , settingsExtensions     = ["DeriveGeneric", "TypeApplications"]
-    , settingsGitignore      = []
-    , settingsGhcOptions     = []
-    , settingsCabal          = True
-    , settingsStack          = False
-    , settingsNoUpload       = False
-    , settingsFiles          = []
-    }
-
-cabalMinimal :: Settings
-cabalMinimal = Settings
-    { settingsRepo           = "cabal-minimal"
-    , settingsOwner          = "kowainik"
-    , settingsDescription    = "Minimal cabal-only test project"
-    , settingsFullName       = "Kowainik"
-    , settingsEmail          = "xrom.xkov@gmail.com"
-    , settingsYear           = "2020"
-    , settingsCategories     = ""
-    , settingsLicenseName    = NONE
-    , settingsLicenseText    = ""
-    , settingsGitHub         = False
-    , settingsGhActions      = False
-    , settingsPrivate        = False
-    , settingsTravis         = False
-    , settingsAppVeyor       = False
-    , settingsIsLib          = False
-    , settingsIsExe          = True
-    , settingsTest           = False
-    , settingsBench          = False
-    , settingsTestedVersions = [defaultGHC]
-    , settingsPrelude        = Nothing
-    , settingsExtensions     = []
-    , settingsGhcOptions     = []
-    , settingsGitignore      = []
-    , settingsCabal          = True
-    , settingsStack          = False
-    , settingsNoUpload       = True
-    , settingsFiles          = mempty
-    }
-
-bsd3License :: License
-bsd3License = License [text|
-BSD 3-Clause License
-
-Copyright (c) 2020, Kowainik
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice, this
-   list of conditions and the following disclaimer.
-
-2. Redistributions in binary form must reproduce the above copyright notice,
-   this list of conditions and the following disclaimer in the documentation
-   and/or other materials provided with the distribution.
-
-3. Neither the name of the copyright holder nor the names of its
-   contributors may be used to endorse or promote products derived from
-   this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-|]
+    Dir path fs     -> Dir path $ sort $ map sortTree fs
 
 -- Orphan instances
 
diff --git a/test/Test/Script.hs b/test/Test/Script.hs
--- a/test/Test/Script.hs
+++ b/test/Test/Script.hs
@@ -1,45 +1,22 @@
-{-# LANGUAGE QuasiQuotes #-}
-
 module Test.Script
-       ( scriptSpec
-       ) where
+    ( scriptSpec
+    ) where
 
-import NeatInterpolation (text)
-import Test.Hspec (Spec, describe, it, shouldBe)
+import Test.Hspec (Spec, describe, it, shouldReturn)
 
-import Summoner.GhcVer (GhcVer (..))
+import Summoner.Default (defaultGHC)
 import Summoner.Settings (Tool (..))
 import Summoner.Template.Script (scriptFile)
 
+import qualified Data.Text as T
 
 scriptSpec :: Spec
 scriptSpec = describe "script golden tests" $ do
     it "correctly creates cabal script" $
-        scriptFile Ghc844 Cabal `shouldBe` cabalScript
+        readScript "examples/cabalScript.hs" `shouldReturn` scriptFile defaultGHC Cabal
     it "correctly creates stack script" $
-        scriptFile Ghc865 Stack `shouldBe` stackScript
-
-cabalScript :: Text
-cabalScript = [text|
-#!/usr/bin/env cabal
-{- cabal:
-build-depends:
-  , base ^>= 4.11.1.0
--}
-
-main :: IO ()
-main = putStrLn "Hello, World!"
-|]
-
-stackScript :: Text
-stackScript = [text|
-#!/usr/bin/env stack
-{- stack
-  --resolver lts-14.27
-  script
-  --package base
--}
+        readScript "examples/stackScript.hs" `shouldReturn` scriptFile defaultGHC Stack
 
-main :: IO ()
-main = putStrLn "Hello, World!"
-|]
+-- | Read a script file, normalizing line endings (CRLF -> LF) for cross-platform compatibility
+readScript :: FilePath -> IO Text
+readScript path = T.filter (/= '\r') . decodeUtf8 <$> readFileBS path
diff --git a/test/Test/Show.hs b/test/Test/Show.hs
--- a/test/Test/Show.hs
+++ b/test/Test/Show.hs
@@ -14,10 +14,17 @@
 
 goldenGhcTable :: [Text]
 goldenGhcTable =
-  [ "GHC-7.10.3    base-4.8.0.2    lts-6.35"
-  , "GHC-8.0.2     base-4.9.1.0    lts-9.21"
-  , "GHC-8.2.2     base-4.10.1.0   lts-11.22"
-  , "GHC-8.4.4     base-4.11.1.0   lts-12.26"
-  , "GHC-8.6.5     base-4.12.0.0   lts-14.27"
-  , "GHC-8.8.3     base-4.13.0.0   lts-15.5"
-  ]
+    [ "GHC-8.0.2     base-4.9.1.0    lts-9.21"
+    , "GHC-8.2.2     base-4.10.1.0   lts-11.22"
+    , "GHC-8.4.4     base-4.11.1.0   lts-12.26"
+    , "GHC-8.6.5     base-4.12.0.0   lts-14.27"
+    , "GHC-8.8.4     base-4.13.0.0   lts-16.31"
+    , "GHC-8.10.7    base-4.14.3.0   lts-18.28"
+    , "GHC-9.0.2     base-4.15.1.0   lts-19.33"
+    , "GHC-9.2.8     base-4.16.4.0   lts-20.26"
+    , "GHC-9.4.8     base-4.17.2.1   lts-21.25"
+    , "GHC-9.6.7     base-4.18.3.1   lts-22.44"
+    , "GHC-9.8.4     base-4.19.2.0   lts-23.28"
+    , "GHC-9.10.3    base-4.20.2.0   lts-24.26"
+    , "GHC-9.12.3    base-4.21.1.0   nightly-2026-01-04"
+    ]
diff --git a/test/Test/TomlSpec.hs b/test/Test/TomlSpec.hs
--- a/test/Test/TomlSpec.hs
+++ b/test/Test/TomlSpec.hs
@@ -3,11 +3,10 @@
        ) where
 
 import Hedgehog (MonadGen, forAll, tripping)
-import Relude.Extra.Enum (universe)
 import Test.Hspec (Spec, describe, it, shouldReturn, shouldSatisfy)
 import Test.Hspec.Hedgehog (hedgehog)
 import Toml.Codec.Code (decode, encode)
-import Validation (Validation (..))
+import Validation (isSuccess)
 
 import Summoner.Config (ConfigP (..), PartialConfig, configCodec, defaultConfig, finalise)
 import Summoner.CustomPrelude (CustomPrelude (..))
@@ -34,11 +33,9 @@
     it "parses default configuration" $
         decode configCodec defaultConfigFileContent `shouldSatisfy` isRight
     it "default configuration is up-to-date" $
-        readFileText "examples/summoner-default.toml"
+        -- Normalize line endings (CRLF -> LF) for cross-platform compatibility
+        T.filter (/= '\r') . decodeUtf8 <$> readFileBS "examples/summoner-default.toml"
             `shouldReturn` defaultConfigFileContent
-  where
-    isSuccess :: Validation e a -> Bool
-    isSuccess = \case { Success _ -> True; _ -> False }
 
 tomlProp :: Spec
 tomlProp = describe "TOML property tests" $
