diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017 Tom Sydney Kerckhove
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,3 @@
+import Distribution.Simple
+
+main = defaultMain
diff --git a/src/Zifter/Stack.hs b/src/Zifter/Stack.hs
new file mode 100644
--- /dev/null
+++ b/src/Zifter/Stack.hs
@@ -0,0 +1,86 @@
+module Zifter.Stack where
+
+import Control.Monad
+import Control.Monad.IO.Class
+import Path
+import Path.IO
+import System.Exit (ExitCode(..))
+import System.IO
+import System.Process
+
+import Distribution.Package
+import Distribution.PackageDescription
+import Distribution.PackageDescription.Configuration
+import Distribution.PackageDescription.Parse
+import Distribution.Verbosity
+
+import Zifter.Zift
+
+stackBuildZift :: Zift ()
+stackBuildZift = do
+    () <- stackCheckAndPrintVersion
+    stackBuild
+
+stackCheckAndPrintVersion :: Zift ()
+stackCheckAndPrintVersion = do
+    let cmd = "stack --version"
+    (_, mouth, _, ph) <-
+        liftIO $ createProcess ((shell cmd) {std_out = CreatePipe})
+    ec <- liftIO $ waitForProcess ph
+    case mouth of
+        Nothing -> pure ()
+        Just outh -> liftIO (hGetContents outh) >>= printZift
+    case ec of
+        ExitFailure c -> fail $ unwords [cmd, "failed with exit code", show c]
+        ExitSuccess -> pure ()
+
+stackGetPackageTargetTuples :: Zift [(String, [String])]
+stackGetPackageTargetTuples = do
+    rd <- getRootDir
+    (_, fs) <- liftIO $ listDirRecur rd
+    let cabalFiles = filter ((== ".cabal") . fileExtension) fs
+    (concat <$>) $
+        forM cabalFiles $ \cabalFile -> do
+            pd <-
+                liftIO $ readPackageDescription deafening $ toFilePath cabalFile
+            let packageDesc = flattenPackageDescription pd
+                name = unPackageName $ pkgName $ package packageDesc
+                libname = name ++ ":lib"
+                lib =
+                    case library packageDesc of
+                        Nothing -> []
+                        Just _ -> [libname]
+                testnames =
+                    map (((name ++ ":test:") ++) . testName) $
+                    testSuites packageDesc
+            pure [(name, lib ++ testnames)]
+
+stackBuild :: Zift ()
+stackBuild = do
+    rd <- getRootDir
+    tups <- stackGetPackageTargetTuples
+    forM_ tups $ \(package_, targets) -> do
+        let cleanCmd = "stack clean " ++ package_
+        cec <-
+            liftIO $ do
+                (_, _, _, ph) <-
+                    createProcess
+                        ((shell cleanCmd) {cwd = Just $ toFilePath rd})
+                waitForProcess ph
+        case cec of
+            ExitFailure c ->
+                fail $ unwords [cleanCmd, "failed with exit code", show c]
+            ExitSuccess -> pure ()
+        forM_ targets $ \target -> do
+            let buildCmd = "stack build --pedantic --haddock --test " ++ target
+            bec <-
+                liftIO $ do
+                    (_, _, _, bph) <-
+                        createProcess
+                            ((shell buildCmd) {cwd = Just $ toFilePath rd})
+                    waitForProcess bph
+            case bec of
+                ExitFailure c ->
+                    fail $ unwords [buildCmd, "failed with exit code", show c]
+                ExitSuccess ->
+                    printPreprocessingDone $ unwords [buildCmd, "succeeded."]
diff --git a/zifter-stack.cabal b/zifter-stack.cabal
new file mode 100644
--- /dev/null
+++ b/zifter-stack.cabal
@@ -0,0 +1,30 @@
+name: zifter-stack
+synopsis: zifter-stack
+description: zifter-stack
+version: 0.0.0.0
+cabal-version: >=1.10
+build-type: Simple
+license: MIT
+license-file: LICENSE
+copyright: Copyright: (c) 2017 Tom Sydney Kerckhove
+maintainer: syd.kerckhove@gmail.com
+homepage: http://cs-syd.eu
+category: Zift
+author: Tom Sydney Kerckhove
+
+library
+    exposed-modules:
+        Zifter.Stack
+    build-depends:
+        base >=4.9 && <=5,
+        process -any,
+        filepath >=1.4 && <1.5,
+        directory -any,
+        zifter >=0.0 && <0.1,
+        path >=0.5 && <0.6,
+        path-io >=1.2 && <1.3,
+        Cabal >=1.24 && <1.25
+    default-language: Haskell2010
+    hs-source-dirs: src/
+    ghc-options: -Wall
+
