diff --git a/examples/examples.hs b/examples/examples.hs
--- a/examples/examples.hs
+++ b/examples/examples.hs
@@ -14,7 +14,6 @@
 module Main where
 
 import Readme.Lhs
-import Formatting
 import Options.Generic
 import Perf
 import Perf.Analysis
@@ -184,11 +183,11 @@
       [ ["pre warmup", show prewarmup]
       , ["one tick_", show onetick]
       , ["next 10", show ticks']
-      , ["average over one million", sformat (fixed 2) avticks]
-      , ["99.999% perc", sformat commas (floor tick99999 :: Integer)]
-      , ["99.9% perc", sformat (fixed 2) tick999]
-      , ["99th perc", sformat (fixed 2) tick99]
-      , ["40th perc", sformat (fixed 2) tick40]
+      , ["average over one million", fixed 2 avticks]
+      , ["99.999% perc", commas 0 tick99999]
+      , ["99.9% perc", fixed 2 tick999]
+      , ["99th perc", fixed 2 tick99]
+      , ["40th perc", fixed 2 tick40]
       , ["[min, 20th, .. 80th, max]",
          Text.intercalate " " (formatF 4 <$> qticks)]
       ]
diff --git a/perf-analysis.cabal b/perf-analysis.cabal
--- a/perf-analysis.cabal
+++ b/perf-analysis.cabal
@@ -1,5 +1,6 @@
+cabal-version:  3.0
 name:           perf-analysis
-version:        0.2.0.0
+version:        0.3.0
 synopsis:       analysis example using perf
 description:     Analytical tools to use with perf. 
 category:       performance
@@ -8,10 +9,9 @@
 author:         Tony Day
 maintainer:     tonyday567@gmail.com
 copyright:      Tony Day
-license:        BSD3
+license:        BSD-3-Clause
 license-file:   LICENSE
 build-type:     Simple
-cabal-version:  2.0
 
 source-repository head
   type: git
@@ -25,13 +25,13 @@
       src
   build-depends:
       base >=4.7 && <5
-    , formatting
-    , perf >=0.4.1.0
-    , protolude
+    , perf >=0.4.1.0 && < 0.7
+    , protolude >= 0.3 && < 0.4
     , scientific
     , tdigest
     , text
-    , readme-lhs
+    , text-format
+    , readme-lhs >= 0.6 && < 0.7
   default-language: Haskell2010
 
 executable perf-examples
@@ -43,12 +43,11 @@
       base >=4.7 && <5
     , containers
     , deepseq
-    , formatting
     , optparse-generic
-    , perf >=0.4.1.0
+    , perf
     , perf-analysis
-    , protolude
+    , protolude >= 0.3 && < 0.4
     , text
     , vector
-    , readme-lhs
+    , readme-lhs >= 0.6 && < 0.7
   default-language: Haskell2010
diff --git a/src/Perf/Analysis.hs b/src/Perf/Analysis.hs
--- a/src/Perf/Analysis.hs
+++ b/src/Perf/Analysis.hs
@@ -8,10 +8,12 @@
 
 import Data.Scientific
 import Data.TDigest
-import Formatting
 import Perf
 import Protolude
 import Readme.Lhs hiding (Format)
+import qualified Data.Text as Text
+import qualified Data.Text.Format as Text
+import Data.Text.Lazy.Builder (toLazyText)
 
 -- | compute deciles
 --
@@ -36,10 +38,31 @@
 percentile :: (Functor f, Foldable f, Integral a) => Double -> f a -> Double
 percentile p xs = fromMaybe 0 $ quantile p (tdigest (fromIntegral <$> xs) :: TDigest 25)
 
+-- | fixed precision
+prec :: (Real a) => Int -> a -> Text
+prec n x = toStrict $ toLazyText $ Text.prec n x
+
+-- | fixed
+fixed :: (Real a) => Int -> a -> Text
+fixed n x = toStrict $ toLazyText $ Text.fixed n x
+
 -- | fixed precision for a Scientific
-prec :: Int -> Format r (Scientific -> r)
-prec n = scifmt Exponent (Just n)
+sciprec :: Int -> Scientific -> Text
+sciprec n x = Text.pack $ formatScientific Exponent (Just n) x
 
+commas :: (RealFrac a) => Int -> a -> Text
+commas n a
+  | a < 1000 = fixed n a
+  | otherwise = go (floor a) ""
+  where
+    go :: Int -> Text -> Text
+    go x t
+      | x < 0 = "-" <> go (- x) ""
+      | x < 1000 = Text.pack (show x) <> t
+      | otherwise =
+        let (d, m) = divMod x 1000
+         in go d ("," <> Text.pack (show m))
+
 -- | convert an integral to a Scientific
 --
 -- >>> sformat (left 8 ' ' %. prec 1) (int2Sci 1000)
@@ -59,15 +82,15 @@
 
 -- | format an Integral as a Scientific with a precision
 formatI :: (Integral a) => Int -> a -> Text
-formatI p x = sformat (prec p) (int2Sci x)
+formatI p x = sciprec p $ int2Sci x
 
 -- | format a Float as a Scientific with a precision
 formatF :: (RealFloat a) => Int -> a -> Text
-formatF p x = sformat (prec p) (fromFloatDigits x)
+formatF p x = sciprec p (fromFloatDigits x)
 
 -- | format a Float as a Scientific with a precision
 formatFixed :: (RealFloat a) => Int -> a -> Text
-formatFixed p x = sformat (fixed p) (fromFloatDigits x)
+formatFixed p x = toStrict $ toLazyText $ Text.fixed p (fromFloatDigits x)
 
 -- | format the first few results, the median and average
 formatRun :: (Integral a) => Text -> Int -> Int -> [a] -> [Text]
