diff --git a/Data/Double/Conversion/ByteString.hs b/Data/Double/Conversion/ByteString.hs
--- a/Data/Double/Conversion/ByteString.hs
+++ b/Data/Double/Conversion/ByteString.hs
@@ -1,5 +1,3 @@
-{-# LANGUAGE TypeFamilies #-}
-
 -- |
 -- Module      : Data.Double.Conversion.ByteString
 -- Copyright   : (c) 2011 MailRank, Inc.
@@ -9,6 +7,10 @@
 -- Stability   : experimental
 -- Portability : GHC
 --
+-- This module left now only for compatibility and should not be used
+-- in new projects. 
+-- Please, use Convertable type class from Data.Double.Conversion.Convertable
+-- 
 -- Fast, efficient support for converting between double precision
 -- floating point values and text.
 --
@@ -18,27 +20,34 @@
 -- 'ByteString' values via @malloc@.)
 
 module Data.Double.Conversion.ByteString
-    ( convert
+    (
+      toExponential
+    , toFixed
+    , toPrecision
+    , toShortest
     ) where
 
-import Control.Monad (when)
-import Data.ByteString.Internal (ByteString(..), mallocByteString)
-import Data.Double.Conversion.FFI (ForeignFloating)
-import Data.Word (Word8)
-import Foreign.C.Types (CDouble, CFloat, CInt)
-import Foreign.ForeignPtr (withForeignPtr)
-import Foreign.Ptr (Ptr)
-import System.IO.Unsafe (unsafePerformIO)
+import qualified Data.Double.Conversion.Convertable
+import Data.ByteString.Internal
 
-convert :: (RealFloat a, RealFloat b , b ~ ForeignFloating a) => String -> CInt -> (b -> Ptr Word8 -> IO CInt)
-        -> a -> ByteString
-{-# SPECIALIZE convert :: String -> CInt -> (CDouble -> Ptr Word8 -> IO CInt) -> Double -> ByteString #-}
-{-# SPECIALIZE convert :: String -> CInt -> (CFloat -> Ptr Word8 -> IO CInt) -> Float -> ByteString #-}
-{-# INLINABLE convert #-}
-convert func len act val = unsafePerformIO $ do
-  fp <- mallocByteString (fromIntegral len)
-  size <- withForeignPtr fp $ act (realToFrac val)
-  when (size == -1) .
-    fail $ "Data.Double.Conversion.ByteString." ++ func ++
-           ": conversion failed (invalid precision requested)"
-  return $ PS fp 0 (fromIntegral size)
+-- | Compute a representation in exponential format with the requested
+-- number of digits after the decimal point. The last emitted digit is
+-- rounded.  If -1 digits are requested, then the shortest exponential
+-- representation is computed.
+toExponential :: Int -> Double -> ByteString
+toExponential = Data.Double.Conversion.Convertable.toExponential
+
+-- | Compute a decimal representation with a fixed number of digits
+-- after the decimal point. The last emitted digit is rounded.
+toFixed :: Int -> Double -> ByteString
+toFixed = Data.Double.Conversion.Convertable.toFixed
+
+-- | Compute the shortest string of digits that correctly represent
+-- the input number.
+toShortest :: Double -> ByteString
+toShortest = Data.Double.Conversion.Convertable.toShortest
+
+-- | Compute @precision@ leading digits of the given value either in
+-- exponential or decimal format. The last computed digit is rounded.
+toPrecision :: Int -> Double -> ByteString
+toPrecision = Data.Double.Conversion.Convertable.toPrecision
diff --git a/Data/Double/Conversion/ByteStringBuilder.hs b/Data/Double/Conversion/ByteStringBuilder.hs
deleted file mode 100644
--- a/Data/Double/Conversion/ByteStringBuilder.hs
+++ /dev/null
@@ -1,40 +0,0 @@
-{-# LANGUAGE TypeFamilies #-}
-
--- |
--- Module      : Data.Double.Conversion.ByteStringBuilder
--- Copyright   : (c) 2011 MailRank, Inc.
---
--- License     : BSD-style
--- Maintainer  : bos@serpentine.com
--- Stability   : experimental
--- Portability : GHC
---
--- Fast, efficient support for converting between double precision
--- floating point values and bytestring builder.
-
--- This functions are much slower on the single value, but also it is much faster in conversting big set of
--- numbers, than bytestring functions. See benchmark.
-
-module Data.Double.Conversion.ByteStringBuilder
-    (convert
-    ) where
-
-import Control.Monad (when)
-
-import Data.ByteString.Builder.Prim.Internal (BoundedPrim, boudedPrim)
-
-import Data.Double.Conversion.FFI (ForeignFloating)
-import Data.Word (Word8)
-import Foreign.C.Types (CDouble, CFloat, CInt)
-import Foreign.Ptr (Ptr, plusPtr)
-
-convert :: (RealFloat a, RealFloat b , b ~ ForeignFloating a) => String -> CInt -> (b -> Ptr Word8 -> IO CInt) -> BoundedPrim a
-{-# SPECIALIZE convert :: String -> CInt -> (CDouble -> Ptr Word8 -> IO CInt) -> BoundedPrim Double #-}
-{-# SPECIALIZE convert :: String -> CInt -> (CFloat -> Ptr Word8 -> IO CInt) -> BoundedPrim Float #-}
-{-# INLINABLE convert #-}
-convert func len act = boudedPrim (fromIntegral len) $ \val ptr -> do
-  size <- act (realToFrac val) ptr
-  when (size == -1) .
-    fail $ "Data.Double.Conversion.ByteString." ++ func ++
-           ": conversion failed (invalid precision requested)"
-  return (ptr `plusPtr` (fromIntegral size))
diff --git a/Data/Double/Conversion/Convertable.hs b/Data/Double/Conversion/Convertable.hs
--- a/Data/Double/Conversion/Convertable.hs
+++ b/Data/Double/Conversion/Convertable.hs
@@ -16,15 +16,15 @@
 import Data.ByteString.Builder.Prim (primBounded)
 import Data.Text (Text)
 
-import Data.Double.Conversion.FFI
+import Data.Double.Conversion.Internal.FFI
 import Data.String (IsString)
 
 import qualified Data.ByteString.Builder as BB (Builder)
 import qualified Data.ByteString.Internal as B (ByteString(..))
-import qualified Data.Double.Conversion.ByteString as CB (convert)
-import qualified Data.Double.Conversion.ByteStringBuilder as CBB (convert)
-import qualified Data.Double.Conversion.Text as CT (convert)
-import qualified Data.Double.Conversion.TextBuilder as CTB (convert)
+import qualified Data.Double.Conversion.Internal.ByteString as CB (convert)
+import qualified Data.Double.Conversion.Internal.ByteStringBuilder as CBB (convert)
+import qualified Data.Double.Conversion.Internal.Text as CT (convert)
+import qualified Data.Double.Conversion.Internal.TextBuilder as CTB (convert)
 import qualified Data.Text.Internal.Builder as T (Builder)
 
 -- | Type class for floating data types, that cen be converted, using double-conversion library
diff --git a/Data/Double/Conversion/FFI.hs b/Data/Double/Conversion/FFI.hs
deleted file mode 100644
--- a/Data/Double/Conversion/FFI.hs
+++ /dev/null
@@ -1,113 +0,0 @@
-{-# LANGUAGE CPP, ForeignFunctionInterface, MagicHash, TypeFamilies,
-             UnliftedFFITypes #-}
-
--- |
--- Module      : Data.Double.Conversion.FFI
--- Copyright   : (c) 2011 MailRank, Inc.
---
--- License     : BSD-style
--- Maintainer  : bos@serpentine.com
--- Stability   : experimental
--- Portability : GHC
---
--- FFI interface support for converting between
--- floating point values and text.
-
-module Data.Double.Conversion.FFI
-    (
-      ForeignFloating (..)
-    , c_Text_ToExponential
-    , c_Text_ToExponentialFloat
-    , c_Text_ToFixed
-    , c_Text_ToFixedFloat
-    , c_Text_ToPrecision
-    , c_Text_ToPrecisionFloat
-    , c_Text_ToShortest
-    , c_Text_ToShortestFloat
-    , c_ToExponentialLength
-    , c_ToFixedLength
-    , c_ToPrecisionLength
-    , c_ToShortestLength
-    , c_ToExponential
-    , c_ToExponentialFloat
-    , c_ToFixed
-    , c_ToFixedFloat
-    , c_ToPrecision
-    , c_ToPrecisionFloat
-    , c_ToShortest
-    , c_ToShortestFloat
-    ) where
-
-import Data.Word (Word8)
-#if __GLASGOW_HASKELL__ >= 703
-import Foreign.C.Types (CDouble(CDouble), CFloat(CFloat), CInt(CInt))
-#else
-import Foreign.C.Types (CDouble, CFloat, CInt)
-#endif
-import Foreign.Ptr (Ptr)
-import GHC.Prim (MutableByteArray#)
-
-type family ForeignFloating h :: *
-
-type instance ForeignFloating Double = CDouble
-type instance ForeignFloating Float = CFloat
-
-foreign import ccall unsafe "hs-double-conversion.h _hs_ToShortestLength"
-    c_ToShortestLength :: CInt
-
-foreign import ccall unsafe "hs-double-conversion.h _hs_Text_ToShortest"
-    c_Text_ToShortest :: CDouble -> MutableByteArray# s -> IO CInt
-
-foreign import ccall unsafe "hs-double-conversion.h _hs_ToShortest"
-    c_ToShortest :: CDouble -> Ptr Word8 -> IO CInt
-
-foreign import ccall unsafe "hs-double-conversion.h _hs_Text_ToShortestFloat"
-    c_Text_ToShortestFloat :: CFloat -> MutableByteArray# s -> IO CInt
-
-foreign import ccall unsafe "hs-double-conversion.h _hs_ToShortestFloat"
-    c_ToShortestFloat :: CFloat -> Ptr Word8 -> IO CInt
-
-foreign import ccall unsafe "hs-double-conversion.h _hs_ToFixedLength"
-    c_ToFixedLength :: CInt
-
-foreign import ccall unsafe "hs-double-conversion.h _hs_Text_ToFixed"
-    c_Text_ToFixed :: CDouble -> MutableByteArray# s -> CInt -> IO CInt
-
-foreign import ccall unsafe "hs-double-conversion.h _hs_Text_ToFixedFloat"
-    c_Text_ToFixedFloat :: CFloat -> MutableByteArray# s -> CInt -> IO CInt
-
-foreign import ccall unsafe "hs-double-conversion.h _hs_ToFixed"
-    c_ToFixed :: CDouble -> Ptr Word8 -> CInt -> IO CInt
-
-foreign import ccall unsafe "hs-double-conversion.h _hs_ToFixedFloat"
-    c_ToFixedFloat :: CFloat -> Ptr Word8 -> CInt -> IO CInt
-
-foreign import ccall unsafe "hs-double-conversion.h _hs_ToExponentialLength"
-    c_ToExponentialLength :: CInt
-
-foreign import ccall unsafe "hs-double-conversion.h _hs_Text_ToExponential"
-    c_Text_ToExponential :: CDouble -> MutableByteArray# s -> CInt -> IO CInt
-
-foreign import ccall unsafe "hs-double-conversion.h _hs_ToExponential"
-    c_ToExponential :: CDouble -> Ptr Word8 -> CInt -> IO CInt
-
-foreign import ccall unsafe "hs-double-conversion.h _hs_Text_ToExponentialFloat"
-    c_Text_ToExponentialFloat :: CFloat -> MutableByteArray# s -> CInt -> IO CInt
-
-foreign import ccall unsafe "hs-double-conversion.h _hs_ToExponentialFloat"
-    c_ToExponentialFloat :: CFloat -> Ptr Word8 -> CInt -> IO CInt
-
-foreign import ccall unsafe "hs-double-conversion.h _hs_ToPrecisionLength"
-    c_ToPrecisionLength :: CInt
-
-foreign import ccall unsafe "hs-double-conversion.h _hs_Text_ToPrecision"
-    c_Text_ToPrecision :: CDouble -> MutableByteArray# s -> CInt -> IO CInt
-
-foreign import ccall unsafe "hs-double-conversion.h _hs_ToPrecision"
-    c_ToPrecision :: CDouble -> Ptr Word8 -> CInt -> IO CInt
-
-foreign import ccall unsafe "hs-double-conversion.h _hs_Text_ToPrecisionFloat"
-    c_Text_ToPrecisionFloat :: CFloat -> MutableByteArray# s -> CInt -> IO CInt
-
-foreign import ccall unsafe "hs-double-conversion.h _hs_ToPrecisionFloat"
-    c_ToPrecisionFloat :: CFloat -> Ptr Word8 -> CInt -> IO CInt
diff --git a/Data/Double/Conversion/Internal/ByteString.hs b/Data/Double/Conversion/Internal/ByteString.hs
new file mode 100644
--- /dev/null
+++ b/Data/Double/Conversion/Internal/ByteString.hs
@@ -0,0 +1,44 @@
+{-# LANGUAGE TypeFamilies #-}
+
+-- |
+-- Module      : Data.Double.Conversion.ByteString
+-- Copyright   : (c) 2011 MailRank, Inc.
+--
+-- License     : BSD-style
+-- Maintainer  : bos@serpentine.com
+-- Stability   : experimental
+-- Portability : GHC
+--
+-- Fast, efficient support for converting between double precision
+-- floating point values and text.
+--
+-- Although about 15 times faster than plain 'show', these functions
+-- are /slower/ than their 'Text' counterparts, at roughly half the
+-- speed.  (This seems to be due to the cost of allocating
+-- 'ByteString' values via @malloc@.)
+
+module Data.Double.Conversion.Internal.ByteString
+    ( convert
+    ) where
+
+import Control.Monad (when)
+import Data.ByteString.Internal (ByteString(..), mallocByteString)
+import Data.Double.Conversion.Internal.FFI (ForeignFloating)
+import Data.Word (Word8)
+import Foreign.C.Types (CDouble, CFloat, CInt)
+import Foreign.ForeignPtr (withForeignPtr)
+import Foreign.Ptr (Ptr)
+import System.IO.Unsafe (unsafePerformIO)
+
+convert :: (RealFloat a, RealFloat b , b ~ ForeignFloating a) => String -> CInt -> (b -> Ptr Word8 -> IO CInt)
+        -> a -> ByteString
+{-# SPECIALIZE convert :: String -> CInt -> (CDouble -> Ptr Word8 -> IO CInt) -> Double -> ByteString #-}
+{-# SPECIALIZE convert :: String -> CInt -> (CFloat -> Ptr Word8 -> IO CInt) -> Float -> ByteString #-}
+{-# INLINABLE convert #-}
+convert func len act val = unsafePerformIO $ do
+  fp <- mallocByteString (fromIntegral len)
+  size <- withForeignPtr fp $ act (realToFrac val)
+  when (size == -1) .
+    fail $ "Data.Double.Conversion.ByteString." ++ func ++
+           ": conversion failed (invalid precision requested)"
+  return $ PS fp 0 (fromIntegral size)
diff --git a/Data/Double/Conversion/Internal/ByteStringBuilder.hs b/Data/Double/Conversion/Internal/ByteStringBuilder.hs
new file mode 100644
--- /dev/null
+++ b/Data/Double/Conversion/Internal/ByteStringBuilder.hs
@@ -0,0 +1,40 @@
+{-# LANGUAGE TypeFamilies #-}
+
+-- |
+-- Module      : Data.Double.Conversion.ByteStringBuilder
+-- Copyright   : (c) 2011 MailRank, Inc.
+--
+-- License     : BSD-style
+-- Maintainer  : bos@serpentine.com
+-- Stability   : experimental
+-- Portability : GHC
+--
+-- Fast, efficient support for converting between double precision
+-- floating point values and bytestring builder.
+
+-- This functions are much slower on the single value, but also it is much faster in conversting big set of
+-- numbers, than bytestring functions. See benchmark.
+
+module Data.Double.Conversion.Internal.ByteStringBuilder
+    (convert
+    ) where
+
+import Control.Monad (when)
+
+import Data.ByteString.Builder.Prim.Internal (BoundedPrim, boundedPrim)
+
+import Data.Double.Conversion.Internal.FFI (ForeignFloating)
+import Data.Word (Word8)
+import Foreign.C.Types (CDouble, CFloat, CInt)
+import Foreign.Ptr (Ptr, plusPtr)
+
+convert :: (RealFloat a, RealFloat b , b ~ ForeignFloating a) => String -> CInt -> (b -> Ptr Word8 -> IO CInt) -> BoundedPrim a
+{-# SPECIALIZE convert :: String -> CInt -> (CDouble -> Ptr Word8 -> IO CInt) -> BoundedPrim Double #-}
+{-# SPECIALIZE convert :: String -> CInt -> (CFloat -> Ptr Word8 -> IO CInt) -> BoundedPrim Float #-}
+{-# INLINABLE convert #-}
+convert func len act = boundedPrim (fromIntegral len) $ \val ptr -> do
+  size <- act (realToFrac val) ptr
+  when (size == -1) .
+    fail $ "Data.Double.Conversion.ByteString." ++ func ++
+           ": conversion failed (invalid precision requested)"
+  return (ptr `plusPtr` (fromIntegral size))
diff --git a/Data/Double/Conversion/Internal/FFI.hs b/Data/Double/Conversion/Internal/FFI.hs
new file mode 100644
--- /dev/null
+++ b/Data/Double/Conversion/Internal/FFI.hs
@@ -0,0 +1,113 @@
+{-# LANGUAGE CPP, ForeignFunctionInterface, MagicHash, TypeFamilies,
+             UnliftedFFITypes #-}
+
+-- |
+-- Module      : Data.Double.Conversion.FFI
+-- Copyright   : (c) 2011 MailRank, Inc.
+--
+-- License     : BSD-style
+-- Maintainer  : bos@serpentine.com
+-- Stability   : experimental
+-- Portability : GHC
+--
+-- FFI interface support for converting between
+-- floating point values and text.
+
+module Data.Double.Conversion.Internal.FFI
+    (
+      ForeignFloating
+    , c_Text_ToExponential
+    , c_Text_ToExponentialFloat
+    , c_Text_ToFixed
+    , c_Text_ToFixedFloat
+    , c_Text_ToPrecision
+    , c_Text_ToPrecisionFloat
+    , c_Text_ToShortest
+    , c_Text_ToShortestFloat
+    , c_ToExponentialLength
+    , c_ToFixedLength
+    , c_ToPrecisionLength
+    , c_ToShortestLength
+    , c_ToExponential
+    , c_ToExponentialFloat
+    , c_ToFixed
+    , c_ToFixedFloat
+    , c_ToPrecision
+    , c_ToPrecisionFloat
+    , c_ToShortest
+    , c_ToShortestFloat
+    ) where
+
+import Data.Word (Word8)
+#if __GLASGOW_HASKELL__ >= 703
+import Foreign.C.Types (CDouble(CDouble), CFloat(CFloat), CInt(CInt))
+#else
+import Foreign.C.Types (CDouble, CFloat, CInt)
+#endif
+import Foreign.Ptr (Ptr)
+import GHC.Prim (MutableByteArray#)
+
+type family ForeignFloating h :: *
+
+type instance ForeignFloating Double = CDouble
+type instance ForeignFloating Float = CFloat
+
+foreign import ccall unsafe "hs-double-conversion.h _hs_ToShortestLength"
+    c_ToShortestLength :: CInt
+
+foreign import ccall unsafe "hs-double-conversion.h _hs_Text_ToShortest"
+    c_Text_ToShortest :: CDouble -> MutableByteArray# s -> IO CInt
+
+foreign import ccall unsafe "hs-double-conversion.h _hs_ToShortest"
+    c_ToShortest :: CDouble -> Ptr Word8 -> IO CInt
+
+foreign import ccall unsafe "hs-double-conversion.h _hs_Text_ToShortestFloat"
+    c_Text_ToShortestFloat :: CFloat -> MutableByteArray# s -> IO CInt
+
+foreign import ccall unsafe "hs-double-conversion.h _hs_ToShortestFloat"
+    c_ToShortestFloat :: CFloat -> Ptr Word8 -> IO CInt
+
+foreign import ccall unsafe "hs-double-conversion.h _hs_ToFixedLength"
+    c_ToFixedLength :: CInt
+
+foreign import ccall unsafe "hs-double-conversion.h _hs_Text_ToFixed"
+    c_Text_ToFixed :: CDouble -> MutableByteArray# s -> CInt -> IO CInt
+
+foreign import ccall unsafe "hs-double-conversion.h _hs_Text_ToFixedFloat"
+    c_Text_ToFixedFloat :: CFloat -> MutableByteArray# s -> CInt -> IO CInt
+
+foreign import ccall unsafe "hs-double-conversion.h _hs_ToFixed"
+    c_ToFixed :: CDouble -> Ptr Word8 -> CInt -> IO CInt
+
+foreign import ccall unsafe "hs-double-conversion.h _hs_ToFixedFloat"
+    c_ToFixedFloat :: CFloat -> Ptr Word8 -> CInt -> IO CInt
+
+foreign import ccall unsafe "hs-double-conversion.h _hs_ToExponentialLength"
+    c_ToExponentialLength :: CInt
+
+foreign import ccall unsafe "hs-double-conversion.h _hs_Text_ToExponential"
+    c_Text_ToExponential :: CDouble -> MutableByteArray# s -> CInt -> IO CInt
+
+foreign import ccall unsafe "hs-double-conversion.h _hs_ToExponential"
+    c_ToExponential :: CDouble -> Ptr Word8 -> CInt -> IO CInt
+
+foreign import ccall unsafe "hs-double-conversion.h _hs_Text_ToExponentialFloat"
+    c_Text_ToExponentialFloat :: CFloat -> MutableByteArray# s -> CInt -> IO CInt
+
+foreign import ccall unsafe "hs-double-conversion.h _hs_ToExponentialFloat"
+    c_ToExponentialFloat :: CFloat -> Ptr Word8 -> CInt -> IO CInt
+
+foreign import ccall unsafe "hs-double-conversion.h _hs_ToPrecisionLength"
+    c_ToPrecisionLength :: CInt
+
+foreign import ccall unsafe "hs-double-conversion.h _hs_Text_ToPrecision"
+    c_Text_ToPrecision :: CDouble -> MutableByteArray# s -> CInt -> IO CInt
+
+foreign import ccall unsafe "hs-double-conversion.h _hs_ToPrecision"
+    c_ToPrecision :: CDouble -> Ptr Word8 -> CInt -> IO CInt
+
+foreign import ccall unsafe "hs-double-conversion.h _hs_Text_ToPrecisionFloat"
+    c_Text_ToPrecisionFloat :: CFloat -> MutableByteArray# s -> CInt -> IO CInt
+
+foreign import ccall unsafe "hs-double-conversion.h _hs_ToPrecisionFloat"
+    c_ToPrecisionFloat :: CFloat -> Ptr Word8 -> CInt -> IO CInt
diff --git a/Data/Double/Conversion/Internal/Text.hs b/Data/Double/Conversion/Internal/Text.hs
new file mode 100644
--- /dev/null
+++ b/Data/Double/Conversion/Internal/Text.hs
@@ -0,0 +1,53 @@
+{-# LANGUAGE CPP, MagicHash, Rank2Types, TypeFamilies #-}
+
+-- |
+-- Module      : Data.Double.Conversion.Text
+-- Copyright   : (c) 2011 MailRank, Inc.
+--
+-- License     : BSD-style
+-- Maintainer  : bos@serpentine.com
+-- Stability   : experimental
+-- Portability : GHC
+--
+-- Fast, efficient support for converting between double precision
+-- floating point values and text.
+--
+-- These functions are about 30 times faster than the default 'show'
+-- implementation for the 'Double' type.
+
+module Data.Double.Conversion.Internal.Text
+    (
+      convert
+    ) where
+
+import Control.Monad (when)
+#if MIN_VERSION_base(4,4,0)
+import Control.Monad.ST.Unsafe (unsafeIOToST)
+#else
+import Control.Monad.ST (unsafeIOToST)
+#endif
+import Control.Monad.ST (ST, runST)
+import Data.Double.Conversion.Internal.FFI (ForeignFloating)
+import qualified Data.Text.Array as A
+import Data.Text.Internal (Text(Text))
+import Foreign.C.Types (CDouble, CFloat, CInt)
+import GHC.Prim (MutableByteArray#)
+
+
+convert :: (RealFloat a, RealFloat b, b ~ ForeignFloating a) => String -> CInt
+        -> (forall s. b -> MutableByteArray# s -> IO CInt)
+        -> a -> Text
+{-# SPECIALIZE convert :: String -> CInt -> (forall s. CDouble -> MutableByteArray# s -> IO CInt) -> Double -> Text #-}
+{-# SPECIALIZE convert :: String -> CInt -> (forall s. CFloat -> MutableByteArray# s -> IO CInt) -> Float -> Text #-}
+{-# INLINABLE convert #-}
+convert func len act val = runST go
+  where
+    go :: (forall s. ST s Text)
+    go = do
+      buf <- A.new (fromIntegral len)
+      size <- unsafeIOToST $ act (realToFrac val) (A.maBA buf)
+      when (size == -1) .
+        fail $ "Data.Double.Conversion.Text." ++ func ++
+               ": conversion failed (invalid precision requested)"
+      frozen <- A.unsafeFreeze buf
+      return $ Text frozen 0 (fromIntegral size)
diff --git a/Data/Double/Conversion/Internal/TextBuilder.hs b/Data/Double/Conversion/Internal/TextBuilder.hs
new file mode 100644
--- /dev/null
+++ b/Data/Double/Conversion/Internal/TextBuilder.hs
@@ -0,0 +1,45 @@
+{-# LANGUAGE CPP, MagicHash, Rank2Types, TypeFamilies #-}
+-- |
+-- Module      : Data.Double.Conversion.TextBuilder
+-- Copyright   : (c) 2011 MailRank, Inc.
+--
+-- License     : BSD-style
+-- Maintainer  : bos@serpentine.com
+-- Stability   : experimental
+-- Portability : GHC
+--
+-- Fast, efficient support for converting between double precision
+-- floating point values and text.
+--
+
+module Data.Double.Conversion.Internal.TextBuilder
+    (
+      convert
+    ) where
+
+
+import Control.Monad (when)
+#if MIN_VERSION_base(4,4,0)
+import Control.Monad.ST.Unsafe (unsafeIOToST)
+#else
+import Control.Monad.ST (unsafeIOToST)
+#endif
+import Data.Double.Conversion.Internal.FFI (ForeignFloating)
+import qualified Data.Text.Array as A
+import Data.Text.Internal.Builder (Builder, writeN)
+import Foreign.C.Types (CDouble, CFloat, CInt)
+import GHC.Prim (MutableByteArray#)
+
+-- | Not implemented yet 
+convert :: (RealFloat a, RealFloat b, b ~ ForeignFloating a) => String -> CInt
+        -> (forall s. b -> MutableByteArray# s -> IO CInt)
+        -> a -> Builder
+{-# SPECIALIZE convert :: String -> CInt -> (forall s. CDouble -> MutableByteArray# s -> IO CInt) -> Double -> Builder #-}
+{-# SPECIALIZE convert :: String -> CInt -> (forall s. CFloat -> MutableByteArray# s -> IO CInt) -> Float -> Builder #-}
+{-# INLINABLE convert #-}
+convert func len act val = writeN (fromIntegral len) $ \(A.MArray maBa) _ -> do
+    size <- unsafeIOToST $ act (realToFrac val) maBa
+    when (size == -1) .
+        fail $ "Data.Double.Conversion.Text." ++ func ++
+               ": conversion failed (invalid precision requested)"
+    return ()
diff --git a/Data/Double/Conversion/Text.hs b/Data/Double/Conversion/Text.hs
--- a/Data/Double/Conversion/Text.hs
+++ b/Data/Double/Conversion/Text.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE CPP, MagicHash, Rank2Types, TypeFamilies #-}
+{-# LANGUAGE CPP, MagicHash, Rank2Types #-}
 
 -- |
 -- Module      : Data.Double.Conversion.Text
@@ -9,6 +9,10 @@
 -- Stability   : experimental
 -- Portability : GHC
 --
+-- This module left now only for compatibility and should not be used
+-- in new projects. 
+-- Please, use Convertable type class from Data.Double.Conversion.Convertable
+--
 -- Fast, efficient support for converting between double precision
 -- floating point values and text.
 --
@@ -17,37 +21,33 @@
 
 module Data.Double.Conversion.Text
     (
-      convert
+      toExponential
+    , toFixed
+    , toPrecision
+    , toShortest
     ) where
 
-import Control.Monad (when)
-#if MIN_VERSION_base(4,4,0)
-import Control.Monad.ST.Unsafe (unsafeIOToST)
-#else
-import Control.Monad.ST (unsafeIOToST)
-#endif
-import Control.Monad.ST (ST, runST)
-import Data.Double.Conversion.FFI (ForeignFloating)
-import qualified Data.Text.Array as A
-import Data.Text.Internal (Text(Text))
-import Foreign.C.Types (CDouble, CFloat, CInt)
-import GHC.Prim (MutableByteArray#)
+import qualified Data.Double.Conversion.Convertable
+import Data.Text.Internal (Text)
 
+-- | Compute a representation in exponential format with the requested
+-- number of digits after the decimal point. The last emitted digit is
+-- rounded.  If -1 digits are requested, then the shortest exponential
+-- representation is computed.
+toExponential :: Int -> Double -> Text
+toExponential = Data.Double.Conversion.Convertable.toExponential
 
-convert :: (RealFloat a, RealFloat b, b ~ ForeignFloating a) => String -> CInt
-        -> (forall s. b -> MutableByteArray# s -> IO CInt)
-        -> a -> Text
-{-# SPECIALIZE convert :: String -> CInt -> (forall s. CDouble -> MutableByteArray# s -> IO CInt) -> Double -> Text #-}
-{-# SPECIALIZE convert :: String -> CInt -> (forall s. CFloat -> MutableByteArray# s -> IO CInt) -> Float -> Text #-}
-{-# INLINABLE convert #-}
-convert func len act val = runST go
-  where
-    go :: (forall s. ST s Text)
-    go = do
-      buf <- A.new (fromIntegral len)
-      size <- unsafeIOToST $ act (realToFrac val) (A.maBA buf)
-      when (size == -1) .
-        fail $ "Data.Double.Conversion.Text." ++ func ++
-               ": conversion failed (invalid precision requested)"
-      frozen <- A.unsafeFreeze buf
-      return $ Text frozen 0 (fromIntegral size)
+-- | Compute a decimal representation with a fixed number of digits
+-- after the decimal point. The last emitted digit is rounded.
+toFixed :: Int -> Double -> Text
+toFixed = Data.Double.Conversion.Convertable.toFixed
+
+-- | Compute the shortest string of digits that correctly represent
+-- the input number.
+toShortest :: Double -> Text
+toShortest = Data.Double.Conversion.Convertable.toShortest
+
+-- | Compute @precision@ leading digits of the given value either in
+-- exponential or decimal format. The last computed digit is rounded.
+toPrecision :: Int -> Double -> Text
+toPrecision = Data.Double.Conversion.Convertable.toPrecision
diff --git a/Data/Double/Conversion/TextBuilder.hs b/Data/Double/Conversion/TextBuilder.hs
deleted file mode 100644
--- a/Data/Double/Conversion/TextBuilder.hs
+++ /dev/null
@@ -1,44 +0,0 @@
-{-# LANGUAGE CPP, MagicHash, Rank2Types, TypeFamilies #-}
--- |
--- Module      : Data.Double.Conversion.TextBuilder
--- Copyright   : (c) 2011 MailRank, Inc.
---
--- License     : BSD-style
--- Maintainer  : bos@serpentine.com
--- Stability   : experimental
--- Portability : GHC
---
--- Fast, efficient support for converting between double precision
--- floating point values and text.
---
-
-module Data.Double.Conversion.TextBuilder
-    (
-      convert
-    ) where
-
-
-import Control.Monad (when)
-#if MIN_VERSION_base(4,4,0)
-import Control.Monad.ST.Unsafe (unsafeIOToST)
-#else
-import Control.Monad.ST (unsafeIOToST)
-#endif
-import Data.Double.Conversion.FFI (ForeignFloating)
-import qualified Data.Text.Array as A
-import Data.Text.Internal.Builder (Builder, writeN)
-import Foreign.C.Types (CDouble, CFloat, CInt)
-import GHC.Prim (MutableByteArray#)
-
-convert :: (RealFloat a, RealFloat b, b ~ ForeignFloating a) => String -> CInt
-        -> (forall s. b -> MutableByteArray# s -> IO CInt)
-        -> a -> Builder
-{-# SPECIALIZE convert :: String -> CInt -> (forall s. CDouble -> MutableByteArray# s -> IO CInt) -> Double -> Builder #-}
-{-# SPECIALIZE convert :: String -> CInt -> (forall s. CFloat -> MutableByteArray# s -> IO CInt) -> Float -> Builder #-}
-{-# INLINABLE convert #-}
-convert func len act val = writeN (fromIntegral len) $ \(A.MArray maBa) _ -> do
-    size <- unsafeIOToST $ act (realToFrac val) maBa
-    when (size == -1) .
-        fail $ "Data.Double.Conversion.Text." ++ func ++
-               ": conversion failed (invalid precision requested)"
-    return ()
diff --git a/README.markdown b/README.markdown
--- a/README.markdown
+++ b/README.markdown
@@ -11,17 +11,11 @@
 and other improvements.
 
 Please report bugs via the
-[github issue tracker](https://github.com/bos/double-conversion/issues).
-
-Master [git repository](https://github.com/bos/double-conversion):
-
-* `git clone git://github.com/bos/double-conversion.git`
-
-There's also a [Mercurial mirror](https://bitbucket.org/bos/double-conversion):
+[github issue tracker](https://github.com/haskell/double-conversion/issues).
 
-* `hg clone https://bitbucket.org/bos/double-conversion`
+Master [git repository](https://github.com/haskell/double-conversion):
 
-(You can create and contribute changes using either git or Mercurial.)
+* `git clone git://github.com/haskell/double-conversion`
 
 Authors
 -------
diff --git a/double-conversion.cabal b/double-conversion.cabal
--- a/double-conversion.cabal
+++ b/double-conversion.cabal
@@ -1,5 +1,5 @@
 name:           double-conversion
-version:        2.0.3.0
+version:        2.0.4.0
 license:        BSD3
 license-file:   LICENSE
 homepage:       https://github.com/Haskell-mouse/double-conversion
@@ -94,19 +94,21 @@
 
   exposed-modules:
     Data.Double.Conversion.Convertable
-
-  other-modules:
-    Data.Double.Conversion.FFI
     Data.Double.Conversion.ByteString
-    Data.Double.Conversion.ByteStringBuilder
     Data.Double.Conversion.Text
-    Data.Double.Conversion.TextBuilder
 
+  other-modules:
+    Data.Double.Conversion.Internal.FFI
+    Data.Double.Conversion.Internal.ByteString
+    Data.Double.Conversion.Internal.ByteStringBuilder
+    Data.Double.Conversion.Internal.Text
+    Data.Double.Conversion.Internal.TextBuilder
+
   build-depends:
     base == 4.*,
     bytestring,
     ghc-prim,
-    text >= 0.11.0.8
+    text >= 0.11.0.8 && < 2.0
 
   if flag(developer)
     ghc-options: -Werror 
