diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -46,7 +46,7 @@
         -- Here you would display the search bar plus results.
         return never
   -- With the handler constructed, run the router with the uri.
-  result <- runExceptT $ runRoute uri myApi handler
+  result <- runRoute uri myApi handler
   case result of
     -- If 'Left', there was no correct route for the uri.
     Left _ -> do
diff --git a/servant-router.cabal b/servant-router.cabal
--- a/servant-router.cabal
+++ b/servant-router.cabal
@@ -1,5 +1,5 @@
 name:                servant-router
-version:             0.8.1
+version:             0.9.0
 synopsis:            Servant router for non-server applications.
 description:         Write Servant APIs to be routed without a server.
 homepage:            https://github.com/ElvishJerricco/servant-router
@@ -23,7 +23,6 @@
                      , http-types     == 0.9.*
                      , network-uri    == 2.6.*
                      , bytestring     == 0.10.*
-                     , mtl            == 2.2.*
   default-language:    Haskell2010
   ghc-options:         -Wall
 
@@ -34,7 +33,6 @@
   build-depends:       base
                      , servant-router
                      , servant
-                     , mtl
   ghc-options:         -Wall -threaded -rtsopts -with-rtsopts=-N
   default-language:    Haskell2010
 
@@ -46,7 +44,6 @@
                      , servant-router
                      , servant-server
                      , servant-blaze
-                     , mtl
                      , warp
                      , blaze-html
   ghc-options:         -Wall -threaded -rtsopts -with-rtsopts=-N
diff --git a/src/Servant/Router.hs b/src/Servant/Router.hs
--- a/src/Servant/Router.hs
+++ b/src/Servant/Router.hs
@@ -9,7 +9,6 @@
 
 module Servant.Router where
 
-import           Control.Monad.Except
 import qualified Data.ByteString.Char8 as BS
 import           Data.Proxy
 import           Data.Text             (Text)
@@ -133,8 +132,8 @@
 -- | Use a handler to route a 'Location'.
 -- Normally 'runRoute' should be used instead, unless you want custom
 -- handling of string failing to parse as 'URI'.
-runRouteLoc :: forall layout m a. (HasRouter layout, MonadError RoutingError m)
-         => Location -> Proxy layout -> RouteT layout m a -> m a
+runRouteLoc :: forall layout m a. (HasRouter layout, Monad m)
+         => Location -> Proxy layout -> RouteT layout m a -> m (Either RoutingError a)
 runRouteLoc loc layout page =
   let routing = route layout (Proxy :: Proxy m) (Proxy :: Proxy a) page
   in routeLoc loc routing
@@ -142,44 +141,47 @@
 -- | Use a handler to route a location, represented as a 'String'.
 -- All handlers must, in the end, return @m a@.
 -- 'routeLoc' will choose a route and return its result.
-runRoute :: forall layout m a. (HasRouter layout, MonadError RoutingError m)
-         => String -> Proxy layout -> RouteT layout m a -> m a
+runRoute :: forall layout m a. (HasRouter layout, Monad m)
+         => String -> Proxy layout -> RouteT layout m a -> m (Either RoutingError a)
 runRoute uriString layout page = case uriToLocation <$> parseURIReference uriString of
-  Nothing -> throwError FailFatal
+  Nothing -> return $ Left FailFatal
   Just loc -> runRouteLoc loc layout page
 
 -- | Use a computed 'Router' to route a 'Location'.
-routeLoc :: MonadError RoutingError m => Location -> Router m a -> m a
+routeLoc :: Monad m => Location -> Router m a -> m (Either RoutingError a)
 routeLoc loc r = case r of
-  RChoice a b -> catchError (routeLoc loc a) $ \e -> case e of
-    Fail -> routeLoc loc b
-    FailFatal -> throwError e
+  RChoice a b -> do
+    result <- routeLoc loc a
+    case result of
+      Left Fail -> routeLoc loc b
+      Left FailFatal -> return $ Left FailFatal
+      Right x -> return $ Right x
   RCapture f -> case locPath loc of
-    [] -> throwError Fail
+    [] -> return $ Left Fail
     capture:paths -> maybe
-      (throwError FailFatal)
+      (return $ Left FailFatal)
       (routeLoc loc { locPath = paths })
       (f <$> parseUrlPieceMaybe capture)
   RQueryParam sym f -> case lookup (BS.pack $ symbolVal sym) (locQuery loc) of
     Nothing -> routeLoc loc $ f Nothing
-    Just Nothing -> throwError FailFatal
+    Just Nothing -> return $ Left FailFatal
     Just (Just text) -> case parseQueryParamMaybe (decodeUtf8 text) of
-      Nothing -> throwError FailFatal
+      Nothing -> return $ Left FailFatal
       Just x -> routeLoc loc $ f (Just x)
-  RQueryParams sym f -> maybe (throwError FailFatal) (routeLoc loc . f) $ do
+  RQueryParams sym f -> maybe (return $ Left FailFatal) (routeLoc loc . f) $ do
     ps <- sequence $ snd <$> filter
       (\(k, _) -> k == BS.pack (symbolVal sym)) (locQuery loc)
     sequence $ (parseQueryParamMaybe . decodeUtf8) <$> ps
   RQueryFlag sym f -> case lookup (BS.pack $ symbolVal sym) (locQuery loc) of
     Nothing -> routeLoc loc $ f False
     Just Nothing -> routeLoc loc $ f True
-    Just (Just _) -> throwError FailFatal
+    Just (Just _) -> return $ Left FailFatal
   RPath sym a -> case locPath loc of
-    [] -> throwError Fail
+    [] -> return $ Left Fail
     p:paths -> if p == T.pack (symbolVal sym)
       then routeLoc (loc { locPath = paths }) a
-      else throwError Fail
-  RPage a -> a
+      else return $ Left Fail
+  RPage a -> Right <$> a
 
 -- | Convert a 'URI' to a 'Location'.
 uriToLocation :: URI -> Location
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -1,9 +1,8 @@
 {-# LANGUAGE DataKinds     #-}
 {-# LANGUAGE TypeOperators #-}
 
-import           Control.Monad.Except
+import           Data.Foldable
 import           Data.Proxy
-import           Data.Traversable
 import           Servant.API
 import           Servant.Router
 
@@ -24,10 +23,10 @@
 
 main :: IO ()
 main = do
-  let root :: Int -> Maybe String -> ExceptT RoutingError IO ()
-      root i s = liftIO $ print (i, s)
-      other :: String -> ExceptT RoutingError IO ()
-      other s = liftIO $ print s
-  void $ for testUris $ \uri -> do
-    result <- runExceptT $ runRoute uri testApi (root :<|> other)
+  let root :: Int -> Maybe String -> IO ()
+      root i s = print (i, s)
+      other :: String -> IO ()
+      other = print
+  for_ testUris $ \uri -> do
+    result <- runRoute uri testApi (root :<|> other)
     print result
