diff --git a/CHANGES.markdown b/CHANGES.markdown
--- a/CHANGES.markdown
+++ b/CHANGES.markdown
@@ -1,3 +1,15 @@
+0.4: 9 August 2013
+------------------
+
+* Add hsenv compatibility.
+* Big improvements in the way rebuilding is handled:
+    - Strip comments before deciding whether to rebuild, so
+      changing only comments does not trigger a rebuild
+    - Take local imports into account: if a diagram has an import
+      which corresponds to a local file, rebuild if that file has
+      changed
+    - Rebuild when options (e.g. size) change
+
 0.3.0.1 (3 April 2013)
 ----------------------
 
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,7 @@
-Copyright (c) 2012, Brent Yorgey
+Copyright (c) 2012-2013 diagrams-builder team:
+
+  Jeffrey Rosenbluth <jeffrey.rosenbluth@gmail.com>
+  Brent Yorgey <byorgey@gmail.com>
 
 All rights reserved.
 
diff --git a/diagrams-builder.cabal b/diagrams-builder.cabal
--- a/diagrams-builder.cabal
+++ b/diagrams-builder.cabal
@@ -1,5 +1,5 @@
 name:                diagrams-builder
-version:             0.3.0.1
+version:             0.4
 synopsis:            hint-based build service for the diagrams graphics EDSL.
 
 description:         @diagrams-builder@ provides backend-agnostic tools for
@@ -25,7 +25,7 @@
                      A LaTeX package, @diagrams-latex.sty@, is also
                      provided in the @latex/@ directory of the source
                      distribution, which renders diagrams code found
-                     within @diagram@ environments. Note that 
+                     within @diagram@ environments. Note that
                      @diagrams-latex.sty@ is licensed under the GPL.
 homepage:            http://projects.haskell.org/diagrams
 license:             BSD3
@@ -47,10 +47,12 @@
                        Diagrams.Builder.Modules
                        Diagrams.Builder.CmdLine
   build-depends:       base >=4.2 && < 4.7,
-                       diagrams-lib >=0.6 && < 0.7,
+                       diagrams-lib >=0.6 && < 0.8,
                        hint ==0.3.*,
                        directory,
                        filepath,
+                       transformers >= 0.3 && < 0.4,
+                       split >= 0.2 && < 0.3,
                        haskell-src-exts >= 1.13.1 && < 1.14,
                        cryptohash >= 0.8 && < 0.10,
                        bytestring >= 0.9.2 && < 0.11,
@@ -92,8 +94,8 @@
                        filepath,
                        directory,
                        diagrams-builder,
-                       diagrams-lib >= 0.6 && < 0.7,
-                       diagrams-cairo >= 0.6 && < 0.7,
+                       diagrams-lib >= 0.6 && < 0.8,
+                       diagrams-cairo >= 0.6 && < 0.8,
                        cmdargs >= 0.6 && < 0.11
 
 executable diagrams-builder-svg
@@ -111,8 +113,8 @@
                        filepath,
                        directory,
                        diagrams-builder,
-                       diagrams-lib >= 0.6 && < 0.7,
-                       diagrams-svg >= 0.6 && < 0.7,
+                       diagrams-lib >= 0.6 && < 0.8,
+                       diagrams-svg >= 0.6 && < 0.8,
                        blaze-svg >= 0.3.3 && < 0.4,
                        bytestring >= 0.9.2 && < 0.11,
                        cmdargs >= 0.6 && < 0.11
@@ -123,7 +125,7 @@
   default-language:    Haskell2010
   other-extensions:    DeriveDataTypeable
                        RecordWildCards
-  
+
   if !flag(ps)
     buildable: False
 
@@ -132,6 +134,6 @@
                        filepath,
                        directory,
                        diagrams-builder,
-                       diagrams-lib >= 0.6 && < 0.7,
-                       diagrams-postscript >= 0.6 && < 0.7,
+                       diagrams-lib >= 0.6 && < 0.8,
+                       diagrams-postscript >= 0.6 && < 0.8,
                        cmdargs >= 0.6 && < 0.11
