diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+# 1.0.1.0
+
+* Backwards-compatible support for `bytestring ^>= 0.11` ([#15](https://github.com/haskell/base16-bytestring/pull/15)) 
+
 # 1.0.0.0
 
 * Merged omnibus PR doing a variety of things in ([#10](https://github.com/haskell/base16-bytestring/pull/10)):
diff --git a/Data/ByteString/Base16.hs b/Data/ByteString/Base16.hs
--- a/Data/ByteString/Base16.hs
+++ b/Data/ByteString/Base16.hs
@@ -25,19 +25,13 @@
 ) where
 
 import Data.ByteString (empty)
-import Data.ByteString.Base16.Internal
-import Data.ByteString.Internal
-
-import Foreign.ForeignPtr
-import Foreign.Ptr
+import Data.ByteString.Base16.Internal (encodeLoop, decodeLoop, lenientLoop, mkBS, withBS)
+import Data.ByteString.Internal (ByteString)
 
-import GHC.ForeignPtr
-#if __GLASGOW_HASKELL__ >= 702
-import System.IO.Unsafe (unsafeDupablePerformIO)
-#else
-import GHC.IO (unsafeDupablePerformIO)
-#endif
+import Foreign.ForeignPtr (withForeignPtr)
+import Foreign.Ptr (plusPtr)
 
+import GHC.ForeignPtr (mallocPlainForeignPtrBytes)
 
 -- | Encode a 'ByteString' value in base16 (i.e. hexadecimal).
 -- Encoded values will always have a length that is a multiple of 2.
@@ -47,14 +41,17 @@
 -- > encode "foo"  == "666f6f"
 --
 encode :: ByteString -> ByteString
-encode (PS sfp soff slen)
-    | slen > maxBound `div` 2 =
-      error "Data.ByteString.Base16.encode: input too long"
-    | otherwise = unsafeCreate (slen * 2) $ \dptr ->
-        withForeignPtr sfp $ \sptr ->
-          encodeLoop dptr
-          (sptr `plusPtr` soff)
-          (sptr `plusPtr` (soff + slen))
+encode bs = withBS bs go
+  where
+    go !sptr !slen
+      | slen > maxBound `div` 2 =
+        error "Data.ByteString.Base16.encode: input too long"
+      | otherwise = do
+          let l = slen * 2
+          dfp <- mallocPlainForeignPtrBytes l
+          withForeignPtr dfp $ \dptr ->
+            encodeLoop dptr sptr (sptr `plusPtr` slen)
+          return $ mkBS dfp l
 
 -- | Decode a base16-encoded 'ByteString' value.
 -- If errors are encountered during the decoding process,
@@ -70,19 +67,18 @@
 -- @since 1.0.0.0
 --
 decode :: ByteString -> Either String ByteString
-decode (PS sfp soff slen)
-    | slen == 0 = Right empty
-    | r /= 0 = Left "invalid bytestring size"
-    | otherwise = unsafeDupablePerformIO $ do
-      dfp <- mallocPlainForeignPtrBytes q
-      withForeignPtr dfp $ \dptr ->
-        withForeignPtr sfp $ \sptr ->
-          decodeLoop dfp dptr
-          (plusPtr sptr soff)
-          (plusPtr sptr (soff + slen))
+decode bs = withBS bs go
   where
-    !q = slen `quot` 2
-    !r = slen `rem` 2
+    go !sptr !slen
+      | slen == 0 = return $ Right empty
+      | r /= 0 = return $ Left "invalid bytestring size"
+      | otherwise = do
+        dfp <- mallocPlainForeignPtrBytes q
+        withForeignPtr dfp $ \dptr ->
+          decodeLoop dfp dptr sptr (plusPtr sptr slen)
+      where
+        !q = slen `quot` 2
+        !r = slen `rem` 2
 
 -- | Decode a Base16-encoded 'ByteString' value leniently, using a
 -- strategy that never fails.
@@ -99,14 +95,13 @@
 -- @since 1.0.0.0
 --
 decodeLenient :: ByteString -> ByteString
-decodeLenient (PS !sfp !soff !slen)
-    | slen == 0 = empty
-    | otherwise = unsafeDupablePerformIO $ do
-      dfp <- mallocPlainForeignPtrBytes (q * 2)
-      withForeignPtr dfp $ \dptr ->
-        withForeignPtr sfp $ \sptr ->
-          lenientLoop dfp dptr
-          (plusPtr sptr soff)
-          (plusPtr sptr (soff + slen))
+decodeLenient bs = withBS bs go
   where
-    !q = slen `quot` 2
+    go !sptr !slen
+      | slen == 0 = return empty
+      | otherwise = do
+        dfp <- mallocPlainForeignPtrBytes (q * 2)
+        withForeignPtr dfp $ \dptr ->
+          lenientLoop dfp dptr sptr (plusPtr sptr slen)
+      where
+        !q = slen `quot` 2
diff --git a/Data/ByteString/Base16/Internal.hs b/Data/ByteString/Base16/Internal.hs
--- a/Data/ByteString/Base16/Internal.hs
+++ b/Data/ByteString/Base16/Internal.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE MagicHash #-}
 module Data.ByteString.Base16.Internal
 ( -- * worker loops
@@ -10,6 +11,8 @@
 , aix
 , reChunk
 , unsafeShiftR
+, withBS
+, mkBS
 ) where
 
 
@@ -18,15 +21,20 @@
 import Data.ByteString.Internal (ByteString(..))
 import Data.Char (ord)
 
-import Foreign.ForeignPtr
-import Foreign.Ptr
-import Foreign.Storable
+import Foreign.ForeignPtr (ForeignPtr, withForeignPtr)
+import Foreign.Ptr (Ptr, minusPtr, plusPtr)
+import Foreign.Storable (Storable(poke, peek))
 
-import GHC.Word
-import GHC.Exts
-  (Int(I#), Addr#, indexWord8OffAddr#, word2Int#, uncheckedShiftRL#)
+import GHC.Word (Word8(..))
+import GHC.Exts (Int(I#), Addr#, indexWord8OffAddr#, word2Int#, uncheckedShiftRL#)
 
+#if __GLASGOW_HASKELL__ >= 702
+import System.IO.Unsafe (unsafeDupablePerformIO)
+#else
+import GHC.IO (unsafeDupablePerformIO)
+#endif
 
+
 -- ------------------------------------------------------------------ --
 -- Loops
 
@@ -67,7 +75,7 @@
     !hi = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x20\x30\x40\x50\x60\x70\x80\x90\xff\xff\xff\xff\xff\xff\xff\xa0\xb0\xc0\xd0\xe0\xf0\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xa0\xb0\xc0\xd0\xe0\xf0\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#
 
     go !dst !src
-      | src == end = return (Right (PS dfp 0 (dst `minusPtr` dptr)))
+      | src == end = return (Right (mkBS dfp (dst `minusPtr` dptr)))
       | otherwise = do
         !x <- peek src
         !y <- peek (plusPtr src 1)
@@ -98,7 +106,7 @@
     !hi = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x20\x30\x40\x50\x60\x70\x80\x90\xff\xff\xff\xff\xff\xff\xff\xa0\xb0\xc0\xd0\xe0\xf0\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xa0\xb0\xc0\xd0\xe0\xf0\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#
 
     goHi !dst !src !n
-      | src == end = return (PS dfp 0 n)
+      | src == end = return (mkBS dfp n)
       | otherwise = do
         !x <- peek src
 
@@ -109,7 +117,7 @@
         else goLo dst (plusPtr src 1) a n
 
     goLo !dst !src !a !n
-      | src == end = return (PS dfp 0 n)
+      | src == end = return (mkBS dfp n)
       | otherwise = do
         !y <- peek src
 
@@ -156,3 +164,21 @@
 c2w :: Char -> Word8
 c2w = fromIntegral . ord
 {-# INLINE c2w #-}
+
+mkBS :: ForeignPtr Word8 -> Int -> ByteString
+#if MIN_VERSION_bytestring(0,11,0)
+mkBS dfp n = BS dfp n
+#else
+mkBS dfp n = PS dfp 0 n
+#endif
+{-# INLINE mkBS #-}
+
+withBS :: ByteString -> (Ptr Word8 -> Int -> IO a) -> a
+#if MIN_VERSION_bytestring(0,11,0)
+withBS (BS !sfp !slen) f = unsafeDupablePerformIO $
+  withForeignPtr sfp $ \p -> f p slen
+#else
+withBS (PS !sfp !soff !slen) f = unsafeDupablePerformIO $
+  withForeignPtr sfp $ \p -> f (plusPtr p soff) slen
+#endif
+{-# INLINE withBS #-}
diff --git a/base16-bytestring.cabal b/base16-bytestring.cabal
--- a/base16-bytestring.cabal
+++ b/base16-bytestring.cabal
@@ -1,6 +1,6 @@
 cabal-version:      1.12
 name:               base16-bytestring
-version:            1.0.0.0
+version:            1.0.1.0
 synopsis:           RFC 4648-compliant Base16 encodings for ByteStrings
 description:
   This package provides support for encoding and decoding binary data according
@@ -58,7 +58,7 @@
 
   build-depends:
       base        >=4   && <5
-    , bytestring  >=0.9 && <0.11
+    , bytestring  >=0.9 && <0.12
 
   ghc-options:      -Wall -funbox-strict-fields
   default-language: Haskell2010
