diff --git a/safe-coloured-text.cabal b/safe-coloured-text.cabal
--- a/safe-coloured-text.cabal
+++ b/safe-coloured-text.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           safe-coloured-text
-version:        0.0.0.0
+version:        0.1.0.0
 synopsis:       Safely output coloured text
 category:       User Interfaces
 homepage:       https://github.com/NorfairKing/safe-coloured-text#readme
@@ -34,6 +34,8 @@
   build-depends:
       base >=4.7 && <5
     , bytestring
-    , terminfo
     , text
+    , validity
+    , validity-bytestring
+    , validity-text
   default-language: Haskell2010
diff --git a/src/Text/Colour.hs b/src/Text/Colour.hs
--- a/src/Text/Colour.hs
+++ b/src/Text/Colour.hs
@@ -72,12 +72,8 @@
 
     -- * IO
     TerminalCapabilities (..),
-    getTerminalCapabilitiesFromEnv,
-    getTerminalCapabilitiesFromHandle,
 
     -- ** Outputting chunks directly
-    putChunks,
-    hPutChunks,
     putChunksWith,
     hPutChunksWith,
   )
@@ -87,22 +83,6 @@
 import System.IO
 import Text.Colour.Capabilities
 import Text.Colour.Chunk
-
--- | Print a list of chunks to 'stdout'.
---
--- This function will use 'getTerminalCapabilitiesHandle' on 'stdout'.
--- If you intend to use this function more than once, it is more efficient to use 'getTerminalCapabilitiesFromEnv' first and then use 'putChunksWith'.
-putChunks :: [Chunk] -> IO ()
-putChunks = hPutChunks stdout
-
--- | Print a list of chunks to the given 'Handle'
---
--- This function will use 'getTerminalCapabilitiesHandle' on the given handle.
--- If you intend to use this function more than once, it is more efficient to use 'getTerminalCapabilitiesHandle' first and then use 'hPutChunksWith'.
-hPutChunks :: Handle -> [Chunk] -> IO ()
-hPutChunks h cs = do
-  tc <- getTerminalCapabilitiesFromHandle h
-  hPutChunksWith tc h cs
 
 -- | Print a list of chunks to stdout with given 'TerminalCapabilities'.
 putChunksWith :: TerminalCapabilities -> [Chunk] -> IO ()
diff --git a/src/Text/Colour/Capabilities.hs b/src/Text/Colour/Capabilities.hs
--- a/src/Text/Colour/Capabilities.hs
+++ b/src/Text/Colour/Capabilities.hs
@@ -3,11 +3,7 @@
 
 module Text.Colour.Capabilities where
 
-import Control.Exception
 import GHC.Generics (Generic)
-import qualified System.Console.Terminfo as Terminfo
-import System.Environment (lookupEnv)
-import System.IO
 
 -- Note that the order of these constructors matters!
 data TerminalCapabilities
@@ -20,38 +16,3 @@
   | -- | All 24-bit colours
     With24BitColours
   deriving (Show, Eq, Ord, Generic)
-
--- | Try to detect how many colours the terminal can handle.
---
--- This is based on the @colors@ capability of the terminfo detected based on the @TERM@ environment variable.
--- If the terminal can handle 8-bit colours and also has the @COLORTERM@ environment variable set to @24bit@ or @truecolor@, then this function will return 'With24BitColours'.
-getTerminalCapabilitiesFromEnv :: IO TerminalCapabilities
-getTerminalCapabilitiesFromEnv = do
-  mTerm <- (Just <$> Terminfo.setupTermFromEnv) `catch` (\(_ :: Terminfo.SetupTermError) -> pure Nothing)
-  case mTerm of
-    Nothing -> pure WithoutColours
-    Just term -> do
-      -- To support 24-bit colour:
-      -- https://unix.stackexchange.com/questions/450365/check-if-terminal-supports-24-bit-true-color
-      mct <- lookupEnv "COLORTERM"
-      pure $ case mct of
-        Just "truecolor" -> With24BitColours
-        Just "24bit" -> With24BitColours
-        _ ->
-          case Terminfo.getCapability term (Terminfo.tiGetNum "colors") of
-            Nothing -> WithoutColours
-            Just c
-              | c > 256 -> With24BitColours
-              | c >= 256 -> With8BitColours
-              | c >= 8 -> With8Colours
-              | otherwise -> WithoutColours
-
--- | Try to detect how many colours a given handle can handle.
---
--- This function does the same as 'getTerminalCapabilitiesFromEnv' but returns 'WithoutColours' is not a terminal device.
-getTerminalCapabilitiesFromHandle :: Handle -> IO TerminalCapabilities
-getTerminalCapabilitiesFromHandle h = do
-  isTerm <- hIsTerminalDevice h
-  if isTerm
-    then getTerminalCapabilitiesFromEnv
-    else pure WithoutColours
diff --git a/src/Text/Colour/Chunk.hs b/src/Text/Colour/Chunk.hs
--- a/src/Text/Colour/Chunk.hs
+++ b/src/Text/Colour/Chunk.hs
@@ -12,6 +12,7 @@
 import Data.String
 import Data.Text (Text)
 import qualified Data.Text.Encoding as TE
