diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2015 Pedro Tacla Yamada
+
+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/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,16 @@
+# stack-run
+[![Build Status](https://travis-ci.org/yamadapc/stack-run.svg?branch=master)](https://travis-ci.org/yamadapc/stack-run)
+- - -
+Like `cabal run` but for `stack`.
+
+## Usage
+
+```
+$ stack run
+```
+
+## Demo
+![](/demo.gif)
+
+## License
+This code is published under the MIT license.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/src/Main.hs b/src/Main.hs
new file mode 100644
--- /dev/null
+++ b/src/Main.hs
@@ -0,0 +1,118 @@
+module Main
+  where
+
+import           Control.Applicative                   ((<$>))
+import           Control.Monad                         (unless)
+import qualified Data.ByteString.Char8                 as ByteString
+import           Data.Conduit
+import qualified Data.Conduit.Binary                   as Conduit.Binary
+import qualified Data.Conduit.List                     as Conduit.List
+import           Data.Conduit.Process
+import           Data.List
+import           Data.List.Utils
+import           Data.Maybe
+import           Distribution.PackageDescription
+import           Distribution.PackageDescription.Parse
+import           System.Console.ANSI
+import           System.Directory
+import           System.Directory.ProjectRoot
+import           System.Environment
+import           System.Exit
+import           System.FilePath
+import           System.IO
+
+usage :: String
+usage = unlines [ ""
+                , "  Usage: stack run [name]"
+                , ""
+                , "  Commands:"
+                , ""
+                , "    stack run [name]             Compiles and runs the executable specified or the default"
+                , "    stack run set-default <name> Sets the default executable to run"
+                , "    stack run -- <name>          Like stack run, but will never match a sub-command"
+                , ""
+                ]
+
+setDefault :: String -> IO ()
+setDefault name = do
+    pr <- fromMaybe (error "No project root found") <$>
+        getProjectRootCurrent
+    writeFile (pr </> ".stack-work" </> ".stack-run-default") name
+
+findDefault :: IO String
+findDefault = do
+    pr <- fromMaybe (error "No project root found") <$>
+        getProjectRootCurrent
+    e <- doesFileExist (pr </> ".stack-work" </> ".stack-run-default")
+    if e then readFile (pr </> ".stack-work" </> ".stack-run-default")
+         else findDefault' pr
+  where
+    findDefault' pr = do
+        cfp <- fromMaybe (error "No cabal file found") <$>
+            (find ((== ".cabal") . takeExtension) <$> getDirectoryContents pr)
+        getPackageDescription cfp >>= getDefaultExecutable
+          where
+            getPackageDescription p = parsePackageDescription <$> readFile p
+            getDefaultExecutable (ParseFailed _) =
+                error "Failed to parse cabal file"
+            getDefaultExecutable (ParseOk _ gpd) = case condExecutables gpd of
+                [] -> error "No executable found"
+                ((d, _):_) -> return d
+
+stackRun :: String -> [String] -> IO b
+stackRun name as = do
+    pr <- fromMaybe (error "No project root found") <$> getProjectRootCurrent
+    stackYmlExists <- doesFileExist (pr </> "stack.yaml")
+    unless stackYmlExists $ do
+        ec <- prettyRunCommand "stack init"
+        case ec of
+            ExitSuccess -> return ()
+            f -> exitWith f
+    ec <- prettyRunCommand "stack build"
+    case ec of
+        ExitSuccess ->
+            setSGR [Reset] >>
+            hFlush stdout >>
+            runCommand ("stack exec " ++ name ++ " -- " ++ join " " as) >>=
+            waitForProcess >>=
+            exitWith
+        f -> exitWith f
+
+prettyRunCommand :: String -> IO ExitCode
+prettyRunCommand cmd = do
+    setSGR [ SetColor Foreground Vivid White
+           , SetConsoleIntensity BoldIntensity
+           ]
+    putStr "$ "
+    setSGR [Reset]
+    setSGR [SetColor Foreground Vivid Cyan]
+    putStrLn cmd
+    setSGR [Reset]
+    (Inherited, out, err, cph) <- streamingProcess (shell cmd)
+    out =$= Conduit.Binary.lines $$ Conduit.List.mapM_ putLineGray
+    err =$= Conduit.Binary.lines $$ Conduit.List.mapM_ putLineRed
+    waitForStreamingProcess cph
+  where
+    putLineSGR sgr b = do
+        setSGR sgr
+        putStr "  "
+        ByteString.putStrLn b
+        setSGR [Reset]
+    putLineGray = putLineSGR [SetColor Foreground Dull White]
+    putLineRed = putLineSGR [SetColor Foreground Vivid Black]
+
+main :: IO ()
+main = do
+    args <- getArgs
+    case args of
+        ("set-default":name:_) -> setDefault name
+        ("set-default":_) -> do
+            hPutStrLn stderr "Missing required parameter: <name>"
+            exitFailure
+        ("get-default":_) -> putStrLn =<< findDefault
+        ("help":_) -> do
+            putStrLn usage
+            exitSuccess
+        ("--":name:as) -> stackRun name as
+        (name:as) -> stackRun name as
+        [] -> flip stackRun [] =<< findDefault
diff --git a/stack-run.cabal b/stack-run.cabal
new file mode 100644
--- /dev/null
+++ b/stack-run.cabal
@@ -0,0 +1,38 @@
+name:                stack-run
+version:             0.1.0.0
+synopsis:            An equivalent to cabal run for stack.
+description:         Finds the project root, compiles your code and runs the
+                     first or set default executable. It's a shorthand for
+                     @stack build && stack run executable@, much like
+                     @cabal run@.
+homepage:            https://github.com/yamadapc/stack-run
+license:             MIT
+license-file:        LICENSE
+author:              Pedro Tacla Yamada
+maintainer:          tacla.yamada@gmail.com
+copyright:           Copyright (c) 2015 Pedro Tacla Yamada
+category:            Development
+build-type:          Simple
+extra-source-files:  README.md
+cabal-version:       >=1.10
+
+tested-with: GHC >= 7.6
+
+executable stack-run
+  main-is:             Main.hs
+  build-depends:       Cabal
+                     , MissingH
+                     , ansi-terminal >= 0.6.2.3
+                     , base >=4 && <5
+                     , bytestring >= 0.10.6.0
+                     , conduit
+                     , conduit-extra
+                     , directory
+                     , filepath
+                     , projectroot >= 0.2
+  hs-source-dirs:      src
+  default-language:    Haskell2010
+
+source-repository head
+  type:     git
+  location: git://github.com/yamadapc/stack-run.git
