diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -2,6 +2,7 @@
 
 [![](https://img.shields.io/hackage/v/shh.svg?colorB=%23999&label=shh)](http://hackage.haskell.org/package/shh)
 [![](https://img.shields.io/hackage/v/shh-extras.svg?colorB=%23999&label=shh-extras)](http://hackage.haskell.org/package/shh-extras)
+[![](https://builds.sr.ht/~lukec/shh/nix.yml.svg)](https://builds.sr.ht/~lukec/shh/nix.yml?)
 [![](https://travis-ci.org/luke-clifton/shh.svg?branch=master)](https://travis-ci.org/luke-clifton/shh)
 
 Shh is a library to enable convinient shell-like programming in Haskell.
diff --git a/shh.cabal b/shh.cabal
--- a/shh.cabal
+++ b/shh.cabal
@@ -1,5 +1,5 @@
 name:                shh
-version:             0.2.0.5
+version:             0.2.0.6
 synopsis:            Simple shell scripting from Haskell
 description:         Provides a shell scripting environment for Haskell. It
                      helps you all external binaries, and allows you to
diff --git a/src/Shh.hs b/src/Shh.hs
--- a/src/Shh.hs
+++ b/src/Shh.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE GADTs #-}
 -- | Shh provides a shell-like environment for Haskell.
 module Shh
     ( initInteractive
@@ -59,6 +61,8 @@
     , loadAnnotatedEnv
     , loadExe
     , loadExeAs
+    -- | = Builtins
+    , cd
     ) where
 
 import Shh.Internal
diff --git a/src/Shh/Internal.hs b/src/Shh/Internal.hs
--- a/src/Shh/Internal.hs
+++ b/src/Shh/Internal.hs
@@ -25,7 +25,7 @@
 import Data.Maybe (mapMaybe, isJust)
 import Language.Haskell.TH
 import qualified System.Directory as Dir
-import System.Environment (getEnv)
+import System.Environment (getEnv, setEnv)
 import System.Exit (ExitCode(..))
 import System.IO
 import System.Posix.Signals
@@ -449,8 +449,12 @@
 -- are ignored. It also creates the IO action @missingExecutables@ which will
 -- do a runtime check to ensure all the executables that were found at
 -- compile time still exist.
+--
+-- Note: If an executable named @cd@ is discovered, this will load it as @cd'@
 loadEnv :: ExecReference -> Q [Dec]
-loadEnv ref = loadAnnotatedEnv ref id
+loadEnv ref = loadAnnotatedEnv ref $ \case
+    "cd" -> "cd'"
+    x    -> x
 
 -- | Test to see if an executable can be found either on the $PATH or absolute.
 checkExecutable :: FilePath -> IO Bool
@@ -511,3 +515,21 @@
 -- | Like `readProc`, but attempts to `Prelude.read` the result.
 readAuto :: Read a => Proc () -> IO a
 readAuto p = read <$> readProc p
+
+-- | Mimics the shell builtin "cd".
+cd' :: FilePath -> IO ()
+cd' p = do
+    Dir.setCurrentDirectory p
+    a <- Dir.getCurrentDirectory
+    setEnv "PWD" a
+
+-- | Helper class for variable number of arguments to @cd@ builtin.
+class Cd a where
+    -- | Mimics the shell builtin "cd"
+    cd :: a
+
+instance (io ~ IO ()) => Cd io where
+    cd = getEnv "HOME" >>= cd'
+
+instance {-# OVERLAPS #-} (io ~ IO (), path ~ FilePath) => Cd (path -> io) where
+    cd = cd'
