diff --git a/Text/Coffee.hs b/Text/Coffee.hs
--- a/Text/Coffee.hs
+++ b/Text/Coffee.hs
@@ -3,66 +3,79 @@
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE CPP #-}
 {-# OPTIONS_GHC -fno-warn-missing-fields #-}
+-- | A Shakespearean module for CoffeeScript, introducing type-safe,
+-- compile-time variable and url interpolation. It is exactly the same as
+-- "Text.Julius", except that the template is first compiled to Javascript with
+-- the system tool @coffee@.
+--
+-- To use this module, @coffee@ must be installed on your system.
+--
+-- @#{...}@ is the Shakespearean standard for variable interpolation, but
+-- CoffeeScript already uses that sequence for string interpolation. Therefore,
+-- Shakespearean interpolation is introduced with @%{...}@.
+--
+-- Further reading:
+--
+-- 1. Shakespearean templates: <http://www.yesodweb.com/book/templates>
+--
+-- 2. CoffeeScript: <http://coffeescript.org/>
 module Text.Coffee
-    ( ToCoffee (..)
-    , CoffeeUrl
-    , Coffeescript
-    , coffee
+    ( -- * Functions
+      -- ** Template-Reading Functions
+      -- | These QuasiQuoter and Template Haskell methods return values of
+      -- type @'JavascriptUrl' url@. See the Yesod book for details.
+      coffee
     , coffeeFile
+    , coffeeFileReload
     , coffeeFileDebug
-    , renderCoffee
+
+#ifdef TEST_EXPORT
+    , coffeeSettings
+#endif
     ) where
 
 import Language.Haskell.TH.Quote (QuasiQuoter (..))
 import Language.Haskell.TH.Syntax
-import Data.Text.Lazy.Builder (Builder, fromText, toLazyText, fromLazyText)
-import qualified Data.Text as TS
-import qualified Data.Text.Lazy as TL
-import System.Process (readProcess)
-import Data.Monoid
 import Text.Shakespeare
-
-renderCoffee :: (url -> [(TS.Text, TS.Text)] -> TS.Text) -> CoffeeUrl url -> IO TL.Text
-renderCoffee r s = do
-  out <- readProcess "coffee" ["-epb", TL.unpack $ toLazyText $ unCoffee $ s r] []
-  return $ TL.pack out
-  where unCoffee (Coffeescript c) = c
-
-newtype Coffeescript = Coffeescript { unCoffeescript :: Builder }
-    deriving Monoid
-
-type CoffeeUrl url = (url -> [(TS.Text, TS.Text)] -> TS.Text) -> Coffeescript
-
--- the types that can be placed in a template
-class ToCoffee c where
-    toCoffee :: c -> Builder
-instance ToCoffee [Char]  where toCoffee = fromLazyText . TL.pack
-instance ToCoffee TS.Text where toCoffee = fromText
-instance ToCoffee TL.Text where toCoffee = fromLazyText
+import Text.Julius
 
-settings :: Q ShakespeareSettings
-settings = do
-  toExp <- [|toCoffee|]
-  wrapExp <- [|Coffeescript|]
-  unWrapExp <- [|unCoffeescript|]
-  return $ defaultShakespeareSettings { varChar = '%'
-  , toBuilder = toExp
-  , wrap = wrapExp
-  , unwrap = unWrapExp
+coffeeSettings :: Q ShakespeareSettings
+coffeeSettings = do
+  jsettings <- javascriptSettings
+  return $ jsettings { varChar = '%'
+  , preConversion = Just PreConvert {
+      preConvert = ReadProcess "coffee" ["-epb"]
+    , preEscapeBegin = "`"
+    -- ^ backticks means the Coffeescript compiler will pass-through to javascript.
+    , preEscapeEnd = "`"
+    , preEscapeIgnore = "'\"`"
+    -- ^ backticks are ignored inside a quote
+    }
   }
 
+-- | Read inline, quasiquoted CoffeeScript.
 coffee :: QuasiQuoter
 coffee = QuasiQuoter { quoteExp = \s -> do
-    rs <- settings
+    rs <- coffeeSettings
     quoteExp (shakespeare rs) s
     }
 
+-- | Read in a CoffeeScript template file. This function reads the file once, at
+-- compile time.
 coffeeFile :: FilePath -> Q Exp
 coffeeFile fp = do
-    rs <- settings
+    rs <- coffeeSettings
     shakespeareFile rs fp
 
-coffeeFileDebug :: FilePath -> Q Exp
-coffeeFileDebug fp = do
-    rs <- settings
+-- | Read in a CoffeeScript template file. This impure function uses
+-- unsafePerformIO to re-read the file on every call, allowing for rapid
+-- iteration.
+coffeeFileReload :: FilePath -> Q Exp
+coffeeFileReload fp = do
+    rs <- coffeeSettings
     shakespeareFileDebug rs fp
+
+-- | Deprecated synonym for 'coffeeFileReload'
+coffeeFileDebug :: FilePath -> Q Exp
+coffeeFileDebug = coffeeFileReload
+{-# DEPRECATED coffeeFileDebug "Please use coffeeFileReload instead." #-}
diff --git a/Text/Julius.hs b/Text/Julius.hs
--- a/Text/Julius.hs
+++ b/Text/Julius.hs
@@ -3,14 +3,21 @@
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE CPP #-}
 {-# OPTIONS_GHC -fno-warn-missing-fields #-}
--- | This module is currently in an identity crisis. Originally called Julius, now being changed to just Javascript (shakespeare-javascript)
+-- | A Shakespearean module for Javascript templates, introducing type-safe,
+-- compile-time variable and url interpolation.--
+-- To use this module, @coffee@ must be installed on your system.
+--
+-- You might consider trying 'Text.Coffee', which compiles down to Javascript.
+--
+-- Further reading: <http://www.yesodweb.com/book/templates>
+--
+-- This module is currently in an identity crisis. Originally called Julius, now being changed to just Javascript (shakespeare-javascript)
 module Text.Julius
-    ( JavascriptUrl
-    , Javascript (..)
-    , ToJavascript (..)
-    , renderJavascript
-    , renderJavascriptUrl
-    , js
+    ( -- * Functions
+      -- ** Template-Reading Functions
+      -- | These QuasiQuoter and Template Haskell methods return values of
+      -- type @'JavascriptUrl' url@. See the Yesod book for details.
+      js
     , julius
     , juliusFile
     , jsFile
@@ -18,6 +25,20 @@
     , jsFileDebug
     , juliusFileReload
     , jsFileReload
+
+      -- * Datatypes
+    , JavascriptUrl
+    , Javascript (..)
+
+      -- * Typeclass for interpolated variables
+    , ToJavascript (..)
+
+      -- ** Rendering Functions
+    , renderJavascript
+    , renderJavascriptUrl
+
+      -- ** internal, used by 'Text.Coffee'
+    , javascriptSettings
     ) where
 
 import Language.Haskell.TH.Quote (QuasiQuoter (..))
@@ -31,21 +52,32 @@
 renderJavascript :: Javascript -> TL.Text
 renderJavascript (Javascript b) = toLazyText b
 
+-- | render with route interpolation. If using this module standalone, apart
+-- from type-safe routes, a dummy renderer can be used:
+-- 
+-- > renderJavascriptUrl (\_ _ -> undefined) javascriptUrl
+--
+-- When using Yesod, a renderer is generated for you, which can be accessed
+-- within the GHandler monad: 'Yesod.Handler.getUrlRenderParams'.
 renderJavascriptUrl :: (url -> [(TS.Text, TS.Text)] -> TS.Text) -> JavascriptUrl url -> TL.Text
 renderJavascriptUrl r s = renderJavascript $ s r
 
+-- | Newtype wrapper of 'Builder'.
 newtype Javascript = Javascript { unJavascript :: Builder }
     deriving Monoid
+
+-- | Return type of template-reading functions.
 type JavascriptUrl url = (url -> [(TS.Text, TS.Text)] -> TS.Text) -> Javascript
 
+-- | A typeclass for types that can be interpolated in CoffeeScript templates.
 class ToJavascript a where
     toJavascript :: a -> Builder
 instance ToJavascript [Char] where toJavascript = fromLazyText . TL.pack
 instance ToJavascript TS.Text where toJavascript = fromText
 instance ToJavascript TL.Text where toJavascript = fromLazyText
 
-settings :: Q ShakespeareSettings
-settings = do
+javascriptSettings :: Q ShakespeareSettings
+javascriptSettings = do
   toJExp <- [|toJavascript|]
   wrapExp <- [|Javascript|]
   unWrapExp <- [|unJavascript|]
@@ -56,7 +88,7 @@
 
 js, julius :: QuasiQuoter
 js = QuasiQuoter { quoteExp = \s -> do
-    rs <- settings
+    rs <- javascriptSettings
     quoteExp (shakespeare rs) s
     }
 
@@ -64,19 +96,21 @@
 
 jsFile, juliusFile :: FilePath -> Q Exp
 jsFile fp = do
-    rs <- settings
+    rs <- javascriptSettings
     shakespeareFile rs fp
 
 juliusFile = jsFile
 
 
-jsFileDebug, juliusFileDebug :: FilePath -> Q Exp
-jsFileDebug fp = do
-    rs <- settings
+jsFileReload, juliusFileReload :: FilePath -> Q Exp
+jsFileReload fp = do
+    rs <- javascriptSettings
     shakespeareFileDebug rs fp
 
-juliusFileDebug = jsFileDebug
+juliusFileReload = jsFileReload
 
-jsFileReload, juliusFileReload :: FilePath -> Q Exp
-juliusFileReload = jsFileDebug
-jsFileReload = jsFileDebug
+jsFileDebug, juliusFileDebug :: FilePath -> Q Exp
+juliusFileDebug = jsFileReload
+{-# DEPRECATED juliusFileDebug "Please use juliusFileReload instead." #-}
+jsFileDebug = jsFileReload
+{-# DEPRECATED jsFileDebug "Please use jsFileReload instead." #-}
diff --git a/shakespeare-js.cabal b/shakespeare-js.cabal
--- a/shakespeare-js.cabal
+++ b/shakespeare-js.cabal
@@ -1,5 +1,5 @@
 name:            shakespeare-js
-version:         0.10.4
+version:         0.11.0
 license:         BSD3
 license-file:    LICENSE
 author:          Michael Snoyman <michael@snoyman.com>
@@ -29,28 +29,48 @@
 
 library
     build-depends:   base             >= 4       && < 5
-                   , shakespeare      >= 0.10    && < 0.11
+                   , shakespeare      >= 0.10.3  && < 0.11
                    , template-haskell
                    , text             >= 0.7     && < 0.12
-                   , process          >= 1.0     && < 1.2
 
     exposed-modules:
                      Text.Julius
                      Text.Coffee
     ghc-options:     -Wall
+    if impl(ghc >= 7.4)
+       cpp-options: -DGHC_7_4
 
+    if flag(test_coffee)
+        cpp-options: -DTEST_COFFEE
+
+    if flag(test_export)
+        cpp-options: -DTEST_EXPORT
+
+flag test_export
+    default: False
+
+flag test_coffee
+    description: render tests through coffeescript render function
+    -- cabal configure --enable-tests -ftest_coffee && cabal build && dist/build/test/test
+    default: False
+
 test-suite test
     hs-source-dirs: test
     main-is: ../test.hs
     type: exitcode-stdio-1.0
 
     ghc-options:   -Wall
-    build-depends: shakespeare-js   >= 0.10    && < 0.11
-                 , shakespeare      >= 0.10    && < 0.11
+    build-depends: shakespeare-js   >= 0.11    && < 0.12
+                 , shakespeare      >= 0.10.3  && < 0.11
                  , base             >= 4       && < 5
                  , HUnit
                  , hspec            >= 0.8     && < 0.10
                  , text             >= 0.7     && < 0.12
+                 , template-haskell
+
+-- cabal bug
+--    if flag(test_coffee)
+--        cpp-options: -DTEST_COFFEE
 
 
 source-repository head
diff --git a/test.hs b/test.hs
--- a/test.hs
+++ b/test.hs
@@ -1,5 +1,5 @@
-import Test.Hspec
+import Test.Hspec.Monadic
 import ShakespeareJsTest (specs)
 
 main :: IO ()
-main = hspecX $ descriptions [specs]
+main = hspecX specs
diff --git a/test/ShakespeareJsTest.hs b/test/ShakespeareJsTest.hs
--- a/test/ShakespeareJsTest.hs
+++ b/test/ShakespeareJsTest.hs
@@ -1,13 +1,18 @@
 {-# LANGUAGE QuasiQuotes #-}
 {-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE CPP #-}
 module ShakespeareJsTest (specs) where
 
 import Test.HUnit hiding (Test)
-import Test.Hspec
+import Test.Hspec.Monadic
 import Test.Hspec.HUnit ()
 
 import Prelude hiding (reverse)
+#ifdef TEST_COFFEE
+import Text.Coffee
+#endif
 import Text.Julius
+import Quoter (quote, quoteFile, quoteFileReload)
 import Data.List (intercalate)
 import qualified Data.Text.Lazy as T
 import qualified Data.List
@@ -15,78 +20,85 @@
 import Data.Text (Text, pack, unpack)
 import Data.Monoid (mappend)
 
-specs :: [Spec]
-specs = describe "shakespeare-js"
-  [ it "julius" $ do
-    let var = "var"
+join :: [String] -> String
+#ifdef TEST_COFFEE
+join l = (intercalate ";\n" l)
+#else
+join = intercalate "\n"
+#endif
+
+specs :: Specs
+specs = describe "shakespeare-js" $ do
+  it "julius" $ do
+    let var = "x=2"
     let urlp = (Home, [(pack "p", pack "q")])
-    flip jelper [julius|שלום
-#{var}
-@{Home}
-@?{urlp}
-^{jmixin}
-|] $ intercalate "\r\n"
-        [ "שלום"
-        , var
-        , "url"
-        , "url?p=q"
-        , "var x;"
-        ] ++ "\r\n"
+    flip jelper [quote|['שלום', @{Home}, #{var}, '@?{urlp}', ^{jmixin} ]|]
+      $ intercalate " "
+        [ "['שלום',"
+        , "url, " ++ var ++ ","
+        , "'url?p=q',"
+        , "f(2) ]"
+        ]
 
 
-  , it "juliusFile" $ do
-    let var = "var"
+  it "juliusFile" $ do
+    let var = "x=2"
     let urlp = (Home, [(pack "p", pack "q")])
-    flip jelper $(juliusFile "test/juliuses/external1.julius") $ unlines
+    flip jelper $(quoteFile "test/juliuses/external1.julius") $ join
         [ "שלום"
         , var
         , "url"
         , "url?p=q"
-        , "var x;"
-        ]
+        , "f(2)"
+        ] ++ "\n"
 
 
-  , it "juliusFileDebug" $ do
-    let var = "var"
+  it "juliusFileReload" $ do
+    let var = "x=2"
     let urlp = (Home, [(pack "p", pack "q")])
-    flip jelper $(juliusFileDebug "test/juliuses/external1.julius") $ unlines
+    flip jelper $(quoteFileReload "test/juliuses/external1.julius") $ join
         [ "שלום"
         , var
         , "url"
         , "url?p=q"
-        , "var x;"
-        ]
+        , "f(2)"
+        ] ++ "\n"
 
 {- TODO
-  , it "juliusFileDebugChange" $ do
-      let var = "somevar"
-          test result = jelper result $(juliusFileDebug "test/juliuses/external2.julius")
-      writeFile "test/juliuses/external2.julius" "var #{var} = 1;"
-      test "var somevar = 1;"
-      writeFile "test/juliuses/external2.julius" "var #{var} = 2;"
-      test "var somevar = 2;"
-      writeFile "test/juliuses/external2.julius" "var #{var} = 1;"
-      -}
+  it "juliusFileDebugChange" $ do
+    let var = "somevar"
+        test result = jelper result $(juliusFileDebug "test/juliuses/external2.julius")
+    writeFile "test/juliuses/external2.julius" "var #{var} = 1;"
+    test "var somevar = 1;"
+    writeFile "test/juliuses/external2.julius" "var #{var} = 2;"
+    test "var somevar = 2;"
+    writeFile "test/juliuses/external2.julius" "var #{var} = 1;"
+    -}
 
 
-  , it "julius module names" $
+  it "julius module names" $
     let foo = "foo"
         double = 3.14 :: Double
-        int = -5 :: Int in
-      jelper "oof oof 3.14 -5"
-        [julius|#{Data.List.reverse foo} #{L.reverse foo} #{show double} #{show int}|]
+        int = -5 :: Int
+    in jelper "[oof, oof, 3.14, -5]"
+#ifdef TEST_COFFEE
+         [quote|[%{Data.List.reverse foo}, %{L.reverse foo}, %{show double}, %{show int}]|]
+#else
+         [quote|[#{Data.List.reverse foo}, #{L.reverse foo}, #{show double}, #{show int}]|]
+#endif
 
 
-  , it "single dollar at and caret" $ do
-    jelper "$@^" [julius|$@^|]
-    jelper "#{@{^{" [julius|#\{@\{^\{|]
-
+-- not valid coffeescript
+#ifndef TEST_COFFEE
+  it "single dollar at and caret" $ do
+    jelper "$@^" [quote|$@^|]
+    jelper "#{@{^{" [quote|#\{@\{^\{|]
+#endif
 
-  , it "dollar operator" $ do
+  it "dollar operator" $ do
     let val = (1 :: Int, (2 :: Int, 3 :: Int))
-    jelper "2" [julius|#{ show $ fst $ snd val }|]
-    jelper "2" [julius|#{ show $ fst $ snd $ val}|]
-  ]
+    jelper "2" [quote|#{ show $ fst $ snd val }|]
+    jelper "2" [quote|#{ show $ fst $ snd $ val}|]
 
 
 
@@ -131,10 +143,11 @@
 
 
 jmixin :: JavascriptUrl u
-jmixin = [julius|var x;|]
+jmixin = [quote|f(2)|]
 
 jelper :: String -> JavascriptUrl Url -> Assertion
-jelper res h = T.pack res @=? renderJavascriptUrl render h
+jelper res h = do
+  T.pack res @=? renderJavascriptUrl render h
 
 instance Show Url where
     show _ = "FIXME remove this instance show Url"
