diff --git a/ats-pkg.cabal b/ats-pkg.cabal
--- a/ats-pkg.cabal
+++ b/ats-pkg.cabal
@@ -1,5 +1,5 @@
 name:                ats-pkg
-version:             2.2.0.0
+version:             2.2.0.1
 synopsis:            Package manager for ATS
 description:         A collection of scripts to make building ATS projects easy.
 homepage:            https://github.com/vmchale/atspkg#readme
@@ -36,6 +36,7 @@
                      , Language.ATS.Package.Dependency
                      , Language.ATS.Package.Compiler
                      , Language.ATS.Package.Build
+                     , Language.ATS.Package.Upgrade
   build-depends:       base >= 4.7 && < 5
                      , http-client
                      , filemanip
diff --git a/src/Language/ATS/Package/Build.hs b/src/Language/ATS/Package/Build.hs
--- a/src/Language/ATS/Package/Build.hs
+++ b/src/Language/ATS/Package/Build.hs
@@ -1,6 +1,8 @@
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE TupleSections     #-}
 
+-- | This module holds various functions for turning a package into a set of rules
+-- or an 'IO ()'.
 module Language.ATS.Package.Build ( mkPkg
                                   , pkgToAction
                                   , build
@@ -53,13 +55,12 @@
 
 -- TODO clean generated ATS
 mkClean :: Rules ()
-mkClean =
-    "clean" ~> do
-        cleanHaskell
-        removeFilesAfter "." ["//*.1", "//*.c", "tags"]
-        removeFilesAfter "target" ["//*"]
-        removeFilesAfter ".atspkg" ["//*"]
-        removeFilesAfter "ats-deps" ["//*"]
+mkClean = "clean" ~> do
+    cleanHaskell
+    removeFilesAfter "." ["//*.1", "//*.c", "tags"]
+    removeFilesAfter "target" ["//*"]
+    removeFilesAfter ".atspkg" ["//*"]
+    removeFilesAfter "ats-deps" ["//*"]
 
 mkInstall :: Rules ()
 mkInstall =
diff --git a/src/Language/ATS/Package/Compiler.hs b/src/Language/ATS/Package/Compiler.hs
--- a/src/Language/ATS/Package/Compiler.hs
+++ b/src/Language/ATS/Package/Compiler.hs
@@ -6,7 +6,6 @@
     , cleanAll
     , fetchCompiler
     , setupCompiler
-    , Version (..)
     ) where
 
 import qualified Codec.Archive.Tar         as Tar
@@ -21,6 +20,9 @@
 import           System.FilePath.Find      (find)
 import           System.Posix.Files
 import           System.Process
+
+-- HOPEFULLY only linux or darwin?
+-- isDigit
 
 -- request to https://github.com/vmchale/atspkg/releases/latest/ for latest
 -- version, then we can upgrade this tool as well.
diff --git a/src/Language/ATS/Package/Exec.hs b/src/Language/ATS/Package/Exec.hs
--- a/src/Language/ATS/Package/Exec.hs
+++ b/src/Language/ATS/Package/Exec.hs
@@ -15,6 +15,7 @@
 import           Language.ATS.Package.Build
 import           Language.ATS.Package.Compiler
 import           Language.ATS.Package.Dependency
+import           Language.ATS.Package.Upgrade
 import           Options.Applicative             hiding (auto)
 import           Paths_ats_pkg
 import           System.Directory
@@ -39,6 +40,7 @@
              | Test
              | Fetch { _url :: String }
              | Nuke
+             | Upgrade
 
 command' :: Parser Command
 command' = hsubparser
@@ -48,6 +50,7 @@
     <> command "build" (info build' (progDesc "Build current package targets"))
     <> command "test" (info (pure Test) (progDesc "Test current package"))
     <> command "nuke" (info (pure Nuke) (progDesc "Uninstall all globally installed libraries"))
+    <> command "upgrade" (info (pure Upgrade) (progDesc "Upgrade to the latest version of atspkg"))
     )
 
 build' :: Parser Command
@@ -95,6 +98,7 @@
     =<< check Nothing
 
 run :: Command -> IO ()
+run Upgrade = upgradeAtsPkg
 run Nuke = cleanAll
 run (Fetch u) = fetchPkg u
 run Clean = mkPkg False False mempty ["clean"] Nothing
diff --git a/src/Language/ATS/Package/Upgrade.hs b/src/Language/ATS/Package/Upgrade.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/ATS/Package/Upgrade.hs
@@ -0,0 +1,32 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Language.ATS.Package.Upgrade ( upgradeAtsPkg
+                                    ) where
+
+import qualified Data.ByteString.Lazy.Char8 as BSL
+import           Data.Char                  (isDigit)
+import           Data.List                  (intersperse)
+import           Data.Semigroup
+import           Network.HTTP.Client
+import           Network.HTTP.Client.TLS    (tlsManagerSettings)
+import           System.Info
+
+manufacturer :: String
+manufacturer = case os of
+    "darwin" -> "apple"
+    _        -> "unknown"
+
+targetArch :: String
+targetArch = mconcat . intersperse "-" $ [arch, manufacturer, os]
+
+upgradeAtsPkg :: IO ()
+upgradeAtsPkg = do
+    manager <- newManager tlsManagerSettings
+    initialRequest <- parseRequest "https://github.com/vmchale/atspkg/releases/latest"
+    response <- responseBody <$> httpLbs (initialRequest { method = "GET", redirectCount = 0 }) manager
+    let strVersion = BSL.takeWhile (/='"') . BSL.dropWhile (not . isDigit) . BSL.dropWhile (/='"') $ response
+        binRequest = "https://github.com/vmchale/atspkg/releases/download/" <> BSL.unpack strVersion <> "/atspkg-" <> targetArch
+    putStrLn binRequest
+    followupRequest <- parseRequest binRequest
+    binBytes <- responseBody <$> httpLbs (followupRequest { method = "GET" }) manager
+    BSL.writeFile "atspkg" binBytes
diff --git a/stack.yaml b/stack.yaml
--- a/stack.yaml
+++ b/stack.yaml
@@ -3,8 +3,8 @@
 packages:
   - '.'
 extra-deps:
-  - shake-ext-2.1.0.2
-  - shake-ats-1.2.0.0
+  - shake-ext-2.3.0.0
+  - shake-ats-1.3.0.0
   - composition-prelude-1.1.0.2
   - language-ats-0.1.1.18
   - cli-setup-0.2.0.1
