diff --git a/pier.cabal b/pier.cabal
--- a/pier.cabal
+++ b/pier.cabal
@@ -2,12 +2,22 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 77964a51e3c513e1ee2b7cb6677f3c8d4cfd18568bcf0c53808f80cd1fb5a611
+-- hash: 115fb97e6ebce1760b087111daeab4b098c7780671dbb3ff12cf5bb265b170b1
 
 name:           pier
-version:        0.2.0.1
+version:        0.3.0.0
 synopsis:       Yet another Haskell build system.
-description:    A build system for Haskell projects, built on top of [shake](http://shakebuild.com).
+description:    Pier is a command-line tool for building Haskell projects.  It is
+                similar in purpose to <https://www.haskellstack.org Stack>,
+                but explores a different design:
+                .
+                * Pier implements the fine-grained Haskell build logic from (nearly)
+                  scratch.  In contrast, Stack relies on Cabal to implement most of its
+                  build steps, giving it a more coarse control over the build.
+                * Pier uses general-purpose libraries for implementing build systems, namely
+                  <https://shakebuild.com Shake> and <https://hackage.haskell.org/package/pier-core pier-core>.
+                .
+                For more information, see the official <https://github.com/judah/pier/blob/master/Readme.md documentation>.
 category:       Development
 homepage:       https://github.com/judah/pier#readme
 bug-reports:    https://github.com/judah/pier/issues
@@ -50,7 +60,7 @@
     , directory >=1.3.1 && <1.4
     , hashable ==1.2.*
     , optparse-applicative
-    , pier-core ==0.2.*
+    , pier-core ==0.3.*
     , shake ==0.16.*
     , split ==0.2.*
     , text ==1.2.*
diff --git a/src/Main.hs b/src/Main.hs
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -47,22 +47,18 @@
     { pierYaml :: Last FilePath
     , shakeFlags :: [String]
     , lastHandleTemps :: Last HandleTemps
-    , lastDownloadLocation :: Last DownloadLocation
     , lastSharedCache :: Last UseSharedCache
     }
 
 instance Semigroup CommonOptions where
-    CommonOptions y f ht dl sc <> CommonOptions y' f' ht' dl' sc'
-        = CommonOptions (y <> y') (f <> f') (ht <> ht') (dl <> dl') (sc <> sc')
+    CommonOptions y f ht sc <> CommonOptions y' f' ht' sc'
+        = CommonOptions (y <> y') (f <> f') (ht <> ht') (sc <> sc')
 
 handleTemps :: CommonOptions -> HandleTemps
 handleTemps = fromMaybe RemoveTemps . getLast . lastHandleTemps
 
-downloadLocation :: CommonOptions -> DownloadLocation
-downloadLocation = fromMaybe DownloadToHome . getLast . lastDownloadLocation
-
 sharedCache :: CommonOptions -> UseSharedCache
-sharedCache = fromMaybe DontUseSharedCache . getLast . lastSharedCache
+sharedCache = fromMaybe UseHomeSharedCache . getLast . lastSharedCache
 
 -- | Parse command-independent options.
 --
@@ -75,7 +71,6 @@
 parseCommonOptions h = CommonOptions <$> parsePierYaml
                                      <*> parseShakeFlags h
                                      <*> parseHandleTemps
-                                     <*> parseDownloadLocation
                                      <*> parseSharedCache
   where
     parsePierYaml :: Parser (Last FilePath)
@@ -89,22 +84,20 @@
                 (long "keep-temps"
                 <> help "Don't remove temporary directories")
 
-    -- OK, this doesn't work!  Nice catch.
-    -- Last isn't what we want I guess.
-    parseDownloadLocation :: Parser (Last DownloadLocation)
-    parseDownloadLocation =
-        Last <$>
-            flag Nothing (Just DownloadLocal)
-                (long "download-local"
-                <> help "Store downloads in the local _pier directory")
-
     parseSharedCache :: Parser (Last UseSharedCache)
-    parseSharedCache = Last <$>
-                        flag Nothing (Just UseSharedCache)
-                            ( long "shared-cache"
-                            <> help "Use a shared cache at ~/.pier/artifact")
+    parseSharedCache = fmap Last $
+                        flag Nothing (Just DontUseSharedCache)
+                            ( long "no-shared-cache"
+                            <> help "Don't use the shared cache at ~/.pier/artifact")
+                       <|> optional (fmap UseSharedCacheAt $ strOption
+                                        $ long "shared-cache-path"
+                                            <> metavar "PATH"
+                                            <> help "Location of shared cache")
 
-data UseSharedCache = UseSharedCache | DontUseSharedCache
+data UseSharedCache
+    = UseHomeSharedCache
+    | DontUseSharedCache
+    | UseSharedCacheAt FilePath
     deriving Show
 
 data Hidden = Hidden | Shown
@@ -302,7 +295,7 @@
             buildPlanRules
             buildPackageRules
             artifactRules cache ht
-            downloadRules $ downloadLocation commonOpts
+            downloadRules cache
             installGhcRules
             configRules pierYamlFile
             runWithOptions next ht cmdOpt
@@ -310,9 +303,14 @@
 
 getSharedCache :: UseSharedCache -> IO (Maybe SharedCache)
 getSharedCache DontUseSharedCache = return Nothing
-getSharedCache UseSharedCache = do
-    h <- getHomeDirectory
-    return $ Just $ SharedCache $ h </> ".pier" </> "artifact"
+getSharedCache (UseSharedCacheAt f) = return (Just $ SharedCache f)
+getSharedCache UseHomeSharedCache = do
+    env <- lookupEnv "PIER_SHARED_CACHE"
+    Just . SharedCache <$> case env of
+        Just p -> return p
+        Nothing -> do
+            h <- getHomeDirectory
+            return $ h </> ".pier" </> "artifact"
 
 -- TODO: move into Build.hs
 data Target
diff --git a/src/Pier/Build/Components.hs b/src/Pier/Build/Components.hs
--- a/src/Pier/Build/Components.hs
+++ b/src/Pier/Build/Components.hs
@@ -275,7 +275,7 @@
     let out = "bin" </> binaryName bin
     tinfo <- getTargetInfo confd (binaryBuildInfo bin) (TargetBinary $ binaryPath bin)
                 transDeps ghc
-    result <- runCommand (output out)
+    result <- runCommandOutput out
         $ message (display (package desc) ++ ": building "
                         ++ binaryTypeName bin ++ " " ++ binaryName bin)
         <> ghcCommand ghc deps confd tinfo
diff --git a/src/Pier/Build/Config.hs b/src/Pier/Build/Config.hs
--- a/src/Pier/Build/Config.hs
+++ b/src/Pier/Build/Config.hs
@@ -99,7 +99,7 @@
     -- We do it again later so the full PackageDescription
     -- doesn't need to get saved in the cache.
     pkgDescs <- mapM (\f -> do
-                        let a = externalFile f
+                        let a = external f
                         pkg <- parseCabalFileInDir a
                         return (packageName pkg, (a, packageVersion pkg)))
                     $ packages yaml
diff --git a/src/Pier/Build/Custom.hs b/src/Pier/Build/Custom.hs
--- a/src/Pier/Build/Custom.hs
+++ b/src/Pier/Build/Custom.hs
@@ -46,7 +46,7 @@
              glr_templates
         ]
     let files = "data-files"
-    runCommand (output files) $
+    runCommandOutput files $
         foldMap (\a -> shadow a $ files </> takeBaseName (pathIn a))
             as
   where
@@ -88,7 +88,7 @@
              wrappers
         ]
     let files = "data-files"
