diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
 # Changelog
 
+## 0.1.3.0 - 2016-02-29
+
+ * Improved performance in stack projects: The stack configuration is
+   updated only when the passed path implies a different `stack.yaml`.
+   Performance improved substantially from roughly ~1s to ~0.3s.
+
 ## 0.1.2.2 - 2016-01-11
 
  * Added type checking support for tests and benchmarks in stack projects.
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (C) 2015 The hdevtools Authors (see AUTHORS file)
+Copyright (C) 2016 The hdevtools Authors (see AUTHORS file)
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,230 @@
+hdevtools
+=========
+
+Persistent GHC powered background server for FAST Haskell development tools
+
+
+About
+-----
+
+`hdevtools` is a backend for text editor plugins, to allow for things such as
+syntax and type checking of Haskell code, and retrieving type information, all
+directly from within your text editor.
+
+The advantage that `hdevtools` has over competitors, is that it runs silently
+in a persistent background process, and therefore is able to keeps all of your
+Haskell modules and dependent libraries loaded in memory. This way, when you
+change only a single source file, only it needs to be reloaded and rechecked,
+instead of having to reload everything.
+
+This makes `hdevtools` very fast for checking syntax and type errors (runs just
+as fast as the `:reload` command in GHCi).
+
+In fact, syntax and type checking is so fast, that you can safely enable auto
+checking on every save. Even for huge projects, checking is nearly instant.
+
+Once you start using `hdevtools` and you get used to having your errors shown
+to you instantly (without having to switch back and forth between GHCi and your
+editor), and shown directly on your code, in your editor (without having to
+wait forever for GHC to run) you will wonder how you ever lived without it.
+
+In addition to checking Haskell source code for errors, `hdevtools` has tools
+for getting info about identifiers, and getting type information for snippets
+of code.
+
+Text Editor Integration
+-----------------------
+
+`hdevtools` is designed to be integrated into text editors. The list of current
+editor plugins that supply this integration is below.
+
+But before you do anything, you must first install `hdevtools` itself. The
+easiest way is from [Stackage][14] using [stack][15]:
+```
+$ stack install hdevtools
+```
+
+**Note:** As stack manages matching GHC versions, the appropriate compiler has
+to be available to `hdevtools`. Thus hdevtools has to be started with `stack exec`,
+for example using the alias:
+```
+$ alias hdevtools="stack exec --no-ghc-package-path hdevtools --"
+```
+
+Alternatively one can install from [Hackage][1] via cabal install:
+```
+$ cabal install hdevtools
+```
+
+Then you should install one or more of the following editor plugins:
+
+### Vim - [Syntastic][2] ###
+
+[Syntastic][2] is a popular syntax checking plugin for Vim, and is the
+recommended Vim integration of `hdevtools` syntax and type checking. Recent
+versions of Syntastic(since Sep. 2012) have builtin support for `hdevtools`.
+
+Simply install `hdevtools` (as above) and [Syntastic][2], and it will
+automatically check your Haskell files.
+
+[Syntastic][2] will respect the `g:hdevtools_options` variable (the same one as
+used by [vim-hdevtools][3], see below). See the section "Specifying GHC
+Options" below for details how to use it.
+
+### Vim - [vim-hdevtools][3] ###
+
+In addition to Syntastic, it is recommended that you also use
+[`vim-hdevtools`][3] for additional functionality.
+
+[`vim-hdevtools`][3] offers integration with the rest of the `hdevtools` tools,
+including retrieving info about the identifier under the cursor, and getting
+the type of the code under the cursor. Refer to its documentation for more
+details.
+
+### Emacs - [flycheck][5] ###
+
+[Flycheck][5] is a modern batteries-included
+syntax checker for Emacs, and there is a [flycheck-hdevtools][6] checker available.
+
+### Atom - [linter][8] ###
+
+There are *two* packages for the [Atom](https://atom.io) editor:
+
++ [linter-hdevtools][8] quickly finds and underlines type errors in Haskell files,
++ [hover-tooltips-hdevtools][9] displays the types of identifiers under the mouse.
+
+### Sublime - [SublimeLinter][10]
+
+[SublimeLinter][10] is a plugin for Sublime Text 3 that provides a framework
+for linting code. The [SublimeLinter-contrib-hdevtools][11] plugin uses
+`hdevtools` to typecheck Haskell code.
+
+### Manual Editor Integration for any Editor ###
+
+Most editors allow you to run a `make` command, and will then parse the output
+for errors and show line numbers, allowing you to jump between errors.
+
+The `hdevtools check` command is suitable for such usage.
+
+For example, in Vim something like this will work:
+
+    :let &makeprg='hdevtools check %'
+
+(Vim will replace the `%` character with the name of the current file). Then
+you can run
+
+    :make
+
+And Vim will invoke `hdevtools` to check the current file for errors, and then
+show a list of them and allow jumping to them.
+
+See the "Command Line Usage" section below for more information.
+
+Command Line Usage
+------------------
+
+Note: When using one of the above editor plugins, you don't really need to know
+this.
+
+### Available Commands and Help ###
+
+For the list of commands available, run:
+
+    $ hdevtools --help
+
+To get help for a specific command, run:
+
+    $ hdevtools [COMMAND] --help
+
+For example:
+
+    $ hdevtools check --help
+
+### The `hdevtools` background process ###
+
+The first time `hdevtools` runs a command, it will spawn a background process
+that will remain running forever. You can check the status of this background
+process by running:
+
+    $ hdevtools --status
+
+You can shutdown the background process by running:
+
+    $ hdevtools --stop-server
+
+Communication with the background process is done through a unix socket file.
+The default name is `.hdevtools.sock`, in the current directory. This allows
+you to use `hdevtools` with multiple projects simultaneously, without the
+background processes getting in the way of each other.
+
+You can use a different socket file name with the `--socket` option, which
+should be used for each invocation of `hdevtools`. Remember that when telling
+`hdevtools` to check a Haskell file, paths are relative to the path of the
+background process, not your current directory. This can cause problems, and
+therefore it is recommended that you leave the socket file as the default, and
+always run `hdevtools` from the same directory.
+
+You can specify the path to a target file with the `--path` option. This is
+useful for integration with IDEs that submit a *copy* of the original source
+file (in a temporary directory) to `hdevtools` making it impossible to extract
+the `.cabal` information for the file's project. In such cases, you can run as:
+
+    $ hdevtools check -p /path/to/file.hs /tmp/file.hs
+
+and `hdevtools` will use the given path to obtain the `.cabal` information.
+
+
+### Specifying GHC Options ###
+
+For most non-trivial projects, you will need to tell `hdevtools` about
+additional GHC options that your project requires.
+
+All `hdevtools` commands accept a `-g` flag for this purpose.
+
+For example:
+
+* Your project source code is in the directory `src`
+* You want to use the GHC option `-Wall`
+* You want to hide the package `transformers` to prevent conflicts
+
+Invoke `hdevtools` with something like this:
+
+    $ hdevtools check -g -isrc -g -Wall -g -hide-package -g transformers Foo.hs
+
+Notice that a `-g` flag is inserted before each GHC option. Don't try to string
+multiple GHC options together after a single `-g` flag:
+
+This won't work:
+
+    $ hdevtools check -g '-hide-package transformers' Foo.hs
+
+The Vim plugins allow setting GHC options in the `g:hdevtools_options`
+variable.  For example, for the above project, put the following in your
+`.vimrc`:
+
+    let g:hdevtools_options = '-g -isrc -g -Wall -g -hide-package -g transformers'
+
+In general, you will need to pass to `hdevtools` the same GHC options that you
+would pass to GHCi.
+
+Credits
+-------
+
+* `hdevtools` was inspired by [ghcmod][4].
+* development moved here from [bitc/hdevtools][12] and [schell/hdevtools][13].
+
+[1]: http://hackage.haskell.org/package/hdevtools
+[2]: https://github.com/scrooloose/syntastic
+[3]: https://github.com/bitc/vim-hdevtools
+[4]: http://www.mew.org/~kazu/proj/ghc-mod/en/
+[5]: https://github.com/flycheck/flycheck
+[6]: https://github.com/flycheck/flycheck-hdevtools
+[7]: https://atom.io
+[8]: https://atom.io/packages/linter-hdevtools
+[9]: https://atom.io/packages/hover-tooltips-hdevtools
+[10]: sublimelinter.com
+[11]: https://packagecontrol.io/packages/SublimeLinter-contrib-hdevtools
+[12]: https://github.com/bitc/hdevtools
+[13]: https://github.com/schell/hdevtools
+[14]: https://www.stackage.org/package/hdevtools
+[15]: haskellstack.org
diff --git a/hdevtools.cabal b/hdevtools.cabal
--- a/hdevtools.cabal
+++ b/hdevtools.cabal
@@ -1,6 +1,17 @@
 name:                hdevtools
-version:             0.1.2.2
+version:             0.1.3.0
 synopsis:            Persistent GHC powered background server for FAST haskell development tools
+license:             MIT
+license-file:        LICENSE
+author:              Bit Connor
+maintainer:          Sebastian Nagel <sebastian.nagel@ncoding.at>, 
+                     Ranjit Jhala <jhala@cs.ucsd.edu>
+copyright:           See AUTHORS file
+category:            Development
+homepage:            https://github.com/hdevtools/hdevtools/
+bug-reports:         https://github.com/hdevtools/hdevtools/issues/
+build-type:          Simple
+cabal-version:       >=1.8
 description:
     'hdevtools' is a backend for text editor plugins, to allow for things such as
     syntax and type checking of Haskell code, and retrieving type information, all
@@ -27,18 +38,9 @@
     for getting info about identifiers, and getting type information for snippets
     of code.
 
-license:             MIT
-license-file:        LICENSE
-author:              Bit Connor
-maintainer:          Sebastian Nagel <sebastian.nagel@ncoding.at>, 
-                     Ranjit Jhala <jhala@cs.ucsd.edu>
-copyright:           See AUTHORS file
-category:            Development
-homepage:            https://github.com/hdevtools/hdevtools/
-bug-reports:         https://github.com/hdevtools/hdevtools/issues/
-build-type:          Simple
-cabal-version:       >=1.8
-extra-source-files:  CHANGELOG.md
+extra-source-files:  
+  CHANGELOG.md
+  README.md
 
 source-repository head
   type:                git
diff --git a/src/Cabal.hs b/src/Cabal.hs
--- a/src/Cabal.hs
+++ b/src/Cabal.hs
@@ -168,7 +168,6 @@
                                        , ghcOptPackages = overNubListR (filter (\(_, pkgId, _) -> Just (pkgName pkgId) /= mbLibName)) $ (ghcOptPackages ghcOpts')
                                        , ghcOptSourcePath = overNubListR (map (baseDir </>)) (ghcOptSourcePath ghcOpts')
                                        }
-                putStrLn "configuring"
                 (ghcInfo,_,_) <- GHC.configure silent Nothing Nothing defaultProgramConfiguration
 
                 return $ Right $ renderGhcOptions ghcInfo ghcOpts
@@ -219,7 +218,7 @@
   where
     pkgDbKey = "package-db:"
     parse = head . filter (pkgDbKey `isPrefixOf`) . lines
-    extractValue = fst . break isSpace . dropWhile isSpace . drop (length pkgDbKey)
+    extractValue = fst . break (`elem` "\n\r") . dropWhile isSpace . drop (length pkgDbKey)
 
 
 findCabalFile :: FilePath -> IO (Maybe FilePath)
diff --git a/src/CommandLoop.hs b/src/CommandLoop.hs
--- a/src/CommandLoop.hs
+++ b/src/CommandLoop.hs
@@ -3,7 +3,7 @@
     ( newCommandLoopState
     , Config(..)
     , CabalConfig(..)
-    , newConfig
+    , updateConfig
     , startCommandLoop
     ) where
 
@@ -49,7 +49,7 @@
     , cabalConfigOpts :: [String]
     , cabalConfigLastUpdatedAt :: EpochTime
     }
-    deriving Eq
+    deriving (Eq, Show)
 
 mkCabalConfig :: FilePath -> [String] -> IO CabalConfig
 mkCabalConfig path opts = do
@@ -64,17 +64,23 @@
     , configCabal   :: Maybe CabalConfig
     , configStack   :: Maybe StackConfig
     }
