diff --git a/src/Data/Text/Lazy/Manipulate.hs b/src/Data/Text/Lazy/Manipulate.hs
--- a/src/Data/Text/Lazy/Manipulate.hs
+++ b/src/Data/Text/Lazy/Manipulate.hs
@@ -55,7 +55,6 @@
     , toAcronym
 
     -- * Ordinals
-    , Ordinal (..)
     , toOrdinal
 
     -- * Casing
@@ -75,7 +74,6 @@
 import           Data.Int
 import           Data.List                            (intersperse)
 import           Data.Monoid
-import           Data.Text.Buildable
 import           Data.Text.Lazy                       (Text)
 import qualified Data.Text.Lazy                       as LText
 import           Data.Text.Lazy.Builder               (toLazyText)
@@ -210,7 +208,6 @@
     | otherwise          = Nothing
 
 -- | Render an ordinal used to denote the position in an ordered sequence.
--- @toOrdinal == build . Ordinal@.
 --
 -- >>> toOrdinal (101 :: Int)
 -- "101st"
@@ -218,7 +215,7 @@
 -- >>> toOrdinal (12 :: Int)
 -- "12th"
 toOrdinal :: Integral a => a -> Text
-toOrdinal = toLazyText . build . Ordinal
+toOrdinal = toLazyText . ordinal
 
 -- | O(n) Convert casing to @Title Cased Phrase@. /Subject to fusion./
 toTitle :: Text -> Text
diff --git a/src/Data/Text/Manipulate.hs b/src/Data/Text/Manipulate.hs
--- a/src/Data/Text/Manipulate.hs
+++ b/src/Data/Text/Manipulate.hs
@@ -55,7 +55,6 @@
     , toAcronym
 
     -- * Ordinals
-    , Ordinal (..)
     , toOrdinal
 
     -- * Casing
@@ -219,7 +218,6 @@
     | otherwise         = Nothing
 
 -- | Render an ordinal used to denote the position in an ordered sequence.
--- @toOrdinal == build . Ordinal@.
 --
 -- >>> toOrdinal (101 :: Int)
 -- "101st"
diff --git a/src/Data/Text/Manipulate/Internal/Types.hs b/src/Data/Text/Manipulate/Internal/Types.hs
--- a/src/Data/Text/Manipulate/Internal/Types.hs
+++ b/src/Data/Text/Manipulate/Internal/Types.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE MagicHash         #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE ViewPatterns      #-}
 
@@ -14,14 +15,21 @@
 module Data.Text.Manipulate.Internal.Types where
 
 import           Control.Monad
-import qualified Data.Char           as Char
+import qualified Data.Char              as Char
 import           Data.Monoid
-import           Data.Text.Buildable
+import           Data.Text.Lazy.Builder (Builder, singleton)
+import           GHC.Base
 
-newtype Ordinal a = Ordinal a
+-- | Returns 'True' for any boundary or uppercase character.
+isWordBoundary :: Char -> Bool
+isWordBoundary c = Char.isUpper c || isBoundary c
 
-instance Integral a => Buildable (Ordinal a) where
-    build (Ordinal (toInteger -> n)) = build n <> suf
+-- | Returns 'True' for any boundary character.
+isBoundary :: Char -> Bool
+isBoundary = not . Char.isAlphaNum
+
+ordinal :: Integral a => a -> Builder
+ordinal (toInteger -> n) = decimal n <> suf
       where
         suf | x `elem` [11..13] = "th"
             | y == 1            = "st"
@@ -30,11 +38,22 @@
             | otherwise         = "th"
 
         (flip mod 100 -> x, flip mod 10 -> y) = join (,) (abs n)
+{-# NOINLINE[0] ordinal #-}
 
--- | Returns 'True' for any boundary or uppercase character.
-isWordBoundary :: Char -> Bool
-isWordBoundary c = Char.isUpper c || isBoundary c
+decimal :: Integral a => a -> Builder
+{-# SPECIALIZE decimal :: Int -> Builder #-}
+decimal i
+    | i < 0     = singleton '-' <> go (-i)
+    | otherwise = go i
+  where
+    go n | n < 10    = digit n
+         | otherwise = go (n `quot` 10) <> digit (n `rem` 10)
+{-# NOINLINE[0] decimal #-}
 
--- | Returns 'True' for any boundary character.
-isBoundary :: Char -> Bool
-isBoundary = not . Char.isAlphaNum
+digit :: Integral a => a -> Builder
+digit n = singleton $! i2d (fromIntegral n)
+{-# INLINE digit #-}
+
+i2d :: Int -> Char
+i2d (I# i#) = C# (chr# (ord# '0'# +# i#))
+{-# INLINE i2d #-}
diff --git a/text-manipulate.cabal b/text-manipulate.cabal
--- a/text-manipulate.cabal
+++ b/text-manipulate.cabal
@@ -1,5 +1,5 @@
 name:                  text-manipulate
-version:               0.1.3.1
+version:               0.2.0
 synopsis:              Case conversion, word boundary manipulation, and textual subjugation.
 homepage:              https://github.com/brendanhay/text-manipulate
 license:               OtherLicense
@@ -44,9 +44,8 @@
         , Data.Text.Manipulate.Internal.Types
 
     build-depends:
-          base        >= 4.5 && < 5.0
-        , text        >= 1.1 && < 1.3
-        , text-format >= 0.3
+          base >= 4.5 && < 5
+        , text >= 1.1
 
 benchmark benchmarks
     type:              exitcode-stdio-1.0