-    runCommand (output files) $
+    runCommandOutput files $
         foldMap (\a -> shadow a $ files </> takeBaseName (pathIn a))
             as
   where
@@ -118,7 +118,7 @@
 processTemplate
     :: InstalledGhc -> Artifact -> String -> [String] -> Action Artifact
 processTemplate ghc baseTemplate outFile args = do
-    a <- runCommand (output outFile)
+    a <- runCommandOutput outFile
         $ ghcProg ghc
             (["-o", outFile, "-E", "-cpp", pathIn baseTemplate] ++ args)
         <> input baseTemplate
diff --git a/src/Pier/Build/Module.hs b/src/Pier/Build/Module.hs
--- a/src/Pier/Build/Module.hs
+++ b/src/Pier/Build/Module.hs
@@ -109,7 +109,7 @@
         exists yFile
         let relOutput = toFilePath m <.> "hs"
         happy <- lift $ askBuiltExecutable (mkPackageName "happy") "happy"
-        lift . runCommand (output relOutput)
+        lift . runCommandOutput relOutput
              $ progBinary happy
                      ["-agc", "-o", relOutput, pathIn yFile]
                 <> input yFile
@@ -118,7 +118,7 @@
         let hsc = srcDir /> toFilePath m <.> "hsc"
         exists hsc
         let relOutput = toFilePath m <.> "hs"
