diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
 ---
-title: SLOANE(1) Sloane User Manual | Version 2.0.3
+title: SLOANE(1) Sloane User Manual | Version 2.0.4
 date: 7 Jan 2015
 ---
 
diff --git a/Sloane/Config.hs b/Sloane/Config.hs
--- a/Sloane/Config.hs
+++ b/Sloane/Config.hs
@@ -29,7 +29,7 @@
     h <- getHomeDirectory
     let dsloane = h </> ".sloane"
     return Config
-        { nameVer   = "sloane 2.0.3"
+        { nameVer   = "sloane 2.0.4"
         , home      = h
         , sloaneDir = dsloane
         , sloaneDB  = dsloane </> "sloane.db"
diff --git a/Sloane/DB.hs b/Sloane/DB.hs
--- a/Sloane/DB.hs
+++ b/Sloane/DB.hs
@@ -26,6 +26,8 @@
 import           Prelude                    hiding (lookup, null, take, read)
 import qualified Prelude                    as P
 import           Data.List                  (intersect)
+import qualified Data.ByteString.Search     as Search
+import qualified Data.ByteString.Char8      as Ch8
 import           Data.ByteString            (ByteString)
 import qualified Data.ByteString            as B
 import qualified Data.ByteString.Lazy       as BL
@@ -43,8 +45,8 @@
 import           Sloane.Config
 import           System.Directory
 
-type ANumber = Text
-type Seq     = Text
+type ANumber = ByteString
+type Seq     = ByteString
 type Key     = Char
 type Entry   = Text
 type Reply   = Map Key Entry
@@ -53,10 +55,10 @@
 type DBRaw   = Map ByteString (Map Char ByteString)
 
 encodeUtf8' :: DB -> DBRaw
-encodeUtf8'= M.mapKeys encodeUtf8 . M.map (M.map encodeUtf8)
+encodeUtf8'= M.map (M.map encodeUtf8)
 
 decodeUtf8' :: DBRaw -> DB
-decodeUtf8' = M.mapKeys decodeUtf8 . M.map (M.map decodeUtf8)
+decodeUtf8' = M.map (M.map decodeUtf8)
 
 gzCompress :: ByteString -> ByteString
 gzCompress = BL.toStrict . GZ.compress . BL.fromStrict
@@ -82,10 +84,10 @@
     putStrLn "Done."
   where
     unionDB = M.unionWith M.union
-    mkDB key = mkMap key . decodeUtf8 . gzDecompress
-    mkMap key = M.fromList . map (aNumberAndReply key) . drop 4 . T.lines
-    mkReply key = M.singleton key . T.dropWhile (==',') . T.drop 8
-    aNumberAndReply key line = (T.take 7 line, mkReply key line)
+    mkDB key = mkMap key . gzDecompress
+    mkMap key = M.fromList . map (aNumberAndReply key) . drop 4 . Ch8.lines
+    mkReply key = M.singleton key . decodeUtf8 . Ch8.dropWhile (==',') . Ch8.drop 8
+    aNumberAndReply key line = (Ch8.take 7 line, mkReply key line)
 
 read :: Config -> IO DB
 read cfg = doesFileExist (sloaneDB cfg) >>= \updated ->
@@ -106,14 +108,17 @@
 lookup :: ANumber -> DB -> Maybe Reply
 lookup = M.lookup
 
-lookupSeq :: ANumber -> DB -> Maybe Seq
+lookupSeq :: ANumber -> DB -> Maybe Text
 lookupSeq anum db = lookup anum db >>= M.lookup 'S'
 
-grep :: Text -> DB -> DB
+isInfix :: ByteString -> ByteString -> Bool
+isInfix q = not . P.null . Search.indices q
+
+grep :: ByteString -> DB -> DB
 grep q = M.filter $ \reply ->
              case M.lookup 'S' reply of
                  Nothing -> False
-                 Just r  -> q `T.isInfixOf` r
+                 Just r  -> q `isInfix` (encodeUtf8 r)
 
 take :: Int -> DB -> DB
 take n = M.fromList . P.take n . M.toList
@@ -128,12 +133,12 @@
 singleton :: ANumber -> Key -> Entry -> DB
 singleton aNum key entry = M.singleton aNum $ M.singleton key entry
 
-parseOEISEntries :: Text -> DB
+parseOEISEntries :: ByteString -> DB
 parseOEISEntries = unions . map parseLine . trim
   where
-    trim = map (T.drop 1) . reverse . drop 2 . reverse . drop 5 . T.lines
-    parseLine = parseWords . T.words
-    parseWords (key:aNum:rest) = singleton aNum (T.head key) (T.unwords rest)
+    trim = map (Ch8.drop 1) . reverse . drop 2 . reverse . drop 5 . Ch8.lines
+    parseLine = parseWords . Ch8.words
+    parseWords (key:aNum:rest) = singleton aNum (Ch8.head key) (decodeUtf8 (Ch8.unwords rest))
     parseWords _ = M.empty
 
 put :: Config -> [Key] -> DB -> IO ()
@@ -146,7 +151,7 @@
                 setSGR [ SetColor Foreground Dull Green ]
                 putStr [key]
                 setSGR [ SetColor Foreground Dull Yellow ]
-                putStr " " >> IO.putStr aNum
+                putStr " " >> Ch8.putStr aNum
                 setSGR []
                 putStr " " >> IO.putStrLn (crop key (termWidth cfg - 10) line)
         putStrLn ""
diff --git a/sloane.1 b/sloane.1
--- a/sloane.1
+++ b/sloane.1
@@ -1,4 +1,4 @@
-.TH "SLOANE" "1" "7 Jan 2015" "Sloane User Manual" "Version 2.0.2"
+.TH "SLOANE" "1" "7 Jan 2015" "Sloane User Manual" "Version 2.0.4"
 .SH NAME
 .PP
 sloane \- a command line interface to Sloane\[aq]s On\-Line Encyclopedia
diff --git a/sloane.cabal b/sloane.cabal
--- a/sloane.cabal
+++ b/sloane.cabal
@@ -1,5 +1,5 @@
 Name:                sloane
-Version:             2.0.3
+Version:             2.0.4
 Synopsis:            A command line interface to Sloane's On-Line Encyclopedia
                      of Integer Sequences
 Description:         A command line interface to Sloane's On-Line Encyclopedia
@@ -40,4 +40,5 @@
                        terminal-size >=0.2,
                        filepath >=1.3,
                        directory >=1.2,
-                       zlib >=0.5
+                       zlib >=0.5,
+                       stringsearch
diff --git a/sloane.hs b/sloane.hs
--- a/sloane.hs
+++ b/sloane.hs
@@ -7,10 +7,9 @@
 import           Data.List                    (intercalate)
 import           Data.Maybe                   (maybeToList)
 import           Data.Monoid
-import           Data.Text                    (Text)
-import qualified Data.Text                    as T
 import qualified Data.Text.IO                 as IO
-import           Data.Text.Encoding           (decodeUtf8)
+import           Data.ByteString              (ByteString)
+import qualified Data.ByteString.Char8        as Ch8
 import           System.IO                    (isEOF)
 import           Network.HTTP                 (urlEncodeVars)
 import           Network.Curl.Download        (openURI)
@@ -42,18 +41,18 @@
 oeisKeys = "ISTUVWXNDHFYAOEeptoKC" -- Valid OEIS keys
 
 oeisUrls :: Config -> DB -> [URL]
-oeisUrls cfg = map ((oeisHost cfg ++) . T.unpack) . DB.aNumbers
+oeisUrls cfg = map ((oeisHost cfg ++) . Ch8.unpack) . DB.aNumbers
 
 oeisLookup :: Options -> Config -> IO DB
 oeisLookup opts cfg =
-    (DB.parseOEISEntries . decodeUtf8 . either error id) <$>
+    (DB.parseOEISEntries . either error id) <$>
     openURI (oeisURL cfg ++ "&" ++ urlEncodeVars [("n", show n), ("q", q)])
   where
     n = limit opts
     q = unwords $ terms opts
 
 grepDB :: Options -> DB -> DB
-grepDB opts = DB.take n . DB.grep (T.pack q)
+grepDB opts = DB.take n . DB.grep (Ch8.pack q)
   where
     n = limit opts
     q = intercalate "," (terms opts)
@@ -69,26 +68,26 @@
     tr c  = if c `elem` ";," then ' ' else c
     input = map read (words (map tr (unwords (terms opts))))
 
-dropComment :: Text -> Text
-dropComment = T.takeWhile (/= '#')
+dropComment :: ByteString -> ByteString
+dropComment = Ch8.takeWhile (/= '#')
 
 showSeq :: [Integer] -> String
 showSeq = intercalate "," . map show
 
-mkSeq :: Text -> Seq
-mkSeq = T.intercalate (T.pack ",") . T.words . clean . dropComment
+mkSeq :: ByteString -> Seq
+mkSeq = Ch8.intercalate (Ch8.pack ",") . Ch8.words . clean . dropComment
   where
-    clean = T.filter (`elem` " 0123456789-") . T.map tr
+    clean = Ch8.filter (`elem` " 0123456789-") . Ch8.map tr
     tr c  = if c `elem` ";," then ' ' else c
 
 mkANumber :: Int -> ANumber
-mkANumber n = let s = show n in T.pack ('A' : replicate (6-length s) '0' ++ s)
+mkANumber n = let s = show n in Ch8.pack ('A' : replicate (6-length s) '0' ++ s)
 
 filterDB :: Options -> DB -> IO [Seq]
-filterDB opts db = filter match . parseSeqs <$> IO.getContents
+filterDB opts db = filter match . parseSeqs <$> Ch8.getContents
   where
     match q = (if invert opts then id else not) (DB.null $ DB.grep q db)
-    parseSeqs = filter (not . T.null) . map mkSeq . T.lines
+    parseSeqs = filter (not . Ch8.null) . map mkSeq . Ch8.lines
 
 optionsParser :: Parser Options
 optionsParser =
@@ -174,7 +173,7 @@
          | update opts = DB.update
          | listTransforms opts = const $ mapM_ (putStrLn . name) transforms
          | anum > 0 = \c -> lookupSeq <$> DB.read c >>= mapM_ IO.putStrLn
-         | filtr opts = \c -> DB.read c >>= filterDB opts >>= mapM_ IO.putStrLn
+         | filtr opts = \c -> DB.read c >>= filterDB opts >>= mapM_ Ch8.putStrLn
          | not (null tname) = const $ applyTransform opts tname
          | local opts = search (\o cfg -> grepDB o <$> DB.read cfg) opts
          | otherwise = search oeisLookup opts
