diff --git a/Main.hs b/Main.hs
--- a/Main.hs
+++ b/Main.hs
@@ -7,6 +7,8 @@
 import System.Console.GetOpt
 import Control.Monad (join)
 import Control.Applicative ((<$>))
+import Control.Monad.Reader
+import Paths_rezoom (getDataFileName)
 import qualified Data.Map as M
 
 version = "0.0.1"
@@ -65,8 +67,14 @@
         (flags, username:_, []) -> do
             let sane = M.fromList $ saneOpts $ (Username username):flags;
                 filename = M.findWithDefault "resume.html" "output" sane
-            html <- (build sane) <$> parse <$> getAPI username
-            putStrLn "Built resume..."
-            html >>= (\e -> writeFile filename e)
-            putStrLn "All done."
+            cssfile <- getDataFileName "Rezoom/rezoom.css"
+            css <- readFile cssfile
+            json <- parse <$> getAPI username
+            case json of
+                Left err -> do error "Unable to parse API response, sorry."
+                Right res -> do
+                    putStrLn "Building resume..."
+                    let html = runReader build $ Resume sane res css
+                    writeFile filename html
+                    putStrLn "All done."
         (_, _, msgs) -> error $ concat msgs ++ usageInfo header options
diff --git a/Rezoom/Builder.hs b/Rezoom/Builder.hs
--- a/Rezoom/Builder.hs
+++ b/Rezoom/Builder.hs
@@ -1,5 +1,6 @@
 module Rezoom.Builder (
-    build
+    build,
+    Resume(..)
     ) where
     import Text.XHtml.Strict
     import Text.JSON
@@ -12,36 +13,36 @@
     import Data.Ord (comparing)
     import Data.List
     import Data.DateTime
-    import Paths_rezoom
     import System.IO
+    import Control.Monad.Reader
 
     eStr = extractString
     
     type Opts = M.Map String String
+
+    data Resume = Resume { opts :: Opts, source :: JSValue, css :: String }
     
     instance Eq Html where
         x == y = showHtml x == showHtml y
     
-    build :: Opts -> Either String JSValue -> IO String
-    build opts val = fmap (renderHtml) $ build_ opts val
-    
-    build_ :: Opts -> Either String JSValue -> IO Html
-    build_ _ (Left err) = buildErr err
-    build_ opts (Right v) = case v $$ "repositories" of 
-        Nothing -> error "Unknown username."
-        Just repos -> do
-            filename <- getDataFileName "Rezoom/rezoom.css"
-            fileContents <- readFile filename
-            return $ buildHeader fileContents +++ body <<
-                        thediv ! [identifier "container"] <<
-                            thediv ! [identifier "container-inner"] <<
-                                (header_ opts +++
-                                 (subsection "Skills" ["langs"] $ skillList knownRepos) +++
-                                 sectionize knownRepos)
-            where
-                knownRepos = sortBy (comparing ($$! "language")) $ 
-                                filter (hasKey "language") $
-                                    extractList repos
+    build :: Reader Resume String
+    build = do
+        v <- asks source
+        case v $$ "repositories" of 
+            Nothing -> error "Unknown username."
+            Just repos -> do
+                fileContents <- asks css
+                options <- asks opts
+                return $ renderHtml $ buildHeader fileContents +++ body <<
+                            thediv ! [identifier "container"] <<
+                                thediv ! [identifier "container-inner"] <<
+                                    (header_ options +++
+                                     (subsection "Skills" ["langs"] $ skillList knownRepos) +++
+                                     sectionize knownRepos)
+                where
+                    knownRepos = sortBy (comparing ($$! "language")) $ 
+                                    filter (hasKey "language") $
+                                        extractList repos
             
     sectionize :: [JSValue] -> [Html]
     sectionize = map (\e -> (<<) (thediv ! (secAttrs $ langname e))
diff --git a/Rezoom/JSON.hs b/Rezoom/JSON.hs
--- a/Rezoom/JSON.hs
+++ b/Rezoom/JSON.hs
@@ -30,7 +30,7 @@
     
     -- Version of $$ that allows you to provide an alternative value
     getOr :: String -> String -> JSValue -> String
-    getOr alt index tree = maybe alt id $ extractString <$> tree $$ index
+    getOr alt index tree = fromMaybe alt $ extractString <$> tree $$ index
     
     -- map applied to a JSON list
     mapJ :: (JSValue -> a) -> JSValue -> [a]
diff --git a/rezoom.cabal b/rezoom.cabal
--- a/rezoom.cabal
+++ b/rezoom.cabal
@@ -1,13 +1,13 @@
 Cabal-Version:	>= 1.6
 Name:			rezoom
-Version:		0.0.2
+Version:		0.0.3
 Synopsis:		Github resume generator
 Description:	Generates a resume from your github page.
 License:		GPL
 License-File:	LICENSE
 Author:			Joel Taylor
 Maintainer:		Joel Taylor <barebonesgraphics@gmail.com>
-Build-Type: Simple
+Build-Type:     Simple
 Data-Files:		Rezoom/rezoom.css
 Extra-Source-Files:	README
 Category:		Utils
@@ -18,5 +18,5 @@
 
 Executable rezoom
     Main-is: Main.hs
-    Build-Depends: base == 4.*, json == 0.5.*, xhtml == 3000.*, HTTP == 4000.*, nano-md5 == 0.1.*, bytestring == 0.9.*, datetime == 0.2.*, containers == 0.4.*
+    Build-Depends: base == 4.*, json == 0.5.*, xhtml == 3000.*, HTTP == 4000.*, nano-md5 == 0.1.*, bytestring == 0.9.*, datetime == 0.2.*, containers == 0.4.*, mtl == 2.0.*
     Other-Modules: Rezoom.Builder, Rezoom.JSON
