diff --git a/library/PtrPoker/ByteString.hs b/library/PtrPoker/ByteString.hs
--- a/library/PtrPoker/ByteString.hs
+++ b/library/PtrPoker/ByteString.hs
@@ -1,10 +1,13 @@
 module PtrPoker.ByteString
 where
 
-import PtrPoker.Prelude
+import PtrPoker.Prelude hiding (empty)
+import Data.ByteString
 import Data.ByteString.Internal
 import Data.ByteString.Builder.Prim
 import qualified Data.Text as Text
+import qualified Data.Text.Array as TextArray
+import qualified Data.Text.Internal as TextInternal
 import qualified Data.Text.Encoding as TextEncoding
 import qualified Data.ByteString.Lazy as Lazy
 import qualified Data.ByteString.Builder as Builder
@@ -36,3 +39,14 @@
     fp <- mallocByteString allocSize
     actualSize <- withForeignPtr fp (\ p -> populate (plusPtr p (pred allocSize)))
     return $! PS fp (allocSize - actualSize) actualSize
+
+{-# INLINABLE textUtf8 #-}
+textUtf8 :: Text -> ByteString
+textUtf8 (TextInternal.Text arr off len) =
+  if len == 0
+    then
+      empty
+    else
+      unsafeCreateUptoN (len * 3) $ \ ptr -> do
+        postPtr <- inline Ffi.encodeText ptr (TextArray.aBA arr) (fromIntegral off) (fromIntegral len)
+        return (minusPtr postPtr ptr)
diff --git a/library/PtrPoker/Poke.hs b/library/PtrPoker/Poke.hs
--- a/library/PtrPoker/Poke.hs
+++ b/library/PtrPoker/Poke.hs
@@ -39,10 +39,10 @@
 concat pokers =
   Poke (\ p -> foldM (\ p (Poke io) -> io p) p pokers)
 
-{-# INLINE[1] byteString #-}
+{-# INLINE byteString #-}
 byteString :: ByteString -> Poke
 byteString bs =
-  Poke $ \ ptr -> ByteStringIO.pokeByteString ptr bs
+  Poke $ \ ptr -> inline ByteStringIO.pokeByteString ptr bs
 
 {-# INLINE[1] word8 #-}
 word8 :: Word8 -> Poke
diff --git a/library/PtrPoker/Write.hs b/library/PtrPoker/Write.hs
--- a/library/PtrPoker/Write.hs
+++ b/library/PtrPoker/Write.hs
@@ -120,9 +120,25 @@
 {-# INLINE byteString #-}
 byteString :: ByteString -> Write
 byteString a =
-  Write (ByteString.length a) (Poke.byteString a)
+  Write (ByteString.length a) (inline Poke.byteString a)
 
-{-# INLINE textUtf8 #-}
+{-|
+Benchmark results in comparison to @Data.Text.Encoding.'Data.Text.Encoding.decodeUtf8'@.
+
+> textUtf8/ptr-poker/latin/1               mean 57.06 ns  ( +- 3.283 ns  )
+> textUtf8/ptr-poker/latin/10              mean 214.1 ns  ( +- 8.601 ns  )
+> textUtf8/ptr-poker/latin/100             mean 1.536 μs  ( +- 75.03 ns  )
+> textUtf8/ptr-poker/greek/1               mean 85.98 ns  ( +- 5.038 ns  )
+> textUtf8/ptr-poker/greek/10              mean 482.1 ns  ( +- 12.38 ns  )
+> textUtf8/ptr-poker/greek/100             mean 4.398 μs  ( +- 33.94 ns  )
+> textUtf8/text/latin/1                    mean 60.28 ns  ( +- 3.517 ns  )
+> textUtf8/text/latin/10                   mean 201.6 ns  ( +- 8.118 ns  )
+> textUtf8/text/latin/100                  mean 1.323 μs  ( +- 51.25 ns  )
+> textUtf8/text/greek/1                    mean 99.14 ns  ( +- 1.264 ns  )
+> textUtf8/text/greek/10                   mean 483.4 ns  ( +- 5.844 ns  )
+> textUtf8/text/greek/100                  mean 4.238 μs  ( +- 40.55 ns  )
+-}
+{-# INLINABLE textUtf8 #-}
 textUtf8 :: Text -> Write
-textUtf8 a =
-  Write (Size.textUtf8 a) (Poke.textUtf8 a)
+textUtf8 =
+  byteString . ByteString.textUtf8
diff --git a/ptr-poker.cabal b/ptr-poker.cabal
--- a/ptr-poker.cabal
+++ b/ptr-poker.cabal
@@ -1,5 +1,5 @@
 name: ptr-poker
-version: 0.1.1
+version: 0.1.1.1
 synopsis: Pointer poking action construction and composition toolkit
 homepage: https://github.com/nikita-volkov/ptr-poker
 bug-reports: https://github.com/nikita-volkov/ptr-poker/issues
