diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,5 @@
+## Changelog
+
+#### 0.1.0.0
+
+* Initial release
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2012, Adam Bergmark, 2014, Luke Randall
+
+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 Adam Bergmark 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/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,60 @@
+snaplet-sass
+===========
+
+[Changelog](CHANGELOG.md)
+
+snaplet-sass integrates [Snap](http://www.snapframework.com) with
+[Sass](http://www.sass-lang.com).
+
+Features
+--------
+
+* Compile and serve sass files on request, no need to restart the
+  snap server.
+* Production mode to pre-compile all sass files.
+* Outputs sourcemaps to make debugging generated CSS easier.
+* Writes CSS to disk to allow reading the generated source.
+
+Example Usage
+-------------
+
+Site.hs:
+```haskell
+import Snap.Snaplet.Sass
+
+routes = [..., ("/sass", with sass sassServe)]
+
+app :: SnapletInit App App
+app = makeSnaplet "app" "A snaplet example application." Nothing $ do
+  s <- nestSnaplet "sass" sass initSass
+  return $ App { _sass = s }
+```
+
+Application.hs:
+```haskell
+import Snap.Snaplet.Sass
+
+data App = App { _sass :: Snaplet Sass }
+
+makeLens ''App
+```
+
+Now run your application and try requesting a Sass file.
+
+A snaplet config file will be generated at snaplets/sass/devel.cfg the
+first time your application initializes the snaplet. The defaults are
+the recommended ones for development.
+
+Place your .sass or .scss files in snaplets/sass/src. Note that a default
+devel.cfg will not be created if you have already created the sass
+directory. If this happens to you, move snaplets/sass, start your
+application, and then move the files back into snaplets/sass.
+
+Any requests to the specified directory (in this case /sass/) will
+compile the appropriate Sass file and serve it.
+
+
+Thanks
+-------
+
+This borrows hugely from [snaplet-fay](https://github.com/faylang/snaplet-fay).
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/resources/devel.cfg b/resources/devel.cfg
new file mode 100644
--- /dev/null
+++ b/resources/devel.cfg
@@ -0,0 +1,15 @@
+# "Development": Compile files on every request.
+#
+# "Production": Compile all files in snaplets/sass/src when the application is started and then serve them statically.
+#
+# Both methods will write files to disk for debugging purposes.
+# Default is "Development".
+compileMode = "Development"
+# Output style. Can be nested (the Sass default), compact, compressed or expanded.
+style = "nested"
+# Output sourcemap (not supported by older versions of Sass).
+sourcemap = on
+# Print more or less information about what the snaplet is doing.
+# Default is on.
+verbose = on
+
diff --git a/snaplet-sass.cabal b/snaplet-sass.cabal
new file mode 100644
--- /dev/null
+++ b/snaplet-sass.cabal
@@ -0,0 +1,76 @@
+name:                snaplet-sass
+version:             0.1.0.0
+synopsis:            Sass integration for Snap with request- and pre-compilation.
+description:         
+    Sass integration for Snap with request based compilation during development and precompilation in production.
+    .
+    Get started by reading through the <https://github.com/lukerandall/snaplet-sass README>.
+    .
+    = Brief overview
+    .
+    Add the snaplet to your App in Application.hs
+    .
+    > import Snap.Snaplet.Sass
+    >
+    > data App = App [
+    >     _sass :: Snaplet Sass
+    >     ] -- these should be curly braces but haddock doesn't allow it
+    .
+    In Site.hs, add a route for sass to serve from and initialize the snaplet
+    .
+    > routes = [..., ("/sass", with sass sassServe)]
+    >
+    > app :: SnapletInit App App
+    > app = makeSnaplet "app" "A snaplet example application." Nothing $ do
+    >   s <- nestSnaplet "sass" sass initSass
+    > return $ App s
+    .
+    Now add your Sass files to snaplets\/sass\/src and they'll be served
+    at \/sass\//FILE/.css. Take note that the .sass or .scss extension will
+    be replaced with .css.
+    .
+
+license:             BSD3
+license-file:        LICENSE
+author:              Luke Randall
+maintainer:          luke.randall@gmail.com
+homepage:            https://github.com/lukerandall/snaplet-sass
+bug-reports:         https://github.com/lukerandall/snaplet-sass/issues
+category:            Web, Snap
+build-type:          Simple
+cabal-version:       >=1.8
+
+extra-source-files:
+  LICENSE
+  README.md
+  CHANGELOG.md
+
+data-files:
+  resources/devel.cfg
+
+source-repository head
+  type: git
+  location: https://github.com/lukerandall/snaplet-sass.git
+
+library
+  ghc-options: -Wall
+  hs-source-dirs: src
+
+  exposed-modules:
+    Snap.Snaplet.Sass
+    Snap.Snaplet.Sass.Internal
+
+  other-modules:
+    Paths_snaplet_sass
+
+  build-depends:
+      base         >= 4       && < 5
+    , bytestring   >= 0.9     && < 0.11
+    , configurator == 0.2.*
+    , directory    >= 1.1     && < 1.3
+    , filepath     == 1.3.*
+    , mtl          >= 2.1     && < 2.3
+    , process      >= 1.1     && <= 1.3
+    , snap         >= 0.11.1  && < 0.14
+    , snap-core    >= 0.9.3.1 && < 0.10
+    , transformers >= 0.3     && < 0.4 || > 0.4.1 && < 0.5
diff --git a/src/Snap/Snaplet/Sass.hs b/src/Snap/Snaplet/Sass.hs
new file mode 100644
--- /dev/null
+++ b/src/Snap/Snaplet/Sass.hs
@@ -0,0 +1,100 @@
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+module Snap.Snaplet.Sass (
+         Sass
+       , initSass
+       , sassServe
+       ) where
+
+------------------------------------------------------------------------------
+import           Control.Monad
+import           Control.Monad.Reader
+import           Control.Monad.State.Class
+import           Control.Monad.Trans.Writer
+import           Data.Char (toLower)
+import qualified Data.Configurator          as C
+import           Data.List (intercalate)
+import           Data.Maybe (isNothing)
+import           Snap.Core (modifyResponse, setContentType)
+import           Snap.Snaplet
+import           Snap.Util.FileServe
+import           System.Process (rawSystem)
+
+import           Paths_snaplet_sass
+import           Snap.Snaplet.Sass.Internal
+
+-- | Snaplet initialization
+initSass :: SnapletInit b Sass
+initSass = makeSnaplet "sass" description datadir $ do
+  config <- getSnapletUserConfig
+  fp <- getSnapletFilePath
+
+  (opts, errs) <- runWriterT $ do
+    cmStr <- logErr "Must specify compileMode" $ C.lookup config "compileMode"
+    cm    <- case cmStr of
+                  Just x -> logErr "Invalid compileMode" . return $ compileModeFromString x
+                  Nothing -> return Nothing
+    stStr <- logErr "Must specify style" $ C.lookup config "style"
+    st    <- case stStr of
+                  Just x  -> logErr "Invalid style" . return $ styleFromString x
+                  Nothing -> return Nothing
+    sm    <- logErr "Must specify sourcemap" $ C.lookup config "sourcemap"
+    v     <- logErr "Must specify verbose" $ C.lookup config "verbose"
+    return (cm, st, sm, v)
+
+  let sass = case opts of
+              (Just cm, Just st, Just sm, Just v) ->
+                Sass
+                  { snapletFilePath = fp
+                  , compileMode     = cm
+                  , style           = st
+                  , sourcemap       = sm
+                  , verbose         = v
+                  }
+              _ -> error $ intercalate "\n" errs
+
+  -- Make sure snaplet/sass, snaplet/sass/src, snaplet/sass/css are present.
+  liftIO $ mapM_ createDirUnlessExists [fp, srcDir sass, destDir sass]
+
+  when (Production == compileMode sass) (liftIO $ compileAll sass)
+
+  return sass
+
+  where
+    datadir = Just $ liftM (++ "/resources") getDataDir
+
+    description = "Automatic (re)compilation and serving of Sass files"
+
+    logErr :: MonadIO m => t -> IO (Maybe a) -> WriterT [t] m (Maybe a)
+    logErr err m = do
+        res <- liftIO m
+        when (isNothing res) (tell [err])
+        return res
+
+
+-- | Serves the compiled Fay scripts using the chosen compile mode.
+sassServe :: Handler b Sass ()
+sassServe = do
+  modifyResponse . setContentType $ "text/css;charset=utf-8"
+  get >>= compileWithMode . compileMode
+
+
+-- | Compiles according to the specified mode.
+compileWithMode :: CompileMode -> Handler b Sass ()
+compileWithMode Development = do
+    config <- get
+    compileAll config
+    compileWithMode Production
+-- Production compilation has already been done.
+compileWithMode Production = get >>= serveDirectory . destDir
+
+compileAll :: MonadIO m => Sass -> m ()
+compileAll cfg = liftIO $ compile >> return ()
+  where
+    compile = verboseLog >> rawSystem "sass" args
+    verboseLog = verbosePut cfg $ "compiling " ++ srcDir cfg
+    args = ["--update", ioDirs, "--style", st] ++ sm
+    ioDirs = srcDir cfg ++ ":" ++ destDir cfg
+    sm = if sourcemap cfg then ["--sourcemap"] else []
+    st = map toLower . show $ style cfg
diff --git a/src/Snap/Snaplet/Sass/Internal.hs b/src/Snap/Snaplet/Sass/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Snap/Snaplet/Sass/Internal.hs
@@ -0,0 +1,82 @@
+module Snap.Snaplet.Sass.Internal
+    (
+    -- * Sass types
+      Sass (..)
+    , CompileMode (..)
+    , Style (..)
+    -- * helper functions
+    , srcDir
+    , destDir
+    , createDirUnlessExists
+    , compileModeFromString
+    , styleFromString
+    , verbosePut
+    ) where
+
+import Control.Monad
+import System.Directory
+import System.FilePath ((</>))
+
+
+-- | Configuration
+data Sass = Sass {
+    snapletFilePath :: FilePath
+  , compileMode     :: CompileMode
+  , style           :: Style
+  , sourcemap       :: Bool
+  , verbose         :: Bool
+  } deriving (Show)
+
+
+-- | Compile on every request or when Snap starts.
+data CompileMode
+     = Development
+     | Production
+       deriving (Eq, Show)
+
+
+-- | Style of generated CSS
+data Style
+     = Nested
+     | Compact
+     | Compressed
+     | Expanded
+       deriving (Eq, Show)
+
+
+-- | Location of Sass files
+srcDir :: Sass -> FilePath
+srcDir = (</> "src") . snapletFilePath
+
+
+-- | Location of CSS files
+destDir :: Sass -> FilePath
+destDir = (</> "css") . snapletFilePath
+
+
+-- | Create given directory unless it exists
+createDirUnlessExists :: FilePath -> IO ()
+createDirUnlessExists fp = do
+    dirExists <- doesDirectoryExist fp
+    unless dirExists $ createDirectory fp
+
+
+-- | Lookup CompileMode for string
+compileModeFromString :: String -> Maybe CompileMode
+compileModeFromString "Development" = Just Development
+compileModeFromString "Production" = Just Production
+compileModeFromString _ = Nothing
+
+
+-- | Lookup Style for string
+styleFromString :: String -> Maybe Style
+styleFromString "nested" = Just Nested
+styleFromString "compact" = Just Compact
+styleFromString "compressed" = Just Compressed
+styleFromString "expanded" = Just Expanded
+styleFromString _ = Nothing
+
+
+-- | Print log messages when the verbose flag is set
+verbosePut :: Sass -> String -> IO ()
+verbosePut config = when (verbose config) . putStrLn . ("snaplet-sass: " ++ )