+import Data.Validity
 import Data.Word
 import GHC.Generics (Generic)
 import Text.Colour.Capabilities
@@ -27,6 +28,8 @@
   }
   deriving (Show, Eq, Generic)
 
+instance Validity Chunk
+
 instance IsString Chunk where
   fromString = chunk . fromString
 
@@ -80,7 +83,7 @@
       chunkBackground >>= colourSGR tc Background
     ]
 
--- Turn a text into a plain chunk, without any styling
+-- | Turn a text into a plain chunk, without any styling
 chunk :: Text -> Chunk
 chunk t =
   Chunk
@@ -119,6 +122,8 @@
   | Colour8Bit !Word8 -- The 8-bit colour
   | Colour24Bit !Word8 !Word8 !Word8
   deriving (Show, Eq, Generic)
+
+instance Validity Colour
 
 colourSGR :: TerminalCapabilities -> ConsoleLayer -> Colour -> Maybe SGR
 colourSGR tc layer =
diff --git a/src/Text/Colour/Code.hs b/src/Text/Colour/Code.hs
--- a/src/Text/Colour/Code.hs
+++ b/src/Text/Colour/Code.hs
@@ -9,6 +9,9 @@
 import qualified Data.ByteString.Internal as SBI
 import qualified Data.ByteString.Lazy as LB
 import Data.List
+import Data.Validity
+import Data.Validity.ByteString ()
+import Data.Validity.Text ()
 import Data.Word
 import GHC.Generics (Generic)
 
@@ -26,6 +29,8 @@
   = SGR [SGR]
   deriving (Show, Eq, Generic)
 
+instance Validity CSI
+
 -- | Render a CSI directly to bytestring.
 -- You probably want to use 'renderCSI' instead.
 -- This is just for testing.
@@ -60,6 +65,8 @@
       !Word8 -- Blue
   deriving (Show, Eq, Generic)
 
+instance Validity SGR
+
 csiParamsToWords :: [Word8] -> Builder
 csiParamsToWords = mconcat . intersperse (SBB.word8 csiDelimiter) . map csiParamToWord
 
@@ -117,6 +124,8 @@
   | NoUnderline
   deriving (Show, Eq, Generic, Bounded, Enum)
 
+instance Validity Underlining
+
 -- | ANSI general console intensity: usually treated as setting the font style
 -- (e.g. 'BoldIntensity' causes text to be bold)
 data ConsoleIntensity
@@ -125,18 +134,24 @@
   | NormalIntensity
   deriving (Show, Eq, Generic, Bounded, Enum)
 
+instance Validity ConsoleIntensity
+
 -- | ANSI's standard colours come in two intensities
 data ColourIntensity
   = Dull
   | Bright
   deriving (Show, Eq, Generic, Enum, Bounded)
 
+instance Validity ColourIntensity
+
 -- | ANSI colours can be set on two different layers
 data ConsoleLayer
   = Foreground
   | Background
   deriving (Show, Eq, Generic, Enum, Bounded)
 
+instance Validity ConsoleLayer
+
 data TerminalColour
   = Black
   | Red
@@ -147,6 +162,8 @@
   | Cyan
   | White
   deriving (Show, Eq, Generic, Enum, Bounded)
+
+instance Validity TerminalColour
 
 terminalColourSGRParameter :: TerminalColour -> Word8
 terminalColourSGRParameter = \case
