diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Revision history for dns-patterns
 
+## 0.2.2 -- 2022-09-08
+
+* Support older bytestring versions
+
 ## 0.2.1 -- 2022-08-24
 
 * Export missing 'LabelPattern' and 'DomainPattern' constructors
diff --git a/dns-patterns.cabal b/dns-patterns.cabal
--- a/dns-patterns.cabal
+++ b/dns-patterns.cabal
@@ -1,6 +1,6 @@
 cabal-version:      3.0
 name:               dns-patterns
-version:            0.2.1
+version:            0.2.2
 author:             Victor Nawothnig
 maintainer:         Victor Nawothnig (dminuoso@icloud.com)
 copyright:          (c) 2022 Wobcom GmbH
@@ -20,7 +20,7 @@
     build-depends:    base ^>= { 4.12.0.0, 4.13.0.0, 4.14.1.0, 4.15.0.0 }
                     , attoparsec ^>= { 0.13.2.5, 0.14.4 }
                     , text ^>= { 1.2.4 }
-                    , bytestring ^>= { 0.11.3 }
+                    , bytestring ^>= { 0.10.0, 0.11.0 }
 
 library
     import:           all
diff --git a/lib/Network/DNS.hs b/lib/Network/DNS.hs
--- a/lib/Network/DNS.hs
+++ b/lib/Network/DNS.hs
@@ -33,6 +33,7 @@
   , unsafeMkDomainLabel
   , unsafeSingletonDomainLabel
   , foldCase
+  , foldCase_
   , foldCaseLabel
 
   -- * Parsing
@@ -110,7 +111,7 @@
 
 -- | Smart constructor for 'DomainLabel'
 mkDomainLabel :: BS.ShortByteString -> DomainLabel
-mkDomainLabel l = DomainLabel l (BS.map foldCase_ l)
+mkDomainLabel l = DomainLabel l (sbsMap foldCase_ l)
 
 -- | Unsafely construct a 'DomainLabel'. The argument must already be case-folded according to [RFC4343](https://datatracker.ietf.org/doc/html/rfc4343#section-3).
 unsafeMkDomainLabel :: BS.ShortByteString -> DomainLabel
@@ -119,7 +120,7 @@
 
 -- | Unsafely construct a 'DomainLabel' from a single Word8. The argument must already be case-folded according to [RFC4343](https://datatracker.ietf.org/doc/html/rfc4343#section-3).
 unsafeSingletonDomainLabel :: Word8 -> DomainLabel
-unsafeSingletonDomainLabel l = DomainLabel (BS.singleton l) (BS.singleton l)
+unsafeSingletonDomainLabel l = DomainLabel (sbsSingleton l) (sbsSingleton l)
 
 -- | Case-folding of a domain according to [RFC4343](https://datatracker.ietf.org/doc/html/rfc4343#section-3).
 -- Note 'Domain' will memoize a case-folded variant for 'Eq', 'Ord' and pretty printing already. This function is not useful to most.
diff --git a/lib/Network/DNS/Internal.hs b/lib/Network/DNS/Internal.hs
--- a/lib/Network/DNS/Internal.hs
+++ b/lib/Network/DNS/Internal.hs
@@ -1,3 +1,7 @@
+{-# LANGUAGE BangPatterns  #-}
+{-# LANGUAGE CPP           #-}
+{-# LANGUAGE MagicHash     #-}
+{-# LANGUAGE UnboxedTuples #-}
 -- |
 -- Module      : Network.DNS.Pattern.Internal
 -- Description : Internal DNS types and definitions
@@ -11,11 +15,23 @@
   , toDList
   , fromDList
   , singleton
+  , sbsMap
+  , sbsSingleton
   )
 
 where
 
 import           Data.Function (on)
+import           GHC.Word
+#if !MIN_VERSION_bytestring(0,11,3)
+import           Control.Monad.ST (runST)
+import           Data.ByteString.Short.Internal (ShortByteString(SBS))
+import           GHC.Exts (Int#, MutableByteArray#, indexWord8Array#,
+                           newByteArray#, unsafeFreezeByteArray#,
+                           writeWord8Array#, (+#))
+import           GHC.Int (Int(..))
+import           GHC.ST (ST(..))
+#endif
 
 import qualified Data.ByteString.Short as BS
 
@@ -60,5 +76,36 @@
   {-# INLINE mempty #-}
   mempty = DList id
 
+{-# INLINE sbsSingleton #-}
+sbsSingleton :: Word8 -> BS.ShortByteString
+#if MIN_VERSION_bytestring(0,11,3)
+sbsSingleton = BS.singleton
+#else
+sbsSingleton (W8# w) = runST $ ST $ \s1 ->
+  case newByteArray# 1# s1 of
+    (# s2, mba #) -> case writeWord8Array# mba 0# w s2 of
+          s3 -> case unsafeFreezeByteArray# mba s3 of
+             (# s4, ma #) -> (# s4, SBS ma #)
 
+#endif
 
+sbsMap :: (Word8 -> Word8) -> BS.ShortByteString -> BS.ShortByteString
+#if MIN_VERSION_bytestring(0,11,3)
+sbsMap = BS.map
+#else
+sbsMap m sbs@(SBS ba) = runST $ ST $ \s1 ->
+  case newByteArray# l# s1 of
+    (# s2, mba #) -> case go mba 0# l# of
+      ST f -> case f s2 of
+        (# s3, _ #) -> case unsafeFreezeByteArray# mba s3 of
+           (# s4, ma #) -> (# s4, SBS ma #)
+  where
+    !(I# l#) = BS.length sbs
+    go :: MutableByteArray# s -> Int# -> Int# -> ST s ()
+    go !mba !i !l
+      | I# i >= I# l = return ()
+      | otherwise = (ST $ \s ->
+          let !(W8# w') = m (W8# (indexWord8Array# ba i)) in
+          (# writeWord8Array# mba i w' s, () #)
+       ) >> go mba (i +# 1#) l
+#endif
diff --git a/lib/Network/DNS/Pattern.hs b/lib/Network/DNS/Pattern.hs
--- a/lib/Network/DNS/Pattern.hs
+++ b/lib/Network/DNS/Pattern.hs
@@ -21,8 +21,8 @@
 {-# LANGUAGE OverloadedStrings #-}
 module Network.DNS.Pattern
   ( -- * Pattern language
-    DomainPattern(..)
-  , LabelPattern(..)
+    DomainPattern
+  , LabelPattern
   , matchesPattern
   , patternWorksInside
   , labelMatchesPattern
