diff --git a/README b/README
--- a/README
+++ b/README
@@ -20,7 +20,7 @@
   * Conforms to WAI Application interface.
   * Uses very fast Warp webserver by default.
 
-See examples/basic.hs to see Scotty in action.
+See examples/basic.hs to see Scotty in action. (basic.hs needs the wai-extra package)
 
     > runghc examples/basic.hs
     Setting phasers to stun... (ctrl-c to quit)
diff --git a/Web/Scotty.hs b/Web/Scotty.hs
--- a/Web/Scotty.hs
+++ b/Web/Scotty.hs
@@ -3,7 +3,7 @@
 -- OverloadedStrings language pragma.
 module Web.Scotty
     ( -- * scotty-to-WAI
-      scotty, scottyApp
+      scotty, scottyApp, scottyOpts, Options(..)
       -- * Defining Middleware and Routes
       --
       -- | 'Middleware' and routes are run in the order in which they
@@ -22,7 +22,7 @@
       --
       -- | Note: only one of these should be present in any given route
       -- definition, as they completely replace the current 'Response' body.
-    , text, html, file, json
+    , text, html, file, json, source
       -- ** Exceptions
     , raise, rescue, next
       -- * Types
@@ -31,13 +31,14 @@
 
 import Blaze.ByteString.Builder (fromByteString)
 
+import Control.Monad (when)
 import Control.Monad.State (execStateT, modify)
 
 import Data.Default (def)
 
 import Network.HTTP.Types (status404)
 import Network.Wai
-import Network.Wai.Handler.Warp (Port, run)
+import Network.Wai.Handler.Warp (Port, runSettings, settingsPort)
 
 import Web.Scotty.Action
 import Web.Scotty.Route
@@ -45,9 +46,14 @@
 
 -- | Run a scotty application using the warp server.
 scotty :: Port -> ScottyM () -> IO ()
-scotty p s = do
-    putStrLn $ "Setting phasers to stun... (ctrl-c to quit) (port " ++ show p ++ ")"
-    run p =<< scottyApp s
+scotty p = scottyOpts $ def { settings = (settings def) { settingsPort = p } }
+
+-- | Run a scotty application using the warp server, passing extra options.
+scottyOpts :: Options -> ScottyM() -> IO ()
+scottyOpts opts s = do
+    when (verbose opts > 0) $
+        putStrLn $ "Setting phasers to stun... (port " ++ show (settingsPort (settings opts)) ++ ") (ctrl-c to quit)"
+    runSettings (settings opts) =<< scottyApp s
 
 -- | Turn a scotty application into a WAI 'Application', which can be
 -- run with any WAI handler.
diff --git a/Web/Scotty/Action.hs b/Web/Scotty/Action.hs
--- a/Web/Scotty/Action.hs
+++ b/Web/Scotty/Action.hs
@@ -2,12 +2,12 @@
 module Web.Scotty.Action
     ( request, body, param, jsonData
     , status, header, redirect
-    , text, html, file, json
+    , text, html, file, json, source
     , raise, rescue, next
     , ActionM, Parsable, Param, runAction
     ) where
 
-import Blaze.ByteString.Builder (fromLazyByteString)
+import Blaze.ByteString.Builder (Builder, fromLazyByteString)
 
 import Control.Applicative
 import Control.Monad.Error
@@ -18,6 +18,7 @@
 import qualified Data.ByteString.Char8 as B
 import qualified Data.ByteString.Lazy.Char8 as BL
 import qualified Data.CaseInsensitive as CI
+import Data.Conduit (Flush, ResourceT, Source)
 import Data.Default (Default, def)
 import Data.Monoid (mconcat)
 import qualified Data.Text.Lazy as T
@@ -164,23 +165,29 @@
 text :: T.Text -> ActionM ()
 text t = do
     header "Content-Type" "text/plain"
-    MS.modify $ setContent $ Left $ fromLazyByteString $ encodeUtf8 t
+    MS.modify $ setContent $ ContentBuilder $ fromLazyByteString $ encodeUtf8 t
 
 -- | Set the body of the response to the given 'T.Text' value. Also sets \"Content-Type\"
 -- header to \"text/html\".
 html :: T.Text -> ActionM ()
 html t = do
     header "Content-Type" "text/html"
-    MS.modify $ setContent $ Left $ fromLazyByteString $ encodeUtf8 t
+    MS.modify $ setContent $ ContentBuilder $ fromLazyByteString $ encodeUtf8 t
 
 -- | Send a file as the response. Doesn't set the \"Content-Type\" header, so you probably
 -- want to do that on your own with 'header'.
 file :: FilePath -> ActionM ()
-file = MS.modify . setContent . Right
+file = MS.modify . setContent . ContentFile
 
 -- | Set the body of the response to the JSON encoding of the given value. Also sets \"Content-Type\"
 -- header to \"application/json\".
 json :: (A.ToJSON a) => a -> ActionM ()
 json v = do
     header "Content-Type" "application/json"
-    MS.modify $ setContent $ Left $ fromLazyByteString $ A.encode v
+    MS.modify $ setContent $ ContentBuilder $ fromLazyByteString $ A.encode v
+
+-- | Set the body of the response to a Source. Doesn't set the
+-- \"Content-Type\" header, so you probably want to do that on your
+-- own with 'header'.
+source :: Source (ResourceT IO) (Flush Builder) -> ActionM ()
+source = MS.modify . setContent . ContentSource
diff --git a/Web/Scotty/Types.hs b/Web/Scotty/Types.hs
--- a/Web/Scotty/Types.hs
+++ b/Web/Scotty/Types.hs
@@ -11,16 +11,24 @@
 import Data.Text.Lazy (Text, pack)
 
 import Network.Wai
+import Network.Wai.Handler.Warp (Settings, defaultSettings)
 
+data Options = Options { verbose :: Int -- ^ 0 = silent, 1(def) = startup banner
+                       , settings :: Settings -- ^ Warp 'Settings'
+                       }
+
+instance Default Options where
+    def = Options 1 defaultSettings
+
 data ScottyState = ScottyState { middlewares :: [Middleware]
                                , routes :: [Middleware]
                                }
 
 addMiddleware :: Middleware -> ScottyState -> ScottyState
-addMiddleware m (ScottyState ms rs) = ScottyState (m:ms) rs
+addMiddleware m s@(ScottyState {middlewares = ms}) = s { middlewares = m:ms }
 
 addRoute :: Middleware -> ScottyState -> ScottyState
-addRoute r (ScottyState ms rs) = ScottyState ms (r:rs)
+addRoute r s@(ScottyState {routes = rs}) = s { routes = r:rs }
 
 instance Default ScottyState where
     def = ScottyState [] []
diff --git a/Web/Scotty/Util.hs b/Web/Scotty/Util.hs
--- a/Web/Scotty/Util.hs
+++ b/Web/Scotty/Util.hs
@@ -2,6 +2,7 @@
     ( lazyTextToStrictByteString
     , strictByteStringToLazyText
     , setContent, setHeader, setStatus
+    , Content(..)
     ) where
 
 import Network.Wai
@@ -10,6 +11,7 @@
 
 import Blaze.ByteString.Builder (Builder)
 import Data.CaseInsensitive (CI)
+import Data.Conduit (Flush, Source, ResourceT)
 import Data.Default
 import Data.Monoid
 
@@ -26,13 +28,20 @@
 strictByteStringToLazyText :: B.ByteString -> T.Text
 strictByteStringToLazyText = T.fromStrict . ES.decodeUtf8
 
-setContent :: Either Builder FilePath -> Response -> Response
-setContent (Left b) (ResponseBuilder s h _)  = ResponseBuilder s h b
-setContent (Left b) (ResponseFile s h _ _)   = ResponseBuilder s h b
-setContent (Left b) (ResponseSource s h _)   = ResponseBuilder s h b
-setContent (Right f) (ResponseBuilder s h _) = ResponseFile s h f Nothing
-setContent (Right f) (ResponseFile s h _ _)  = ResponseFile s h f Nothing
-setContent (Right f) (ResponseSource s h _)  = ResponseFile s h f Nothing
+data Content = ContentBuilder Builder
+             | ContentFile FilePath
+             | ContentSource (Source (ResourceT IO) (Flush Builder))
+
+setContent :: Content -> Response -> Response
+setContent (ContentBuilder b) (ResponseBuilder s h _)  = ResponseBuilder s h b
+setContent (ContentBuilder b) (ResponseFile s h _ _)   = ResponseBuilder s h b
+setContent (ContentBuilder b) (ResponseSource s h _)   = ResponseBuilder s h b
+setContent (ContentFile f) (ResponseBuilder s h _) = ResponseFile s h f Nothing
+setContent (ContentFile f) (ResponseFile s h _ _)  = ResponseFile s h f Nothing
+setContent (ContentFile f) (ResponseSource s h _)  = ResponseFile s h f Nothing
+setContent (ContentSource src) (ResponseBuilder s h _) = ResponseSource s h src
+setContent (ContentSource src) (ResponseFile s h _ _)  = ResponseSource s h src
+setContent (ContentSource src) (ResponseSource s h _)  = ResponseSource s h src
 
 setHeader :: (CI Ascii, Ascii) -> Response -> Response
 setHeader (k,v) (ResponseBuilder s h b) = ResponseBuilder s (update h k v) b
diff --git a/examples/basic.hs b/examples/basic.hs
--- a/examples/basic.hs
+++ b/examples/basic.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE OverloadedStrings #-}
 import Web.Scotty
 
-import Network.Wai.Middleware.RequestLogger
+import Network.Wai.Middleware.RequestLogger -- install wai-extra if you don't have this
 
 import Control.Monad.Trans
 import Data.Monoid
@@ -85,7 +85,7 @@
         b <- body
         text $ decodeUtf8 b
 
-    get "/lambda/:foo/:bar" $ \ foo bar baz -> do
+    get "/lambda/:foo/:bar/:baz" $ \ foo bar baz -> do
         text $ mconcat [foo, bar, baz]
 
 {- If you don't want to use Warp as your webserver,
diff --git a/examples/options.hs b/examples/options.hs
new file mode 100644
--- /dev/null
+++ b/examples/options.hs
@@ -0,0 +1,20 @@
+{-# LANGUAGE OverloadedStrings #-}
+import Web.Scotty
+
+import Network.Wai.Middleware.RequestLogger -- install wai-extra if you don't have this
+
+import Data.Default (def)
+import Network.Wai.Handler.Warp (settingsPort)
+
+-- Set some Scotty settings
+opts :: Options
+opts = def { verbose = 0
+           , settings = (settings def) { settingsPort = 4000 }
+           }
+
+-- This won't display anything at startup, and will listen on localhost:4000
+main :: IO ()
+main = scottyOpts opts $ do
+    middleware logStdoutDev
+
+    get "/" $ text "hello world"
diff --git a/scotty.cabal b/scotty.cabal
--- a/scotty.cabal
+++ b/scotty.cabal
@@ -1,5 +1,5 @@
 Name:                scotty
-Version:             0.4.2
+Version:             0.4.3
 Synopsis:            Haskell web framework inspired by Ruby's Sinatra, using WAI and Warp
 Homepage:            https://github.com/xich/scotty
 Bug-reports:         https://github.com/xich/scotty/issues
@@ -55,8 +55,9 @@
 Extra-source-files:
     README
     examples/basic.hs
-    examples/urlshortener.hs
     examples/json.hs
+    examples/options.hs
+    examples/urlshortener.hs
     examples/static/jquery.js
     examples/static/jquery-json.js
     examples/static/json.js
