diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c)2011, Michael Snoyman
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Michael Snoyman nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,7 @@
+#!/usr/bin/env runhaskell
+
+> module Main where
+> import Distribution.Simple
+
+> main :: IO ()
+> main = defaultMain
diff --git a/servius.cabal b/servius.cabal
new file mode 100644
--- /dev/null
+++ b/servius.cabal
@@ -0,0 +1,32 @@
+Name:                servius
+Version:             0.0.0
+Synopsis:            Serve Shakespearean templates via Warp
+Homepage:            http://github.com/yesodweb/hamlet
+License:             BSD3
+License-file:        LICENSE
+Author:              Michael Snoyman
+Maintainer:          michael@snoyman.com
+Category:            Web
+Build-type:          Simple
+Cabal-version:       >=1.2
+Description:         Does not support any variable interpolation. Supports Hamlet and Lucius files (must have .hamlet and .lucius file extensions, respectively).
+
+
+Executable servius
+  Main-is:       servius.hs
+  Build-depends: base            >= 4                  && < 5
+               , warp            >= 0.4                && < 0.5
+               , wai-app-static  >= 0.3                && < 0.4
+               , wai-extra       >= 0.4                && < 0.5
+               , cmdargs         >= 0.6.7
+               , directory       >= 1.0
+               , containers      >= 0.2                && < 0.5
+               , bytestring      >= 0.9.1.4
+               , text            >= 0.7
+               , blaze-builder
+               , blaze-html
+               , http-types
+               , hamlet
+               , shakespeare-css
+               , transformers
+               , wai
diff --git a/servius.hs b/servius.hs
new file mode 100644
--- /dev/null
+++ b/servius.hs
@@ -0,0 +1,102 @@
+{-# LANGUAGE DeriveDataTypeable, RecordWildCards #-}
+{-# LANGUAGE OverloadedStrings #-}
+import Network.Wai.Application.Static
+    ( StaticSettings (..), staticApp, defaultMimeType, defaultListing
+    , defaultMimeTypes, mimeTypeByExt
+    , defaultFileServerSettings, fileSystemLookup
+    , fileName, toFilePath
+    )
+import Network.Wai.Handler.Warp (run)
+import System.Console.CmdArgs
+import Text.Printf (printf)
+import System.Directory (canonicalizePath)
+import Control.Monad (unless)
+import Network.Wai.Middleware.Autohead
+import Network.Wai.Middleware.Debug
+import Network.Wai.Middleware.Gzip
+import qualified Data.Map as Map
+import qualified Data.ByteString.Char8 as S8
+import Control.Arrow ((***))
+import Data.Text (Text, pack)
+import qualified Data.Text as T
+import Network.Wai
+import Data.ByteString (ByteString)
+import Control.Monad.IO.Class (liftIO)
+import Data.Text.Encoding (decodeUtf8With)
+import Data.Text.Encoding.Error (lenientDecode)
+import Text.Lucius (luciusRT)
+import Text.Hamlet (defaultHamletSettings)
+import Text.Hamlet.RT (parseHamletRT, renderHamletRT)
+import Network.HTTP.Types (status200)
+import Text.Blaze.Renderer.Utf8 (renderHtmlBuilder)
+import qualified Data.Text.Lazy as TL
+import Blaze.ByteString.Builder.Char.Utf8 (fromLazyText)
+
+data Args = Args
+    { docroot :: FilePath
+    , index :: [FilePath]
+    , port :: Int
+    , noindex :: Bool
+    , quiet :: Bool
+    , verbose :: Bool
+    , mime :: [(String, String)]
+    }
+    deriving (Show, Data, Typeable)
+
+defaultArgs :: Args
+defaultArgs = Args "." ["index.html", "index.htm"] 3000 False False False []
+
+main :: IO ()
+main = do
+    Args {..} <- cmdArgs defaultArgs
+    let mime' = map (toFilePath *** S8.pack) mime
+    let mimeMap = Map.fromList mime' `Map.union` defaultMimeTypes
+    docroot' <- canonicalizePath docroot
+    unless quiet $ printf "Serving directory %s on port %d with %s index files.\n" docroot' port (if noindex then "no" else show index)
+    let middle = gzip False
+               . (if verbose then debug else id)
+               . autohead
+               . shake docroot
+    run port $ middle $ staticApp defaultFileServerSettings
+        { ssFolder = fileSystemLookup $ toFilePath docroot
+        , ssIndices = if noindex then [] else map pack index
+        , ssListing = Just defaultListing
+        , ssGetMimeType = return . mimeTypeByExt mimeMap defaultMimeType . fileName
+        }
+
+shake :: FilePath -> Middleware
+shake docroot app req
+    | any unsafe p = app req
+    | null p = app req
+    | ".hamlet" `T.isSuffixOf` l = liftIO $ hamlet pr
+    | ".lucius" `T.isSuffixOf` l = liftIO $ lucius pr
+    | otherwise = app req
+  where
+    p = pathInfo req
+    pr = T.intercalate "/" $ T.pack docroot : p
+    l = last p
+
+unsafe :: Text -> Bool
+unsafe s
+    | T.null s = False
+    | T.head s == '.' = True
+    | otherwise = T.any (== '/') s
+
+readFileUtf8 :: Text -> IO String
+readFileUtf8 fp = do
+    bs <- S8.readFile $ T.unpack fp
+    let t = decodeUtf8With lenientDecode bs
+    return $ T.unpack t
+
+hamlet :: Text -> IO Response
+hamlet fp = do
+    str <- readFileUtf8 fp
+    hrt <- parseHamletRT defaultHamletSettings str
+    html <- renderHamletRT hrt [] (error "No URLs allowed")
+    return $ ResponseBuilder status200 [("Content-Type", "text/html; charset=utf-8")] $ renderHtmlBuilder html
+
+lucius :: Text -> IO Response
+lucius fp = do
+    str <- readFileUtf8 fp
+    let text = either error id $ luciusRT (TL.pack str) []
+    return $ ResponseBuilder status200 [("Content-Type", "text/css; charset=utf-8")] $ fromLazyText text