-    deriving Eq
+    deriving (Eq, Show)
 
-newConfig :: CommandExtra -> IO Config
-newConfig cmdExtra = do
-    mbCabalConfig <- traverse (\path -> mkCabalConfig path (ceCabalOptions cmdExtra)) $ ceCabalConfig cmdExtra
-    mbStackConfig <- getStackConfig cmdExtra
+updateConfig :: Maybe Config -> CommandExtra -> IO Config
+updateConfig mConfig cmdExtra = do
+    mbCabalConfig <- traverse (\path -> mkCabalConfig path (ceCabalOptions cmdExtra)) $
+      ceCabalFilePath cmdExtra
 
+    mbStackConfig <- if (stackYaml <$> msc) == (ceStackYamlPath cmdExtra)
+      then return msc
+      else getStackConfig cmdExtra
+
     return $ Config { configGhcOpts = "-O0" : ceGhcOptions cmdExtra
                     , configCabal = mbCabalConfig
                     , configStack = mbStackConfig
                     }
+ where
+  msc = mConfig >>= configStack
 
 type CommandObj = (Command, Config)
 
diff --git a/src/Main.hs b/src/Main.hs
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -17,6 +17,7 @@
 import CommandArgs
 import Daemonize (daemonize)
 import Server (startServer, createListenSocket)