diff --git a/src/Diagrams/Builder.hs b/src/Diagrams/Builder.hs
--- a/src/Diagrams/Builder.hs
+++ b/src/Diagrams/Builder.hs
@@ -1,8 +1,8 @@
-{-# LANGUAGE StandaloneDeriving
-           , DeriveDataTypeable
-           , ScopedTypeVariables
-           , FlexibleContexts
-  #-}
+{-# LANGUAGE DeriveDataTypeable    #-}
+{-# LANGUAGE FlexibleContexts      #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE ScopedTypeVariables   #-}
+{-# LANGUAGE StandaloneDeriving    #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 
 -----------------------------------------------------------------------------
@@ -37,23 +37,33 @@
 
        ) where
 
-import Diagrams.Builder.Modules
-import Diagrams.Builder.CmdLine
-
-import Diagrams.Prelude hiding ((<.>), e)
-
-import Language.Haskell.Exts (prettyPrint)
-import Language.Haskell.Interpreter hiding (ModuleName)
+import           Control.Monad                (guard, mplus, mzero)
+import           Control.Monad.Trans.Maybe    (MaybeT, runMaybeT)
+import           Crypto.Hash                  (Digest, MD5,
+                                               digestToHexByteString, hash)
+import qualified Data.ByteString.Char8        as B
+import           Data.List                    (nub)
+import           Data.List.Split              (splitOn)
+import           Data.Maybe                   (catMaybes, fromMaybe)
+import           Data.Typeable                (Typeable)
+import           System.Directory             (doesFileExist,
+                                               getDirectoryContents,
+                                               getTemporaryDirectory,
+                                               removeFile)
+import           System.FilePath              (takeBaseName, (<.>), (</>))
+import           System.IO                    (hClose, hPutStr, openTempFile)
 
-import System.IO
-import System.FilePath
-import System.Directory
+import           Language.Haskell.Exts        (ImportDecl, Module (..),
+                                               ModuleName (..), importModule,
+                                               prettyPrint)
+import           Language.Haskell.Interpreter hiding (ModuleName)
 
-import Crypto.Hash (Digest, MD5, digestToHexByteString, hash)
+import           Diagrams.Builder.CmdLine
+import           Diagrams.Builder.Modules
+import           Diagrams.Prelude             hiding (e, (<.>))
+import           System.Environment           (getEnvironment)
+import           Language.Haskell.Interpreter.Unsafe (unsafeRunInterpreterWithArgs)
 
-import qualified Data.ByteString.Char8 as B
-import Data.List (nub)
-import Data.Typeable
 deriving instance Typeable Any
 
 ------------------------------------------------------------
@@ -67,15 +77,18 @@
 
 -- | Set up the module to be interpreted, in the context of the
 --   necessary imports.
-setDiagramImports :: MonadInterpreter m
-                  => String      -- ^ Filename of the module containing the diagrams
-                  -> [String]    -- ^ Additional necessary
-                                 --   imports. @Prelude@,
-                                 --   @Diagrams.Prelude@,
-                                 --   @Diagrams.Core.Types@,
-                                 --   and @Data.Monoid@ are included
-                                 --   by default.
-                  -> m ()
+setDiagramImports
+  :: MonadInterpreter m
+  => String
+     -- ^ Filename of the module containing the diagrams
+
+  -> [String]
+     -- ^ Additional necessary imports. @Prelude@, @Diagrams.Prelude@,
+     --   @Diagrams.Core.Types@, and @Data.Monoid@ are included by
+     --   default.
+
+  -> m ()
+
 setDiagramImports m imps = do
     loadModules [m]
     setTopLevelModules [takeBaseName m]
@@ -86,21 +99,31 @@
                  ]
                  ++ imps
 
+getHsenvArgv :: IO [String]
+getHsenvArgv = do
+  env <- getEnvironment
+  return $ case (lookup "HSENV" env) of
+             Nothing -> []
+             _       -> hsenvArgv
+                 where hsenvArgv = words $ fromMaybe "" (lookup "PACKAGE_DB_FOR_GHC" env)
+
 -- | Interpret a diagram expression based on the contents of a given
 --   source file, using some backend to produce a result.
-interpretDiagram :: forall b v.
-                  ( Typeable b, Typeable v
-                  , InnerSpace v, OrderedField (Scalar v), Backend b v
-                  )
-               => b             -- ^ Backend token
-               -> v             -- ^ Dummy vector to identify the vector space
-               -> Options b v   -- ^ Rendering options
-               -> FilePath      -- ^ Filename of the module containing the example
-               -> [String]      -- ^ Additional imports needed
-               -> String        -- ^ Expression of type @Diagram b v@ to be compiled
-               -> IO (Either InterpreterError (Result b v))
-interpretDiagram b _ opts m imps dexp =
-    runInterpreter $ do
+interpretDiagram
+  :: forall b v.
+     ( Typeable b, Typeable v
+     , InnerSpace v, OrderedField (Scalar v), Backend b v
+     )
+  => b             -- ^ Backend token
+  -> v             -- ^ Dummy vector to identify the vector space
+  -> Options b v   -- ^ Rendering options
+  -> FilePath      -- ^ Filename of the module containing the example
+  -> [String]      -- ^ Additional imports needed
+  -> String        -- ^ Expression of type @Diagram b v@ to be compiled
+  -> IO (Either InterpreterError (Result b v))
+interpretDiagram b _ opts m imps dexp = do
+    args <- liftIO getHsenvArgv
+    unsafeRunInterpreterWithArgs args $ do
       setDiagramImports m imps
       d <- interpret dexp (as :: Diagram b v)
       return (renderDia b opts d)
@@ -131,63 +154,60 @@
 --   module and interpreting the given expression.  Can return either
 --   a parse error if the source does not parse, an interpreter error,
 --   or the final result.
-buildDiagram :: ( Typeable b, Typeable v
-                , InnerSpace v, OrderedField (Scalar v), Backend b v
-                )
-             => b              -- ^ Backend token
-             -> v              -- ^ Dummy vector to fix the vector type
-             -> Options b v    -- ^ Backend-specific options to use
-             -> [String]       -- ^ Source code snippets.  Each should
-                               --   be a syntactically valid Haskell
-                               --   module.  They will be combined
-                               --   intelligently, /i.e./ not just
-                               --   pasted together textually but
-                               --   combining pragmas, imports,
-                               --   /etc./ separately.
-             -> String         -- ^ Diagram expression to interpret
-             -> [String]       -- ^ Extra @LANGUAGE@ pragmas to use
-                               --   (@NoMonomorphismRestriction@ is used
-                               --   by default.)
-             -> [String]       -- ^ Additional imports
-                               --   ("Diagrams.Prelude" is imported by
-                               --   default).
-             -> (String -> IO (x, Maybe (Options b v -> Options b v)))
-                               -- ^ A function to decide whether a
-                               --   particular diagram needs to be
-                               --   regenerated.  It will be passed
-                               --   the final assembled source for the
-                               --   diagram (but with the module name
-                               --   set to @Main@ instead of something
-                               --   auto-generated, so that hashing
-                               --   the source will produce consistent
-                               --   results across runs). It can
-                               --   return some information (such as a
-                               --   hash of the source) via the @x@
-                               --   result, which will be passed
-                               --   through to the result of
-                               --   'buildDiagram'.  More importantly,
-                               --   it decides whether the diagram
-                               --   should be built: a result of
-                               --   'Just' means the diagram /should/
-                               --   be built; 'Nothing' means it
-                               --   should not. In the case that it
-                               --   should be built, it returns a
-                               --   function for updating the
-                               --   rendering options.  This could be
-                               --   used, /e.g./, to request a
-                               --   filename based on a hash of the
-                               --   source.
-                               --
-                               --   Two standard decision functions
-                               --   are provided for convenience:
-                               --   'alwaysRegenerate' returns no
-                               --   extra information and always
-                               --   decides to regenerate the diagram;
-                               --   'hashedRegenerate' creates a hash
-                               --   of the diagram source and looks
-                               --   for a file with that name in a
-                               --   given directory.
-             -> IO (BuildResult b v x)
+buildDiagram
+  :: ( Typeable b, Typeable v
+     , InnerSpace v, OrderedField (Scalar v), Backend b v
+     , Show (Options b v)
+     )
+  => b
+     -- ^ Backend token
+
+  -> v
+     -- ^ Dummy vector to fix the vector type
+
+  -> Options b v
+     -- ^ Backend-specific options to use
+
+  -> [String]
+     -- ^ Source code snippets.  Each should be a syntactically valid
+     --   Haskell module.  They will be combined intelligently, /i.e./
+     --   not just pasted together textually but combining pragmas,
+     --   imports, /etc./ separately.
+
+  -> String
+     -- ^ Diagram expression to interpret
+
+  -> [String]
+     -- ^ Extra @LANGUAGE@ pragmas to use (@NoMonomorphismRestriction@
+     --   is used by default.)
+
+  -> [String]
+     -- ^ Additional imports ("Diagrams.Prelude" is imported by
+     --   default).
+
+  -> (String -> IO (x, Maybe (Options b v -> Options b v)))
+     -- ^ A function to decide whether a particular diagram needs to
+     --   be regenerated.  It will be passed the final assembled
+     --   source for the diagram (but with the module name set to
+     --   @Main@ instead of something auto-generated, so that hashing
+     --   the source will produce consistent results across runs). It
+     --   can return some information (such as a hash of the source)
+     --   via the @x@ result, which will be passed through to the
+     --   result of 'buildDiagram'.  More importantly, it decides
+     --   whether the diagram should be built: a result of 'Just'
+     --   means the diagram /should/ be built; 'Nothing' means it
+     --   should not. In the case that it should be built, it returns
+     --   a function for updating the rendering options.  This could
+     --   be used, /e.g./, to request a filename based on a hash of
+     --   the source.
+     --
+     --   Two standard decision functions are provided for
+     --   convenience: 'alwaysRegenerate' returns no extra information
+     --   and always decides to regenerate the diagram;
+     --   'hashedRegenerate' creates a hash of the diagram source and
+     --   looks for a file with that name in a given directory.
+
+  -> IO (BuildResult b v x)
 buildDiagram b v opts source dexp langs imps shouldRegen = do
   let source'   = map unLit source
   case createModule
@@ -196,8 +216,9 @@
          ("Diagrams.Prelude" : imps)
          source' of
     Left  err -> return (ParseErr err)
-    Right m   -> do
-      regen <- shouldRegen (prettyPrint m ++ dexp)
+    Right m@(Module _ _ _ _ _ srcImps _) -> do
+      liHashes <- getLocalImportHashes srcImps
+      regen    <- shouldRegen (prettyPrint m ++ dexp ++ show opts ++ concat liHashes)
       case regen of
         (info, Nothing)  -> return $ Skipped info
         (info, Just upd) -> do
@@ -211,6 +232,39 @@
           removeFile tmp
           return $ either InterpErr (OK info) compilation
 
+-- | Take a list of imports, and return hashes of the contents of
+--   those imports which are local.  Note, this only finds imports
+--   which exist relative to the current directory, which is not as
+--   general as it probably should be --- we could be calling
+--   'buildDiagram' on source code which lives anywhere.
+getLocalImportHashes :: [ImportDecl] -> IO [String]
+getLocalImportHashes
+  = (fmap . map) hashStr
+  . fmap catMaybes
+  . mapM getLocalSource
+  . map (foldr1 (</>) . splitOn "." . getModuleName . importModule)
+
+-- | Given a relative path with no extension, like
+--   @\"Foo\/Bar\/Baz\"@, check whether such a file exists with either
+--   a @.hs@ or @.lhs@ extension; if so, return its /pretty-printed/
+--   contents (removing all comments, canonicalizing formatting, /etc./).
+getLocalSource :: FilePath -> IO (Maybe String)
+getLocalSource f = runMaybeT $ do
+  contents <- getLocal f
+  case (doModuleParse . unLit) contents of
+    Left _  -> mzero
+    Right m -> return (prettyPrint m)
+
+-- | Given a relative path with no extension, like
+--   @\"Foo\/Bar\/Baz\"@, check whether such a file exists with either a
+--   @.hs@ or @.lhs@ extension; if so, return its contents.
+getLocal :: FilePath -> MaybeT IO String
+getLocal m = tryExt "hs" `mplus` tryExt "lhs"
+  where
+    tryExt ext = do
+      let f = m <.> ext
+      liftIO (doesFileExist f) >>= guard >> liftIO (readFile f)
+
 -- | Convenience function suitable to be given as the final argument
 --   to 'buildDiagram'.  It implements the simple policy of always
 --   rebuilding every diagram.
@@ -227,25 +281,23 @@
 --   hash.  (Most likely, one would want to set the requested output
 --   file to the hash followed by some extension.)  It also returns
 --   the generated hash.
-hashedRegenerate :: (String -> a -> a)  -- ^ A function for computing
-                                        --   an update to rendering
-                                        --   options, given a new base
-                                        --   filename computed from a
-                                        --   hash of the diagram
-                                        --   source.
-                 -> FilePath            -- ^ The directory in which to
-                                        --   look for generated files
-                 -> String              -- ^ The \"source\" to
-                                        -- hash. Note that this does
-                                        -- not actually have to be
-                                        -- valid source code.  A
-                                        -- common trick is to
-                                        -- concatenate the actual
-                                        -- source code with String
-                                        -- representations of any
-                                        -- other information on which
-                                        -- the diagram depends.
-                 -> IO (String, Maybe (a -> a))
+hashedRegenerate
+  :: (String -> a -> a)
+     -- ^ A function for computing an update to rendering options,
+     --   given a new base filename computed from a hash of the
+     --   diagram source.
+
+  -> FilePath
+     -- ^ The directory in which to look for generated files
+
+  -> String
+     -- ^ The \"source\" to hash. Note that this does not actually
+     -- have to be valid source code.  A common trick is to
+     -- concatenate the actual source code with String representations
+     -- of any other information on which the diagram depends.
+
+  -> IO (String, Maybe (a -> a))
+
 hashedRegenerate upd dir src = do
   let fileBase = hashStr src
   files <- getDirectoryContents dir
