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/hpaste.cabal b/hpaste.cabal
new file mode 100644
--- /dev/null
+++ b/hpaste.cabal
@@ -0,0 +1,56 @@
+Name:                hpaste
+Version:             0.0.0
+stability:           Stable
+Synopsis:            Haskell paste web site.
+Description:         Haskell paste web site.
+Homepage:            http://hpaste.org/
+License:             GPL
+Author:              Chris Done <chrisdone@gmail.com>
+Maintainer:          Chris Done <chrisdone@gmail.com>
+Copyright:           2010-2013 by Chris Done
+Category:            Web
+Build-type:          Simple
+Cabal-version:       >=1.2
+
+Executable hpaste
+  Main-is:           Main.hs
+  Ghc-options:       -threaded -Wall -O2 -fno-warn-name-shadowing
+  Hs-source-dirs:    src
+  Build-depends:
+    -- Hard versions
+    Diff                      == 0.1.3
+   ,blaze-html                == 0.4.3.4
+   -- Soft versions
+   ,base                      >= 4     && < 5
+   ,css                       >= 0.1
+   ,named-formlet             >= 0.2
+   ,snap-app                  >= 0.3.2
+   -- Free versions
+   ,ConfigFile
+   ,HJScript
+   ,MissingH
+   ,MonadCatchIO-transformers
+   ,blaze-builder
+   ,bytestring
+   ,containers
+   ,directory
+   ,download-curl
+   ,feed
+   ,filepath
+   ,haskell-src-exts
+   ,hlint
+   ,hscolour
+   ,mtl
+   ,network
+   ,old-locale
+   ,safe
+   ,snap-core
+   ,snap-server
+   ,text
+   ,time
+   ,transformers
+   ,utf8-string
+   ,mime-mail
+   ,cgi
+   ,process
+   ,postgresql-simple
diff --git a/src/Main.hs b/src/Main.hs
new file mode 100644
--- /dev/null
+++ b/src/Main.hs
@@ -0,0 +1,67 @@
+{-# OPTIONS -Wall #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+-- | Main entry point.
+
+module Main (main) where
+
+import Hpaste.Config
+import Hpaste.Controller.Activity as Activity
+import Hpaste.Controller.Browse   as Browse
+import Hpaste.Controller.Diff     as Diff
+import Hpaste.Controller.Home     as Home
+import Hpaste.Controller.New      as New
+import Hpaste.Controller.Paste    as Paste
+import Hpaste.Controller.Raw      as Raw
+import Hpaste.Controller.Report   as Report
+import Hpaste.Controller.Reported as Reported
+import Hpaste.Controller.Style    as Style
+import Hpaste.Controller.Script   as Script
+import Hpaste.Model.Announcer     (newAnnouncer)
+import Hpaste.Types
+import Hpaste.Types.Announcer
+
+import Control.Concurrent.Chan    (Chan)
+import Data.Text.Lazy             (Text)
+import System.Environment
+import Snap.App
+import Snap.Http.Server           hiding (Config)
+import Snap.Util.FileServe
+
+
+-- | Main entry point.
+main :: IO ()
+main = do
+  cpath:_ <- getArgs
+  config <- getConfig cpath
+  announces <- newAnnouncer (configAnnounce config)
+  pool <- newPool (configPostgres config)
+  setUnicodeLocale "en_US"
+  httpServe server (serve config pool announces)
+ where server = setPort 10000 defaultConfig
+
+-- | Serve the controllers.
+serve :: Config -> Pool -> Announcer -> Snap ()
+serve config pool ans = route routes where
+  routes = [("/css/amelie.css", run Style.handle)
+           ,("/css/",serveDirectory "static/css")
+           ,("/js/amelie.js",run Script.handle)
+           ,("/js/",serveDirectory "static/js")
+           ,("/hs/",serveDirectory "static/hs")
+           ,("",run (Home.handle False))
+	   ,("/spam",run (Home.handle True))
+           ,("/:id",run (Paste.handle False))
+           ,("/raw/:id",run Raw.handle)
+           ,("/revision/:id",run (Paste.handle True))
+           ,("/report/:id",run Report.handle)
+           ,("/reported",run Reported.handle)
+           ,("/new",run (New.handle New.NewPaste))
+           ,("/annotate/:id",run (New.handle New.AnnotatePaste))
+           ,("/edit/:id",run (New.handle New.EditPaste))
+           ,("/new/:channel",run (New.handle New.NewPaste))
+           ,("/browse",run Browse.handle)
+           ,("/activity",run Activity.handle)
+           ,("/diff/:this/:that",run Diff.handle)
+	   ,("/delete",run Report.handleDelete)
+           ]
+  run = runHandler ans config pool