-        lift $ runCommand (output relOutput)
+        lift $ runCommandOutput relOutput
              $ hsc2hsProg ghc
                       (["-o", relOutput
                        , pathIn hsc
@@ -135,7 +135,7 @@
         let relOutput = toFilePath m <.> "hs"
         -- TODO: mkPackageName doesn't exist in older ones
         alex <- lift $ askBuiltExecutable (mkPackageName "alex") "alex"
-        lift . runCommand (output relOutput)
+        lift . runCommandOutput relOutput
             $ progBinary alex
                      ["-g", "-o", relOutput, pathIn xFile]
                <> input xFile
@@ -144,7 +144,7 @@
         exists chsFile
         let relOutput = toFilePath m <.> "hs"
         c2hs <- lift $ askBuiltExecutable (mkPackageName "c2hs") "c2hs"
-        lift . runCommand (output relOutput)
+        lift . runCommandOutput relOutput
              $ input chsFile
             <> inputs (cIncludeDirs flags)
             <> progBinary c2hs
diff --git a/src/Pier/Build/Package.hs b/src/Pier/Build/Package.hs
--- a/src/Pier/Build/Package.hs
+++ b/src/Pier/Build/Package.hs
@@ -27,15 +27,14 @@
 downloadCabalPackage pkg = do
     let n = display pkg
     askDownload Download
-        { downloadFilePrefix = "hackage"
-        , downloadName = n <.> "tar.gz"
+        { downloadName = n <.> "tar.gz"
         , downloadUrlPrefix = "https://hackage.haskell.org/package/" ++ n
         }
 
 getPackageSourceDir :: PackageIdentifier -> Action Artifact
 getPackageSourceDir pkg = do
     tarball <- downloadCabalPackage pkg
-    runCommand (output outDir)
+    runCommandOutput outDir
         $ message ("Unpacking " ++ display pkg)
         <> prog "tar" ["-xzf", pathIn tarball, "-C", takeDirectory outDir]
         <> input tarball
@@ -50,7 +49,7 @@
     case buildType desc of
         Configure -> do
             let configuredDir = name
-            configuredPackage <- runCommand (output configuredDir)
+            configuredPackage <- runCommandOutput configuredDir
                 $ shadow packageSourceDir configuredDir
                 <> message ("Configuring " ++ name)
                 <> withCwd configuredDir (progTemp (configuredDir </> "configure") [])
diff --git a/src/Pier/Build/Stackage.hs b/src/Pier/Build/Stackage.hs
--- a/src/Pier/Build/Stackage.hs
+++ b/src/Pier/Build/Stackage.hs
@@ -79,8 +79,7 @@
 buildPlanRules :: Rules ()
 buildPlanRules = addPersistent $ \(ReadPlan planName) -> do
         f <- askDownload Download
-                { downloadFilePrefix = "stackage/plan"
-                , downloadName = renderPlanName planName <.> "yaml"
+                { downloadName = renderPlanName planName <.> "yaml"
                 , downloadUrlPrefix = planUrlPrefix planName
                 }
         cs <- readArtifactB f
@@ -152,7 +151,7 @@
 parseGlobalPackagePath ghc f
     | Just f' <- List.stripPrefix "${pkgroot}/" f
         = ghcLibRoot ghc /> f'
-    | otherwise = externalFile f
+    | otherwise = external f
 
 ghcBinDir :: InstalledGhc -> Artifact
 ghcBinDir ghc = ghcLibRoot ghc /> "bin"
@@ -202,7 +201,7 @@
 getSystemGhc version = do
     path <- fmap (head . words) . runCommandStdout
                 $ prog (versionedGhc version) ["--print-libdir"]
-    return $ InstalledGhc (externalFile path) version
+    return $ InstalledGhc (external path) version
 
 data DownloadInfo = DownloadInfo
     { downloadUrl :: String
@@ -250,8 +249,7 @@
     :: Version -> Action InstalledGhc
 downloadAndInstallGHC version = do
     setupYaml <- askDownload Download
-                    { downloadFilePrefix = "stackage/setup"
-                    , downloadName = "stack-setup-2.yaml"
+                    { downloadName = "stack-setup-2.yaml"
                     , downloadUrlPrefix = setupUrl
                     }
     -- TODO: don't re-parse the yaml for every GHC version
@@ -267,8 +265,7 @@
     -- rerunIfCleaned
     let (url, f) = splitFileName $ downloadUrl download
     tar <- askDownload Download
-            { downloadFilePrefix = "stackage/ghc"
-            , downloadName = f
+            { downloadName = f
             , downloadUrlPrefix = url
             }
     -- TODO: check file size and sha1
@@ -324,10 +321,10 @@
     let ghcFixed = "ghc-fixed"
     let db = ghcFixed </> packageConfD
     let ghcPkg = progTemp (ghcFixed </> "bin/ghc-pkg")
-    ghcDir <- runCommand (output ghcFixed)
+    ghcDir <- runCommandOutput ghcFixed
                 $ shadow (ghcLibRoot ghc) ghcFixed
                 <> inputList confs
-                <> message "Making global DB relative"
+                <> message "Building core package database"
                 <> prog "rm" ["-rf", db]
                 <> ghcPkg ["init", db]
                 <> foldMap
