diff --git a/source/library/Witch.hs b/source/library/Witch.hs
--- a/source/library/Witch.hs
+++ b/source/library/Witch.hs
@@ -8,6 +8,9 @@
 -- In typical usage, the functions that you will use most often are
 -- 'Witch.Utility.into' for conversions that always succeed and
 -- 'Witch.Utility.tryInto' for conversions that sometimes fail.
+--
+-- Please consider reading the blog post that announces this library:
+-- <https://taylor.fausak.me/2021/07/13/witch/>
 module Witch
   ( -- * Type classes
 
diff --git a/source/library/Witch/Encoding.hs b/source/library/Witch/Encoding.hs
new file mode 100644
--- /dev/null
+++ b/source/library/Witch/Encoding.hs
@@ -0,0 +1,11 @@
+{-# LANGUAGE DataKinds #-}
+
+module Witch.Encoding where
+
+import qualified Data.Tagged as Tagged
+
+-- | <https://en.wikipedia.org/wiki/ISO/IEC_8859-1>
+type ISO_8859_1 = Tagged.Tagged "ISO-8859-1"
+
+-- | <https://en.wikipedia.org/wiki/UTF-8>
+type UTF_8 = Tagged.Tagged "UTF-8"
diff --git a/source/library/Witch/Instances.hs b/source/library/Witch/Instances.hs
--- a/source/library/Witch/Instances.hs
+++ b/source/library/Witch/Instances.hs
@@ -1,4 +1,3 @@
-{-# LANGUAGE DataKinds #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE PolyKinds #-}
@@ -9,10 +8,14 @@
 module Witch.Instances where
 
 import qualified Control.Exception as Exception
+import qualified Control.Monad as Monad
 import qualified Data.Bits as Bits
 import qualified Data.ByteString as ByteString
+import qualified Data.ByteString.Char8 as Char8
 import qualified Data.ByteString.Lazy as LazyByteString
+import qualified Data.ByteString.Lazy.Char8 as LazyChar8
 import qualified Data.ByteString.Short as ShortByteString
+import qualified Data.Char as Char
 import qualified Data.Complex as Complex
 import qualified Data.Fixed as Fixed
 import qualified Data.Foldable as Foldable
@@ -38,6 +41,7 @@
 import qualified GHC.Float as Float
 import qualified Numeric
 import qualified Numeric.Natural as Natural
+import qualified Witch.Encoding as Encoding
 import qualified Witch.From as From
 import qualified Witch.TryFrom as TryFrom
 import qualified Witch.TryFromException as TryFromException
@@ -1039,24 +1043,6 @@
 instance From.From ByteString.ByteString ShortByteString.ShortByteString where
   from = ShortByteString.toShort
 
--- | Uses 'Text.decodeUtf8''.
-instance TryFrom.TryFrom (Tagged.Tagged "UTF-8" ByteString.ByteString) Text.Text where
-  tryFrom = Utility.eitherTryFrom $ Text.decodeUtf8' . From.from
-
--- | Converts via 'Text.Text'.
-instance TryFrom.TryFrom (Tagged.Tagged "UTF-8" ByteString.ByteString) LazyText.Text where
-  tryFrom =
-    Utility.eitherTryFrom $
-      fmap (Utility.into @LazyText.Text)
-        . Utility.tryInto @Text.Text
-
--- | Converts via 'Text.Text'.
-instance TryFrom.TryFrom (Tagged.Tagged "UTF-8" ByteString.ByteString) String where
-  tryFrom =
-    Utility.eitherTryFrom $
-      fmap (Utility.into @String)
-        . Utility.tryInto @Text.Text
-
 -- LazyByteString
 
 -- | Uses 'LazyByteString.pack'.
@@ -1071,24 +1057,6 @@
 instance From.From LazyByteString.ByteString ByteString.ByteString where
   from = LazyByteString.toStrict
 
--- | Uses 'LazyText.decodeUtf8''.
-instance TryFrom.TryFrom (Tagged.Tagged "UTF-8" LazyByteString.ByteString) LazyText.Text where
-  tryFrom = Utility.eitherTryFrom $ LazyText.decodeUtf8' . From.from
-
--- | Converts via 'LazyText.Text'.
-instance TryFrom.TryFrom (Tagged.Tagged "UTF-8" LazyByteString.ByteString) Text.Text where
-  tryFrom =
-    Utility.eitherTryFrom $
-      fmap (Utility.into @Text.Text)
-        . Utility.tryInto @LazyText.Text
-
--- | Converts via 'LazyText.Text'.
-instance TryFrom.TryFrom (Tagged.Tagged "UTF-8" LazyByteString.ByteString) String where
-  tryFrom =
-    Utility.eitherTryFrom $
-      fmap (Utility.into @String)
-        . Utility.tryInto @LazyText.Text
-
 -- ShortByteString
 
 -- | Uses 'ShortByteString.pack'.
@@ -1109,28 +1077,12 @@
 instance From.From Text.Text LazyText.Text where
   from = LazyText.fromStrict
 
--- | Uses 'Text.encodeUtf8'.
-instance From.From Text.Text (Tagged.Tagged "UTF-8" ByteString.ByteString) where
-  from = From.from . Text.encodeUtf8
-
--- | Converts via 'ByteString.ByteString'.
-instance From.From Text.Text (Tagged.Tagged "UTF-8" LazyByteString.ByteString) where
-  from = fmap From.from . Utility.into @(Tagged.Tagged "UTF-8" ByteString.ByteString)
-
 -- LazyText
 
 -- | Uses 'LazyText.toStrict'.
 instance From.From LazyText.Text Text.Text where
   from = LazyText.toStrict
 
--- | Uses 'LazyText.encodeUtf8'.
-instance From.From LazyText.Text (Tagged.Tagged "UTF-8" LazyByteString.ByteString) where
-  from = From.from . LazyText.encodeUtf8
-
--- | Converts via 'LazyByteString.ByteString'.
-instance From.From LazyText.Text (Tagged.Tagged "UTF-8" ByteString.ByteString) where
-  from = fmap From.from . Utility.into @(Tagged.Tagged "UTF-8" LazyByteString.ByteString)
-
 -- String
 
 -- | Uses 'Text.pack'. Some 'Char' values cannot be represented in 'Text.Text'
@@ -1151,14 +1103,6 @@
 instance From.From LazyText.Text String where
   from = LazyText.unpack
 
--- | Converts via 'Text.Text'.
-instance From.From String (Tagged.Tagged "UTF-8" ByteString.ByteString) where
-  from = Utility.via @Text.Text
-
--- | Converts via 'LazyText.Text'.
-instance From.From String (Tagged.Tagged "UTF-8" LazyByteString.ByteString) where
-  from = Utility.via @LazyText.Text
-
 -- TryFromException
 
 -- | Uses @coerce@.
@@ -1285,6 +1229,110 @@
 
 -- | Uses @coerce@. Essentially the same as 'Tagged.retag'.
 instance From.From (Tagged.Tagged t a) (Tagged.Tagged u a)
+
+-- ISO-8859-1
+
+-- | Uses 'Text.decodeLatin1'.
+instance From.From (Encoding.ISO_8859_1 ByteString.ByteString) Text.Text where
+  from = Text.decodeLatin1 . From.from
+
+-- | Converts via 'Text.Text'.
+instance From.From (Encoding.ISO_8859_1 ByteString.ByteString) LazyText.Text where
+  from = Utility.via @Text.Text
+
+-- | Converts via 'Text.Text'.
+instance From.From (Encoding.ISO_8859_1 ByteString.ByteString) String where
+  from = Utility.via @Text.Text
+
+-- | Uses 'LazyText.decodeLatin1'.
+instance From.From (Encoding.ISO_8859_1 LazyByteString.ByteString) LazyText.Text where
+  from = LazyText.decodeLatin1 . From.from
+
+-- | Converts via 'LazyText.Text'.
+instance From.From (Encoding.ISO_8859_1 LazyByteString.ByteString) Text.Text where
+  from = Utility.via @LazyText.Text
+
+-- | Converts via 'LazyText.Text'.
+instance From.From (Encoding.ISO_8859_1 LazyByteString.ByteString) String where
+  from = Utility.via @LazyText.Text
+
+-- | Converts via 'String'.
+instance TryFrom.TryFrom Text.Text (Encoding.ISO_8859_1 ByteString.ByteString) where
+  tryFrom = Utility.eitherTryFrom $ TryFrom.tryFrom . Utility.into @String
+
+-- | Converts via 'String'.
+instance TryFrom.TryFrom Text.Text (Encoding.ISO_8859_1 LazyByteString.ByteString) where
+  tryFrom = Utility.eitherTryFrom $ TryFrom.tryFrom . Utility.into @String
+
+-- | Converts via 'String'.
+instance TryFrom.TryFrom LazyText.Text (Encoding.ISO_8859_1 LazyByteString.ByteString) where
+  tryFrom = Utility.eitherTryFrom $ TryFrom.tryFrom . Utility.into @String
+
+-- | Converts via 'String'.
+instance TryFrom.TryFrom LazyText.Text (Encoding.ISO_8859_1 ByteString.ByteString) where
+  tryFrom = Utility.eitherTryFrom $ TryFrom.tryFrom . Utility.into @String
+
+-- | Uses 'Char8.pack' when each character 'Char.isLatin1'.
+instance TryFrom.TryFrom String (Encoding.ISO_8859_1 ByteString.ByteString) where
+  tryFrom = Utility.maybeTryFrom $ \string -> do
+    Monad.guard $ all Char.isLatin1 string
+    pure . From.from $ Char8.pack string
+
+-- | Uses 'LazyChar8.pack' when each character 'Char.isLatin1'.
+instance TryFrom.TryFrom String (Encoding.ISO_8859_1 LazyByteString.ByteString) where
+  tryFrom = Utility.maybeTryFrom $ \string -> do
+    Monad.guard $ all Char.isLatin1 string
+    pure . From.from $ LazyChar8.pack string
+
+-- UTF-8
+
+-- | Uses 'Text.decodeUtf8''.
+instance TryFrom.TryFrom (Encoding.UTF_8 ByteString.ByteString) Text.Text where
+  tryFrom = Utility.eitherTryFrom $ Text.decodeUtf8' . From.from
+
+-- | Converts via 'Text.Text'.
+instance TryFrom.TryFrom (Encoding.UTF_8 ByteString.ByteString) LazyText.Text where
+  tryFrom = Utility.eitherTryFrom $ fmap (Utility.into @LazyText.Text) . Utility.tryInto @Text.Text
+
+-- | Converts via 'Text.Text'.
+instance TryFrom.TryFrom (Encoding.UTF_8 ByteString.ByteString) String where
+  tryFrom = Utility.eitherTryFrom $ fmap (Utility.into @String) . Utility.tryInto @Text.Text
+
+-- | Uses 'LazyText.decodeUtf8''.
+instance TryFrom.TryFrom (Encoding.UTF_8 LazyByteString.ByteString) LazyText.Text where
+  tryFrom = Utility.eitherTryFrom $ LazyText.decodeUtf8' . From.from
+
+-- | Converts via 'LazyText.Text'.
+instance TryFrom.TryFrom (Encoding.UTF_8 LazyByteString.ByteString) Text.Text where
+  tryFrom = Utility.eitherTryFrom $ fmap (Utility.into @Text.Text) . Utility.tryInto @LazyText.Text
+
+-- | Converts via 'LazyText.Text'.
+instance TryFrom.TryFrom (Encoding.UTF_8 LazyByteString.ByteString) String where
+  tryFrom = Utility.eitherTryFrom $ fmap (Utility.into @String) . Utility.tryInto @LazyText.Text
+
+-- | Uses 'Text.encodeUtf8'.
+instance From.From Text.Text (Encoding.UTF_8 ByteString.ByteString) where
+  from = From.from . Text.encodeUtf8
+
+-- | Converts via 'ByteString.ByteString'.
+instance From.From Text.Text (Encoding.UTF_8 LazyByteString.ByteString) where
+  from = fmap From.from . Utility.into @(Encoding.UTF_8 ByteString.ByteString)
+
+-- | Uses 'LazyText.encodeUtf8'.
+instance From.From LazyText.Text (Encoding.UTF_8 LazyByteString.ByteString) where
+  from = From.from . LazyText.encodeUtf8
+
+-- | Converts via 'LazyByteString.ByteString'.
+instance From.From LazyText.Text (Encoding.UTF_8 ByteString.ByteString) where
+  from = fmap From.from . Utility.into @(Encoding.UTF_8 LazyByteString.ByteString)
+
+-- | Converts via 'Text.Text'.
+instance From.From String (Encoding.UTF_8 ByteString.ByteString) where
+  from = Utility.via @Text.Text
+
+-- | Converts via 'LazyText.Text'.
+instance From.From String (Encoding.UTF_8 LazyByteString.ByteString) where
+  from = Utility.via @LazyText.Text
 
 --
 
diff --git a/source/test-suite/Main.hs b/source/test-suite/Main.hs
--- a/source/test-suite/Main.hs
+++ b/source/test-suite/Main.hs
@@ -33,6 +33,7 @@
 import qualified Numeric.Natural as Natural
 import qualified Test.HUnit as HUnit
 import qualified Witch
+import qualified Witch.Encoding as Encoding
 
 main :: IO ()
 main = HUnit.runTestTTAndExit $ specToTest spec
@@ -1800,27 +1801,6 @@
         f (ByteString.pack [0x00]) `shouldBe` ShortByteString.pack [0x00]
         f (ByteString.pack [0x0f, 0xf0]) `shouldBe` ShortByteString.pack [0x0f, 0xf0]
 
-    describe "TryFrom ByteString Text" $ do
-      let f = hush . Witch.tryFrom @(Tagged.Tagged "UTF-8" ByteString.ByteString) @Text.Text
-      it "works" $ do
-        f (Tagged.Tagged (ByteString.pack [])) `shouldBe` Just (Text.pack "")
-        f (Tagged.Tagged (ByteString.pack [0x61])) `shouldBe` Just (Text.pack "a")
-        f (Tagged.Tagged (ByteString.pack [0xff])) `shouldBe` Nothing
-
-    describe "TryFrom ByteString LazyText" $ do
-      let f = hush . Witch.tryFrom @(Tagged.Tagged "UTF-8" ByteString.ByteString) @LazyText.Text
-      it "works" $ do
-        f (Tagged.Tagged (ByteString.pack [])) `shouldBe` Just (LazyText.pack "")
-        f (Tagged.Tagged (ByteString.pack [0x61])) `shouldBe` Just (LazyText.pack "a")
-        f (Tagged.Tagged (ByteString.pack [0xff])) `shouldBe` Nothing
-
-    describe "TryFrom ByteString String" $ do
-      let f = hush . Witch.tryFrom @(Tagged.Tagged "UTF-8" ByteString.ByteString) @String
-      it "works" $ do
-        f (Tagged.Tagged (ByteString.pack [])) `shouldBe` Just ""
-        f (Tagged.Tagged (ByteString.pack [0x61])) `shouldBe` Just "a"
-        f (Tagged.Tagged (ByteString.pack [0xff])) `shouldBe` Nothing
-
     describe "From [Word8] LazyByteString" $ do
       let f = Witch.from @[Word.Word8] @LazyByteString.ByteString
       it "works" $ do
@@ -1842,27 +1822,6 @@
         f (LazyByteString.pack [0x00]) `shouldBe` ByteString.pack [0x00]
         f (LazyByteString.pack [0x0f, 0xf0]) `shouldBe` ByteString.pack [0x0f, 0xf0]
 
-    describe "TryFrom LazyByteString LazyText" $ do
-      let f = hush . Witch.tryFrom @(Tagged.Tagged "UTF-8" LazyByteString.ByteString) @LazyText.Text
-      it "works" $ do
-        f (Tagged.Tagged (LazyByteString.pack [])) `shouldBe` Just (LazyText.pack "")
-        f (Tagged.Tagged (LazyByteString.pack [0x61])) `shouldBe` Just (LazyText.pack "a")
-        f (Tagged.Tagged (LazyByteString.pack [0xff])) `shouldBe` Nothing
-
-    describe "TryFrom LazyByteString Text" $ do
-      let f = hush . Witch.tryFrom @(Tagged.Tagged "UTF-8" LazyByteString.ByteString) @Text.Text
-      it "works" $ do
-        f (Tagged.Tagged (LazyByteString.pack [])) `shouldBe` Just (Text.pack "")
-        f (Tagged.Tagged (LazyByteString.pack [0x61])) `shouldBe` Just (Text.pack "a")
-        f (Tagged.Tagged (LazyByteString.pack [0xff])) `shouldBe` Nothing
-
-    describe "TryFrom LazyByteString String" $ do
-      let f = hush . Witch.tryFrom @(Tagged.Tagged "UTF-8" LazyByteString.ByteString) @String
-      it "works" $ do
-        f (Tagged.Tagged (LazyByteString.pack [])) `shouldBe` Just ""
-        f (Tagged.Tagged (LazyByteString.pack [0x61])) `shouldBe` Just "a"
-        f (Tagged.Tagged (LazyByteString.pack [0xff])) `shouldBe` Nothing
-
     describe "From [Word8] ShortByteString" $ do
       let f = Witch.from @[Word.Word8] @ShortByteString.ShortByteString
       it "works" $ do
@@ -1891,18 +1850,6 @@
         f (Text.pack "a") `shouldBe` LazyText.pack "a"
         f (Text.pack "ab") `shouldBe` LazyText.pack "ab"
 
-    describe "From Text ByteString" $ do
-      let f = Witch.from @Text.Text @(Tagged.Tagged "UTF-8" ByteString.ByteString)
-      it "works" $ do
-        f (Text.pack "") `shouldBe` Tagged.Tagged (ByteString.pack [])
-        f (Text.pack "a") `shouldBe` Tagged.Tagged (ByteString.pack [0x61])
-
-    describe "From Text LazyByteString" $ do
-      let f = Witch.from @Text.Text @(Tagged.Tagged "UTF-8" LazyByteString.ByteString)
-      it "works" $ do
-        f (Text.pack "") `shouldBe` Tagged.Tagged (LazyByteString.pack [])
-        f (Text.pack "a") `shouldBe` Tagged.Tagged (LazyByteString.pack [0x61])
-
     describe "From LazyText Text" $ do
       let f = Witch.from @LazyText.Text @Text.Text
       it "works" $ do
@@ -1910,18 +1857,6 @@
         f (LazyText.pack "a") `shouldBe` Text.pack "a"
         f (LazyText.pack "ab") `shouldBe` Text.pack "ab"
 
-    describe "From LazyText LazyByteString" $ do
-      let f = Witch.from @LazyText.Text @(Tagged.Tagged "UTF-8" LazyByteString.ByteString)
-      it "works" $ do
-        f (LazyText.pack "") `shouldBe` Tagged.Tagged (LazyByteString.pack [])
-        f (LazyText.pack "a") `shouldBe` Tagged.Tagged (LazyByteString.pack [0x61])
-
-    describe "From LazyText ByteString" $ do
-      let f = Witch.from @LazyText.Text @(Tagged.Tagged "UTF-8" ByteString.ByteString)
-      it "works" $ do
-        f (LazyText.pack "") `shouldBe` Tagged.Tagged (ByteString.pack [])
-        f (LazyText.pack "a") `shouldBe` Tagged.Tagged (ByteString.pack [0x61])
-
     describe "From String Text" $ do
       let f = Witch.from @String @Text.Text
       it "works" $ do
@@ -1950,18 +1885,6 @@
         f (LazyText.pack "a") `shouldBe` "a"
         f (LazyText.pack "ab") `shouldBe` "ab"
 
-    describe "From String ByteString" $ do
-      let f = Witch.from @String @(Tagged.Tagged "UTF-8" ByteString.ByteString)
-      it "works" $ do
-        f "" `shouldBe` Tagged.Tagged (ByteString.pack [])
-        f "a" `shouldBe` Tagged.Tagged (ByteString.pack [0x61])
-
-    describe "From String LazyByteString" $ do
-      let f = Witch.from @String @(Tagged.Tagged "UTF-8" LazyByteString.ByteString)
-      it "works" $ do
-        f "" `shouldBe` Tagged.Tagged (LazyByteString.pack [])
-        f "a" `shouldBe` Tagged.Tagged (LazyByteString.pack [0x61])
-
     describe "From Integer Day" $ do
       let f = Witch.from @Integer @Time.Day
       it "works" $ do
@@ -2086,6 +2009,158 @@
       let f = Witch.from @(Tagged.Tagged "old" Bool) @(Tagged.Tagged "new" Bool)
       it "works" $ do
         f (Tagged.Tagged False) `shouldBe` Tagged.Tagged False
+
+    describe "From (ISO_8859_1 ByteString) Text" $ do
+      let f = Witch.from @(Encoding.ISO_8859_1 ByteString.ByteString) @Text.Text
+      it "works" $ do
+        f (Tagged.Tagged (ByteString.pack [0x61])) `shouldBe` Text.pack "a"
+
+    describe "From (ISO_8859_1 ByteString) LazyText" $ do
+      let f = Witch.from @(Encoding.ISO_8859_1 ByteString.ByteString) @LazyText.Text
+      it "works" $ do
+        f (Tagged.Tagged (ByteString.pack [0x61])) `shouldBe` LazyText.pack "a"
+
+    describe "From (ISO_8859_1 ByteString) String" $ do
+      let f = Witch.from @(Encoding.ISO_8859_1 ByteString.ByteString) @String
+      it "works" $ do
+        f (Tagged.Tagged (ByteString.pack [0x61])) `shouldBe` "a"
+
+    describe "From (ISO_8859_1 LazyByteString) LazyText" $ do
+      let f = Witch.from @(Encoding.ISO_8859_1 LazyByteString.ByteString) @LazyText.Text
+      it "works" $ do
+        f (Tagged.Tagged (LazyByteString.pack [0x61])) `shouldBe` LazyText.pack "a"
+
+    describe "From (ISO_8859_1 LazyByteString) Text" $ do
+      let f = Witch.from @(Encoding.ISO_8859_1 LazyByteString.ByteString) @Text.Text
+      it "works" $ do
+        f (Tagged.Tagged (LazyByteString.pack [0x61])) `shouldBe` Text.pack "a"
+
+    describe "From (ISO_8859_1 LazyByteString) String" $ do
+      let f = Witch.from @(Encoding.ISO_8859_1 LazyByteString.ByteString) @String
+      it "works" $ do
+        f (Tagged.Tagged (LazyByteString.pack [0x61])) `shouldBe` "a"
+
+    describe "TryFrom Text (ISO_8859_1 ByteString)" $ do
+      let f = hush . Witch.tryFrom @Text.Text @(Encoding.ISO_8859_1 ByteString.ByteString)
+      it "works" $ do
+        f (Text.pack "a") `shouldBe` Just (Tagged.Tagged $ ByteString.pack [0x61])
+        f (Text.pack "\x100") `shouldBe` Nothing
+
+    describe "TryFrom Text (ISO_8859_1 LazyByteString)" $ do
+      let f = hush . Witch.tryFrom @Text.Text @(Encoding.ISO_8859_1 LazyByteString.ByteString)
+      it "works" $ do
+        f (Text.pack "a") `shouldBe` Just (Tagged.Tagged $ LazyByteString.pack [0x61])
+        f (Text.pack "\x100") `shouldBe` Nothing
+
+    describe "TryFrom LazyText (ISO_8859_1 LazyByteString)" $ do
+      let f = hush . Witch.tryFrom @LazyText.Text @(Encoding.ISO_8859_1 LazyByteString.ByteString)
+      it "works" $ do
+        f (LazyText.pack "a") `shouldBe` Just (Tagged.Tagged $ LazyByteString.pack [0x61])
+        f (LazyText.pack "\x100") `shouldBe` Nothing
+
+    describe "TryFrom LazyText (ISO_8859_1 ByteString)" $ do
+      let f = hush . Witch.tryFrom @LazyText.Text @(Encoding.ISO_8859_1 ByteString.ByteString)
+      it "works" $ do
+        f (LazyText.pack "a") `shouldBe` Just (Tagged.Tagged $ ByteString.pack [0x61])
+        f (LazyText.pack "\x100") `shouldBe` Nothing
+
+    describe "TryFrom String (ISO_8859_1 ByteString)" $ do
+      let f = hush . Witch.tryFrom @String @(Encoding.ISO_8859_1 ByteString.ByteString)
+      it "works" $ do
+        f "a" `shouldBe` Just (Tagged.Tagged $ ByteString.pack [0x61])
+        f "\x100" `shouldBe` Nothing
+
+    describe "TryFrom String (ISO_8859_1 LazyByteString)" $ do
+      let f = hush . Witch.tryFrom @String @(Encoding.ISO_8859_1 LazyByteString.ByteString)
+      it "works" $ do
+        f "a" `shouldBe` Just (Tagged.Tagged $ LazyByteString.pack [0x61])
+        f "\x100" `shouldBe` Nothing
+
+    describe "TryFrom (UTF_8 ByteString) Text" $ do
+      let f = hush . Witch.tryFrom @(Encoding.UTF_8 ByteString.ByteString) @Text.Text
+      it "works" $ do
+        f (Tagged.Tagged (ByteString.pack [])) `shouldBe` Just (Text.pack "")
+        f (Tagged.Tagged (ByteString.pack [0x61])) `shouldBe` Just (Text.pack "a")
+        f (Tagged.Tagged (ByteString.pack [0xff])) `shouldBe` Nothing
+        f (Tagged.Tagged (ByteString.pack [0x24])) `shouldBe` Just (Text.pack "\x24")
+        f (Tagged.Tagged (ByteString.pack [0xc2, 0xa3])) `shouldBe` Just (Text.pack "\xa3")
+        f (Tagged.Tagged (ByteString.pack [0xe2, 0x82, 0xac])) `shouldBe` Just (Text.pack "\x20ac")
+        f (Tagged.Tagged (ByteString.pack [0xf0, 0x90, 0x8d, 0x88])) `shouldBe` Just (Text.pack "\x10348")
+
+    describe "TryFrom (UTF_8 ByteString) LazyText" $ do
+      let f = hush . Witch.tryFrom @(Encoding.UTF_8 ByteString.ByteString) @LazyText.Text
+      it "works" $ do
+        f (Tagged.Tagged (ByteString.pack [])) `shouldBe` Just (LazyText.pack "")
+        f (Tagged.Tagged (ByteString.pack [0x61])) `shouldBe` Just (LazyText.pack "a")
+        f (Tagged.Tagged (ByteString.pack [0xff])) `shouldBe` Nothing
+
+    describe "TryFrom (UTF_8 ByteString) String" $ do
+      let f = hush . Witch.tryFrom @(Encoding.UTF_8 ByteString.ByteString) @String
+      it "works" $ do
+        f (Tagged.Tagged (ByteString.pack [])) `shouldBe` Just ""
+        f (Tagged.Tagged (ByteString.pack [0x61])) `shouldBe` Just "a"
+        f (Tagged.Tagged (ByteString.pack [0xff])) `shouldBe` Nothing
+
+    describe "TryFrom (UTF_8 LazyByteString) LazyText" $ do
+      let f = hush . Witch.tryFrom @(Encoding.UTF_8 LazyByteString.ByteString) @LazyText.Text
+      it "works" $ do
+        f (Tagged.Tagged (LazyByteString.pack [])) `shouldBe` Just (LazyText.pack "")
+        f (Tagged.Tagged (LazyByteString.pack [0x61])) `shouldBe` Just (LazyText.pack "a")
+        f (Tagged.Tagged (LazyByteString.pack [0xff])) `shouldBe` Nothing
+
+    describe "TryFrom (UTF_8 LazyByteString) Text" $ do
+      let f = hush . Witch.tryFrom @(Encoding.UTF_8 LazyByteString.ByteString) @Text.Text
+      it "works" $ do
+        f (Tagged.Tagged (LazyByteString.pack [])) `shouldBe` Just (Text.pack "")
+        f (Tagged.Tagged (LazyByteString.pack [0x61])) `shouldBe` Just (Text.pack "a")
+        f (Tagged.Tagged (LazyByteString.pack [0xff])) `shouldBe` Nothing
+
+    describe "TryFrom (UTF_8 LazyByteString) String" $ do
+      let f = hush . Witch.tryFrom @(Encoding.UTF_8 LazyByteString.ByteString) @String
+      it "works" $ do
+        f (Tagged.Tagged (LazyByteString.pack [])) `shouldBe` Just ""
+        f (Tagged.Tagged (LazyByteString.pack [0x61])) `shouldBe` Just "a"
+        f (Tagged.Tagged (LazyByteString.pack [0xff])) `shouldBe` Nothing
+
+    describe "From Text (UTF_8 ByteString)" $ do
+      let f = Witch.from @Text.Text @(Encoding.UTF_8 ByteString.ByteString)
+      it "works" $ do
+        f (Text.pack "") `shouldBe` Tagged.Tagged (ByteString.pack [])
+        f (Text.pack "a") `shouldBe` Tagged.Tagged (ByteString.pack [0x61])
+        f (Text.pack "\x24") `shouldBe` Tagged.Tagged (ByteString.pack [0x24])
+        f (Text.pack "\xa3") `shouldBe` Tagged.Tagged (ByteString.pack [0xc2, 0xa3])
+        f (Text.pack "\x20ac") `shouldBe` Tagged.Tagged (ByteString.pack [0xe2, 0x82, 0xac])
+        f (Text.pack "\x10348") `shouldBe` Tagged.Tagged (ByteString.pack [0xf0, 0x90, 0x8d, 0x88])
+
+    describe "From Text (UTF_8 LazyByteString)" $ do
+      let f = Witch.from @Text.Text @(Encoding.UTF_8 LazyByteString.ByteString)
+      it "works" $ do
+        f (Text.pack "") `shouldBe` Tagged.Tagged (LazyByteString.pack [])
+        f (Text.pack "a") `shouldBe` Tagged.Tagged (LazyByteString.pack [0x61])
+
+    describe "From LazyText (UTF_8 LazyByteString)" $ do
+      let f = Witch.from @LazyText.Text @(Encoding.UTF_8 LazyByteString.ByteString)
+      it "works" $ do
+        f (LazyText.pack "") `shouldBe` Tagged.Tagged (LazyByteString.pack [])
+        f (LazyText.pack "a") `shouldBe` Tagged.Tagged (LazyByteString.pack [0x61])
+
+    describe "From LazyText (UTF_8 ByteString)" $ do
+      let f = Witch.from @LazyText.Text @(Encoding.UTF_8 ByteString.ByteString)
+      it "works" $ do
+        f (LazyText.pack "") `shouldBe` Tagged.Tagged (ByteString.pack [])
+        f (LazyText.pack "a") `shouldBe` Tagged.Tagged (ByteString.pack [0x61])
+
+    describe "From String (UTF_8 ByteString)" $ do
+      let f = Witch.from @String @(Encoding.UTF_8 ByteString.ByteString)
+      it "works" $ do
+        f "" `shouldBe` Tagged.Tagged (ByteString.pack [])
+        f "a" `shouldBe` Tagged.Tagged (ByteString.pack [0x61])
+
+    describe "From String (UTF_8 LazyByteString)" $ do
+      let f = Witch.from @String @(Encoding.UTF_8 LazyByteString.ByteString)
+      it "works" $ do
+        f "" `shouldBe` Tagged.Tagged (LazyByteString.pack [])
+        f "a" `shouldBe` Tagged.Tagged (LazyByteString.pack [0x61])
 
 newtype Age
   = Age Int.Int8
diff --git a/witch.cabal b/witch.cabal
--- a/witch.cabal
+++ b/witch.cabal
@@ -1,7 +1,7 @@
 cabal-version: 2.2
 
 name: witch
-version: 1.1.0.0
+version: 1.1.1.0
 synopsis: Convert values from one type into another.
 description: Witch converts values from one type into another.
 
@@ -76,6 +76,7 @@
     , template-haskell >= 2.12 && < 2.20
   exposed-modules:
     Witch
+    Witch.Encoding
     Witch.From
     Witch.Instances
     Witch.Lift
