diff --git a/haskus-utils-compat.cabal b/haskus-utils-compat.cabal
--- a/haskus-utils-compat.cabal
+++ b/haskus-utils-compat.cabal
@@ -1,12 +1,12 @@
 name:                haskus-utils-compat
-version:             1.0
+version:             1.1
 synopsis:            Compatibility modules with other external packages (ByteString, etc.)
 license:             BSD3
 license-file:        LICENSE
 author:              Sylvain Henry
 maintainer:          sylvain@haskus.fr
 homepage:            http://docs.haskus.org/
-copyright:           Sylvain Henry 2019
+copyright:           Sylvain Henry 2020
 category:            System
 build-type:          Simple
 cabal-version:       1.20
@@ -16,11 +16,12 @@
 
 source-repository head
   type: git
-  location: git://github.com/haskus/haskus-utils.git
+  location: git://github.com/haskus/packages.git
 
 library
   exposed-modules:
     Haskus.Utils.Embed.ByteString
+    Haskus.Utils.Text
 
   other-modules:
 
@@ -32,8 +33,9 @@
       ,  directory
       ,  filepath
       ,  bytestring
+      ,  text
+      ,  formatting
 
-  build-tools: 
   ghc-options:          -Wall
   default-language:     Haskell2010
   hs-source-dirs:       src/lib
diff --git a/src/lib/Haskus/Utils/Embed/ByteString.hs b/src/lib/Haskus/Utils/Embed/ByteString.hs
--- a/src/lib/Haskus/Utils/Embed/ByteString.hs
+++ b/src/lib/Haskus/Utils/Embed/ByteString.hs
@@ -1,12 +1,15 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE TemplateHaskell #-}
 {-# LANGUAGE GADTs #-}
 {-# LANGUAGE DataKinds #-}
+{-# LANGUAGE LambdaCase #-}
 
 -- | Embed files as ByteStrings into an executable
 module Haskus.Utils.Embed.ByteString
    ( bufferToByteString
    , embedBS
    , embedBSFile
+   , embedBSFilePrefix
    , embedBSOneFileOf
    , embedBSDir
    , module Haskus.Memory.Embed
@@ -48,6 +51,16 @@
    bs <- runIO $ BS.readFile fp
    embedBS bs
 
+embedBSFilePrefix :: FilePath -> FilePath -> Q Exp
+embedBSFilePrefix prefix fp' = do
+   -- small hack because "stack build" and "stack repl" in the multi-package
+   -- project have different CWD
+   fp <- liftIO (doesFileExist fp') >>= \case
+            True  -> return fp'
+            False -> return (prefix </> fp')
+   embedBSFile fp
+
+
 -- | Embed a single existing file in your source code
 -- out of list a list of paths supplied.
 --
@@ -82,7 +95,11 @@
    bufToBs <- [| bufferToByteString |]
    let embedPair (relpath,realpath) = do
          exp' <- embedFile realpath False Nothing Nothing Nothing
+#if __GLASGOW_HASKELL__ >= 810
+         return $! TupE [Just (LitE $ StringL relpath), Just (bufToBs `AppE` exp')]
+#else
          return $! TupE [LitE $ StringL relpath, bufToBs `AppE` exp']
+#endif
    e <- ListE <$> ((runIO $ listDirectoryRec fp) >>= mapM embedPair)
    return $ SigE e typ
 
diff --git a/src/lib/Haskus/Utils/Text.hs b/src/lib/Haskus/Utils/Text.hs
new file mode 100644
--- /dev/null
+++ b/src/lib/Haskus/Utils/Text.hs
@@ -0,0 +1,75 @@
+-- | Wrap Data.Text
+--
+-- We plan to replace it with Haskus.Text in the future
+module Haskus.Utils.Text
+   ( module Data.Text
+   -- * Conversions
+   , bufferDecodeUtf8
+   , textEncodeUtf8
+   , stringEncodeUtf8
+   -- * Formatting
+   , textFormat
+   , F.Format
+   , (F.%)
+   , (F.%.)
+   , module Formatting.Formatters
+   -- * Parsing
+   , textParseHexadecimal
+   -- * Get/Put
+   , putTextUtf8
+   , getTextUtf8
+   , getTextUtf8Nul
+   , tshow
+   -- * IO
+   , T.putStrLn
+   )
+where
+
+import Data.Text hiding (center)
+import qualified Data.Text.Encoding as T
+import qualified Data.Text          as T
+import qualified Data.Text.IO       as T
+import Formatting                   as F
+import Formatting.Formatters
+import Data.Text.Read               as T
+
+import Haskus.Binary.Buffer
+import Haskus.Binary.Put
+import Haskus.Binary.Get
+
+-- | Decode Utf8
+bufferDecodeUtf8 :: Buffer -> Text
+bufferDecodeUtf8 (Buffer bs) = T.decodeUtf8 bs
+
+-- | Encode Text into Utf8
+textEncodeUtf8 :: Text -> Buffer
+textEncodeUtf8 = Buffer . T.encodeUtf8
+
+-- | Encode String into Utf8
+stringEncodeUtf8 :: String -> Buffer
+stringEncodeUtf8 = textEncodeUtf8 . T.pack
+
+-- | Format a text (strict)
+textFormat :: Format Text a -> a
+textFormat = F.sformat
+
+-- | Parse an hexadecimal number
+-- FIXME: use a real parser (MegaParsec, etc.)
+textParseHexadecimal :: Integral a => Text -> Either String a
+textParseHexadecimal s = fst <$> T.hexadecimal s
+
+-- | Put an UTF8 encoded text
+putTextUtf8 :: Text -> Put
+putTextUtf8 = putBuffer . textEncodeUtf8
+
+-- | Pull n bytes from the input, as a Buffer
+getTextUtf8 :: Word -> Get Text
+getTextUtf8 sz = bufferDecodeUtf8 <$> getBuffer sz
+
+-- | Pull \0 terminal text
+getTextUtf8Nul :: Get Text
+getTextUtf8Nul = bufferDecodeUtf8 <$> getBufferNul
+
+-- | Show as Text
+tshow :: Show a => a -> Text
+tshow = pack . show