+import Stack (findStackYaml)
 import Types (Command(..), CommandExtra(..), emptyCommandExtra)
 
 absoluteFilePath :: FilePath -> IO FilePath
@@ -56,11 +57,13 @@
     let argPath = pathArg args
     dir  <- maybe getCurrentDirectory (return . takeDirectory) argPath
     mCabalFile <- findCabalFile dir >>= traverse absoluteFilePath
+    mStackYaml <- findStackYaml dir
     let extra = emptyCommandExtra
-                    { ceGhcOptions  = ghcOpts args
-                    , ceCabalConfig = mCabalFile
-                    , cePath        = argPath
+                    { cePath = argPath
+                    , ceGhcOptions  = ghcOpts args
+                    , ceCabalFilePath = mCabalFile
                     , ceCabalOptions = cabalOpts args
+                    , ceStackYamlPath = mStackYaml
                     }
     let defaultSocketPath = maybe "" takeDirectory mCabalFile </> defaultSocketFile
     let sock = fromMaybe defaultSocketPath $ socket args
diff --git a/src/Server.hs b/src/Server.hs
--- a/src/Server.hs
+++ b/src/Server.hs
@@ -10,7 +10,7 @@
 import System.IO (Handle, hClose, hFlush, hGetLine, hPutStrLn)
 import System.IO.Error (ioeGetErrorType, isAlreadyInUseError, isDoesNotExistError)
 
-import CommandLoop (newCommandLoopState, Config, newConfig, startCommandLoop)
+import CommandLoop (newCommandLoopState, Config, updateConfig, startCommandLoop)
 import Types (ClientDirective(..), Command, emptyCommandExtra, ServerDirective(..))
 import Util (readMaybe)
 
@@ -38,8 +38,9 @@
     go sock = do
         state <- newCommandLoopState
         currentClient <- newIORef Nothing
-        config <- newConfig emptyCommandExtra
-        startCommandLoop state (clientSend currentClient) (getNextCommand currentClient sock) config Nothing
+        configRef <- newIORef Nothing
+        config <- updateConfig Nothing emptyCommandExtra
+        startCommandLoop state (clientSend currentClient) (getNextCommand currentClient sock configRef) config Nothing
 
     removeSocketFile :: IO ()
     removeSocketFile = do
@@ -60,8 +61,8 @@
     ignoreEPipe = handleJust (guard . isEPipe) (const $ return ())
     isEPipe = (==ResourceVanished) . ioeGetErrorType
 
-getNextCommand :: IORef (Maybe Handle) -> Socket -> IO (Maybe (Command, Config))
-getNextCommand currentClient sock = do
+getNextCommand :: IORef (Maybe Handle) -> Socket -> IORef (Maybe Config) -> IO (Maybe (Command, Config))
+getNextCommand currentClient sock config = do
     checkCurrent <- readIORef currentClient
     case checkCurrent of
         Just h -> hClose h
@@ -74,16 +75,18 @@
         Nothing -> do
             clientSend currentClient $ ClientUnexpectedError $
                 "The client sent an invalid message to the server: " ++ show msg
-            getNextCommand currentClient sock
+            getNextCommand currentClient sock config
         Just (SrvCommand cmd cmdExtra) -> do
-            config <- newConfig cmdExtra
-            return $ Just (cmd, config)
+            curConfig <- readIORef config
+            config' <- updateConfig curConfig cmdExtra
+            writeIORef config (Just config')
+            return $ Just (cmd, config')
         Just SrvStatus -> do
             mapM_ (clientSend currentClient) $
                 [ ClientStdout "Server is running."
                 , ClientExit ExitSuccess
                 ]
-            getNextCommand currentClient sock
+            getNextCommand currentClient sock config
         Just SrvExit -> do
             mapM_ (clientSend currentClient) $
                 [ ClientStdout "Shutting down server."
diff --git a/src/Stack.hs b/src/Stack.hs
--- a/src/Stack.hs
+++ b/src/Stack.hs
@@ -2,7 +2,7 @@
 module Stack
       ( -- * The bits of information needed from `stack`
         StackConfig (..)
-        -- * Run `stack exec` to compute @StackConfig@
+      , findStackYaml
       , getStackConfig
       ) where
 
@@ -21,45 +21,28 @@
 import Control.Exception
 import Types
 
-
--- | This module adds support for `stack`, as follows:
---   1. Figure out if the target-file is in a stack project,
---   2. If `stack` in available in PATH, run `stack exec` to extract
---      `StackConfig`
---   3. The `StackConfig` is used to suitably alter the cabal ConfigFlags in
---      Cabal.hs
-
-
 -- TODO: Move into Types?
-data StackConfig = StackConfig { stackDist :: FilePath
+data StackConfig = StackConfig { stackYaml :: FilePath
+                               , stackDist :: FilePath
                                , stackDbs  :: [FilePath]
                                }
                    deriving (Eq, Show)
 
---------------------------------------------------------------------------------
-getStackConfig :: CommandExtra -> IO (Maybe StackConfig)
---------------------------------------------------------------------------------
-getStackConfig ce = case cePath ce of
-                      Nothing -> return Nothing
-                      Just p  -> getStackConfig' p
-
-getStackConfig' :: FilePath -> IO (Maybe StackConfig)
-getStackConfig' p = do
-  mbYaml <- getStackYaml p
-  case mbYaml of
-    Nothing -> return Nothing
-    Just _  -> do mdbs <- getStackDbs p
-                  mdst <- getStackDist p
-                  return $ StackConfig <$> mdst <*> mdbs
-
---------------------------------------------------------------------------------
-getStackYaml :: FilePath -> IO (Maybe FilePath)
---------------------------------------------------------------------------------
-getStackYaml p = listToMaybe <$> filterM doesFileExist paths
+-- | Search for a @stack.yaml@ upwards in given file path tree.
+findStackYaml :: FilePath -> IO (Maybe FilePath)
+findStackYaml p = listToMaybe <$> filterM doesFileExist paths
   where
     paths      = [ d </> "stack.yaml" | d <- pathsToRoot dir]
     dir        = takeDirectory p
 
+-- | Run @stack path@ to compute @StackConfig@
+getStackConfig :: CommandExtra -> IO (Maybe StackConfig)
+getStackConfig CommandExtra { ceStackYamlPath = Nothing } = return Nothing
+getStackConfig CommandExtra { ceStackYamlPath = Just p } = do
+    dbs <- getStackDbs p
+    dist <- getStackDist p
+    return $ StackConfig p <$> dist <*> dbs
+
 pathsToRoot :: FilePath -> [FilePath]
 pathsToRoot p
   | p == parent = [p]
@@ -84,7 +67,7 @@
                        Just pp -> Just <$> extractDbs pp
                        Nothing -> return Nothing
   where
-    cmd       = "stack --verbosity quiet exec printenv GHC_PACKAGE_PATH"
+    cmd       = "stack path --ghc-package-path"
 
 extractDbs :: String -> IO [FilePath]
 extractDbs = filterM doesDirectoryExist . stringPaths
diff --git a/src/Types.hs b/src/Types.hs
--- a/src/Types.hs
+++ b/src/Types.hs
@@ -9,17 +9,19 @@
 import System.Exit (ExitCode)
 
 data CommandExtra = CommandExtra
-  { ceGhcOptions  :: [String]
-  , ceCabalConfig :: Maybe FilePath
-  , cePath        :: Maybe FilePath
+  { cePath :: Maybe FilePath
+  , ceGhcOptions :: [String]
+  , ceCabalFilePath :: Maybe FilePath
   , ceCabalOptions :: [String]
+  , ceStackYamlPath :: Maybe FilePath
   } deriving (Read, Show)
 
 emptyCommandExtra :: CommandExtra
-emptyCommandExtra = CommandExtra { ceGhcOptions  = []
-                                 , ceCabalConfig = Nothing
-                                 , cePath        = Nothing
+emptyCommandExtra = CommandExtra { cePath = Nothing
+                                 , ceGhcOptions  = []
+                                 , ceCabalFilePath = Nothing
                                  , ceCabalOptions = []
+                                 , ceStackYamlPath = Nothing
                                  }
 
 data ServerDirective
