diff --git a/src/Network/Wai/Route.hs b/src/Network/Wai/Route.hs
--- a/src/Network/Wai/Route.hs
+++ b/src/Network/Wai/Route.hs
@@ -17,15 +17,22 @@
 
 import qualified Data.ByteString.Lazy as L
 
-type Handler m = [(ByteString, ByteString)] -- ^ The captured path parameters.
-               -> Request                   -- ^ The matched 'Request'.
-               -> m Response
+-- | A 'Handler' is a generalized 'Application' that receives the captured
+-- path parameters as its first argument.
+type Handler m = [(ByteString, ByteString)]        -- ^ The captured path parameters.
+               -> Request                          -- ^ The matched 'Request'.
+               -> (Response -> m ResponseReceived) -- ^ The continuation.
+               -> m ResponseReceived
 
 -- | Routes requests to 'Handler's according to a routing table.
-route :: Monad m => [(ByteString, Handler m)] -> Request -> m Response
-route rs rq = case lookup (fromList rs) path of
-    Just (f, c) -> f c rq
-    Nothing     -> notFound
+route :: Monad m
+      => [(ByteString, Handler m)]
+      -> Request
+      -> (Response -> m ResponseReceived)
+      -> m ResponseReceived
+route rs rq k = case lookup (fromList rs) path of
+    Just (f, c) -> f c rq k
+    Nothing     -> k notFound
   where
     path     = segments (rawPathInfo rq)
-    notFound = return $ responseLBS status404 [] L.empty
+    notFound = responseLBS status404 [] L.empty
diff --git a/test/Test/Network/Wai/Route.hs b/test/Test/Network/Wai/Route.hs
--- a/test/Test/Network/Wai/Route.hs
+++ b/test/Test/Network/Wai/Route.hs
@@ -15,8 +15,8 @@
 import Data.Monoid ((<>))
 import Network.HTTP.Types
 import Network.Wai
+import Network.Wai.Internal (ResponseReceived (..))
 import Network.Wai.Route
-import Test.QuickCheck (Gen)
 import Test.Tasty
 import Test.Tasty.QuickCheck
 
@@ -32,10 +32,11 @@
     check routes =
         let h1  = route $ map (fmap unHandler) routes
             rsv = routes >>= C.split '/' . fst
+            res = const $ return ResponseReceived
         in conjoin . flip map routes $ \(r, TestHandler h2) ->
             forAll (genReq r rsv) $ \(params2, rq) ->
-                let result1 = h1 rq    -- routed
-                    result2 = h2 [] rq -- direct
+                let result1 = h1 rq res    -- routed
+                    result2 = h2 [] rq res -- direct
                     (hId1, params1) = execState result1 (-1, [])
                     (hId2,       _) = execState result2 (-1, [])
                 in hId1 == hId2 && params1 == params2
@@ -50,9 +51,9 @@
     show _ = "<test-handler>"
 
 handler :: Int -> TestHandler
-handler i = TestHandler $ \p _ -> do
+handler i = TestHandler $ \p _ k -> do
     put (i, p)
-    return $ responseLBS status200 [] L.empty
+    k $ responseLBS status200 [] L.empty
 
 genDir :: Gen ByteString
 genDir = C.pack <$> listOf1 arbitrary `suchThat` f
diff --git a/wai-route.cabal b/wai-route.cabal
--- a/wai-route.cabal
+++ b/wai-route.cabal
@@ -1,5 +1,5 @@
 name:                wai-route
-version:             0.1.2
+version:             0.2
 synopsis:            Minimalistic, efficient routing for WAI
 description:
     .
@@ -32,7 +32,7 @@
 
     build-depends:
         base                 == 4.*
-      , wai                  >= 2.0
+      , wai                  == 3.0.*
       , unordered-containers >= 0.2
       , http-types           >= 0.8
       , bytestring           >= 0.10
@@ -54,12 +54,12 @@
         -threaded
     other-modules: Test.Network.Wai.Route
     build-depends:
-        base             == 4.6.*
-      , bytestring       >= 0.10
-      , http-types       >= 0.8
+        base             == 4.*
+      , bytestring
+      , http-types
       , mtl              >= 2.1
       , QuickCheck       >= 2.5
-      , tasty            >= 0.3
-      , tasty-quickcheck >= 0.2
-      , wai              >= 2.0
+      , tasty            >= 0.8
+      , tasty-quickcheck >= 0.8.1
+      , wai
       , wai-route
