diff --git a/Changelog.md b/Changelog.md
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,3 +1,9 @@
+# 0.1.2.2
+
+- Lower minimum supported GHC to 8.6 and base to 4.12
+- Improve generated documentation
+- Faster `stg_newCounterzh`
+
 # 0.1.2.1
 
 - Disable cmm on 32 bit x86 architecture
diff --git a/Counter.cmm b/Counter.cmm
--- a/Counter.cmm
+++ b/Counter.cmm
@@ -1,5 +1,7 @@
 #include "Cmm.h"
 
+#define SIZEOF_StgCounter (SIZEOF_StgHeader + WDS(1))
+
 INFO_TABLE(stg_Counter, 0, 1, MUT_PRIM, "Counter", "Counter") ()
 {
   foreign "C" barf("stg_Counter entered!", NULL) never returns;
@@ -8,7 +10,8 @@
 stg_newCounterzh (W_ x)
 {
   P_ c;
-  ("ptr" c) = ccall allocate(MyCapability() "ptr", BYTES_TO_WDS(SIZEOF_StgHeader + WDS(1)));
+  ALLOC_PRIM_N (SIZEOF_StgCounter, stg_newCounterzh, x);
+  c = Hp - SIZEOF_StgCounter + WDS(1);
   SET_HDR(c, stg_Counter_info, CCCS);
   W_[c + SIZEOF_StgHeader] = x;
   return (c);
diff --git a/Readme.md b/Readme.md
--- a/Readme.md
+++ b/Readme.md
@@ -28,6 +28,9 @@
 setting where it does seem like a clear winner (please see benchmarks
 below).
 
+Still even is single-threaded scenario the `Counter` can serve as an
+efficient mutable integer cell that does not box the integer.
+
 # Benchmark
 
 ### Summary
@@ -720,8 +723,12 @@
 
 # Memory overhead
 
-Each unlifted value of type `Counter` is a singleton mutable array
-from GHC primitives under the hood. Thus it occupies at least
-`platform integer size` + `array size` + `header` bytes which should
-typically be at least 3 machine words. Lifted values may occupy more
-depending on optimizations.
+In pure Haskell (i.e. with `no-cmm` flag enabled) each unlifted value of
+type `Counter` is a singleton mutable array from GHC primitives under
+the hood. Thus it occupies at least `platform integer size` + `array
+size` + `header` bytes which should typically be at least 3 machine
+words. Lifted values may occupy more depending on optimizations.
+
+By default CMM will be enabled which should save one word of overhead
+because there would be no array any more hence no need to store
+trivial size.
diff --git a/atomic-counter.cabal b/atomic-counter.cabal
--- a/atomic-counter.cabal
+++ b/atomic-counter.cabal
@@ -5,7 +5,7 @@
 name:
   atomic-counter
 version:
-  0.1.2.1
+  0.1.2.2
 synopsis:
   Mutable counters that can be modified with atomic operatinos
 
@@ -31,6 +31,16 @@
 category:
   Concurrency, Data, Data Structures
 
+tested-with:
+  GHC == 8.6,
+  GHC == 8.8,
+  GHC == 8.10,
+  GHC == 9.2,
+  GHC == 9.4,
+  GHC == 9.6,
+  GHC == 9.8,
+  GHC == 9.10
+
 build-type:
   Simple
 
@@ -74,7 +84,6 @@
     -Wno-missed-specialisations
     -Wno-missing-import-lists
     -Wno-missing-local-signatures
-    -Wno-missing-safe-haskell-mode
     -Wno-safe
     -Wno-type-defaults
     -Wno-unsafe
@@ -83,10 +92,20 @@
     ghc-options:
       -Wno-missing-deriving-strategies
 
+  if impl(ghc >= 8.10)
+    ghc-options:
+      -Wno-missing-safe-haskell-mode
+      -Wno-prepositive-qualified-module
+
   if impl(ghc >= 9.2)
     ghc-options:
       -Wno-missing-kind-signatures
 
+  if impl(ghc >= 9.8)
+    ghc-options:
+      -Wno-missing-role-annotations
+      -Wno-missing-poly-kind-signatures
+
 library
   import: ghc-options
   exposed-modules:
@@ -97,7 +116,7 @@
   hs-source-dirs:
     src
   build-depends:
-    , base >= 4.14 && < 5
+    , base >= 4.12 && < 5
   if impl(ghc >= 9.4) && !arch(javascript) && !arch(i386) && !flag(no-cmm)
     cmm-sources:
       Counter.cmm
@@ -109,6 +128,8 @@
 
 library test-utils
   import: ghc-options
+  visibility:
+    private
   exposed-modules:
     TestUtils
   hs-source-dirs:
@@ -116,7 +137,7 @@
   build-depends:
     , QuickCheck
     , async >= 2
-    , base >= 4.14
+    , base >= 4.12 && < 5
 
 test-suite test
   import: ghc-options
@@ -129,10 +150,10 @@
   build-depends:
     , QuickCheck
     , atomic-counter
-    , base >= 4.14
+    , base >= 4.12
     , tasty
     , tasty-quickcheck
-    , test-utils
+    , atomic-counter:test-utils
   ghc-options:
     -rtsopts
     -threaded
@@ -150,13 +171,13 @@
   build-depends:
     , QuickCheck
     , atomic-counter
-    , base >= 4.14
+    , base >= 4.12
     , primitive
     , stm
     , tasty >= 1.4.2
     , tasty-bench >= 0.3.4
     , tasty-quickcheck
-    , test-utils
+    , atomic-counter:test-utils
   ghc-options:
     -rtsopts
     -threaded
diff --git a/bench/BenchMain.hs b/bench/BenchMain.hs
--- a/bench/BenchMain.hs
+++ b/bench/BenchMain.hs
@@ -8,7 +8,6 @@
 
 {-# LANGUAGE BangPatterns        #-}
 {-# LANGUAGE CPP                 #-}
-{-# LANGUAGE ImportQualifiedPost #-}
 {-# LANGUAGE MagicHash           #-}
 {-# LANGUAGE NamedFieldPuns      #-}
 {-# LANGUAGE UnboxedTuples       #-}
@@ -27,9 +26,9 @@
 import Test.Tasty hiding (defaultMain)
 import Test.Tasty.Bench
 import Test.Tasty.Patterns.Printer
-import Test.Tasty.QuickCheck qualified as QC
+import qualified Test.Tasty.QuickCheck as QC
 
-import Control.Concurrent.Counter.Lifted.IO qualified as C
+import qualified Control.Concurrent.Counter.Lifted.IO as C
 
 import TestUtils
 
diff --git a/src/Control/Concurrent/Counter.hs b/src/Control/Concurrent/Counter.hs
--- a/src/Control/Concurrent/Counter.hs
+++ b/src/Control/Concurrent/Counter.hs
@@ -10,7 +10,27 @@
 ----------------------------------------------------------------------------
 
 module Control.Concurrent.Counter
-  ( module Control.Concurrent.Counter.Lifted.IO
+  ( Counter
+
+  -- * Create
+  , new
+
+  -- * Read/write
+  , get
+  , set
+  , cas
+
+  -- * Arithmetic operations
+  , add
+  , sub
+
+  -- * Bitwise operations
+  , and
+  , or
+  , xor
+  , nand
   ) where
+
+import Prelude hiding (and, or)
 
 import Control.Concurrent.Counter.Lifted.IO
diff --git a/src/Control/Concurrent/Counter/Lifted/IO.hs b/src/Control/Concurrent/Counter/Lifted/IO.hs
--- a/src/Control/Concurrent/Counter/Lifted/IO.hs
+++ b/src/Control/Concurrent/Counter/Lifted/IO.hs
@@ -9,8 +9,7 @@
 -- operate in the 'IO' monad.
 ----------------------------------------------------------------------------
 
-{-# LANGUAGE ImportQualifiedPost #-}
-{-# LANGUAGE TypeApplications    #-}
+{-# LANGUAGE TypeApplications #-}
 
 module Control.Concurrent.Counter.Lifted.IO
   ( Counter
@@ -41,8 +40,7 @@
 import GHC.IO
 import GHC.ST
 
-import Control.Concurrent.Counter.Lifted.ST qualified as Lifted
-
+import qualified Control.Concurrent.Counter.Lifted.ST as Lifted
 
 -- | Memory location that supports select few atomic operations.
 --
diff --git a/src/Control/Concurrent/Counter/Lifted/ST.hs b/src/Control/Concurrent/Counter/Lifted/ST.hs
--- a/src/Control/Concurrent/Counter/Lifted/ST.hs
+++ b/src/Control/Concurrent/Counter/Lifted/ST.hs
@@ -10,9 +10,8 @@
 -- same operation (terms and conditions apply).
 ----------------------------------------------------------------------------
 
-{-# LANGUAGE ImportQualifiedPost #-}
-{-# LANGUAGE MagicHash           #-}
-{-# LANGUAGE UnboxedTuples       #-}
+{-# LANGUAGE MagicHash     #-}
+{-# LANGUAGE UnboxedTuples #-}
 
 module Control.Concurrent.Counter.Lifted.ST
   ( Counter
@@ -41,8 +40,7 @@
 import GHC.Exts (Int(..), Int#, State#)
 import GHC.ST
 
-import Control.Concurrent.Counter.Unlifted qualified as Unlifted
-
+import qualified Control.Concurrent.Counter.Unlifted as Unlifted
 
 -- | Memory location that supports select few atomic operations.
 --
diff --git a/src/Control/Concurrent/Counter/Unlifted.hs b/src/Control/Concurrent/Counter/Unlifted.hs
--- a/src/Control/Concurrent/Counter/Unlifted.hs
+++ b/src/Control/Concurrent/Counter/Unlifted.hs
@@ -22,8 +22,11 @@
 {-# LANGUAGE MagicHash            #-}
 {-# LANGUAGE UnboxedTuples        #-}
 {-# LANGUAGE UnliftedFFITypes     #-}
-{-# LANGUAGE UnliftedNewtypes     #-}
 
+#if __GLASGOW_HASKELL__ >= 810
+{-# LANGUAGE UnliftedNewtypes #-}
+#endif
+
 module Control.Concurrent.Counter.Unlifted
   ( Counter
 
@@ -113,10 +116,18 @@
 sameCounter (Counter x) (Counter y) =
   isTrue# (reallyUnsafePtrEquality# x y)
 
-#else
+#endif
 
+#if !(defined(USE_CMM) && SIZEOF_HSINT == 8)
+
 -- | Memory location that supports select few atomic operations.
+#if __GLASGOW_HASKELL__ >= 810
 newtype Counter s = Counter (MutableByteArray# s)
+#endif
+
+#if !(__GLASGOW_HASKELL__ >= 810)
+data Counter s = Counter (MutableByteArray# s)
+#endif
 
 {-# INLINE new #-}
 -- | Create new counter with initial value.
diff --git a/test/TestMain.hs b/test/TestMain.hs
--- a/test/TestMain.hs
+++ b/test/TestMain.hs
@@ -7,7 +7,6 @@
 ----------------------------------------------------------------------------
 
 {-# LANGUAGE BangPatterns        #-}
-{-# LANGUAGE ImportQualifiedPost #-}
 {-# LANGUAGE NamedFieldPuns      #-}
 
 module TestMain (main) where
@@ -18,9 +17,9 @@
 import Data.Semigroup
 import Test.QuickCheck
 import Test.Tasty
-import Test.Tasty.QuickCheck qualified as QC
+import qualified Test.Tasty.QuickCheck as QC
 
-import Control.Concurrent.Counter.Lifted.IO qualified as C
+import qualified Control.Concurrent.Counter.Lifted.IO as C
 
 import TestUtils
 
