diff --git a/.gitignore b/.gitignore
new file mode 100644
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,1 @@
+dist-newstyle
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,80 @@
+# This file has been generated by `make_travis_yml_2.hs`
+# see https://github.com/hvr/multi-ghc-travis for more information
+language: c
+sudo: false
+
+cache:
+  directories:
+    - $HOME/.cabal/packages
+    - $HOME/.cabal/store
+
+before_cache:
+  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/build-reports.log
+  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/00-index.tar
+
+matrix:
+  include:
+    - env: CABALVER=1.24 GHCVER=7.4.2
+      compiler: ": #GHC 7.4.2"
+      addons: {apt: {packages: [cabal-install-1.24,ghc-7.4.2], sources: [hvr-ghc]}}
+    - env: CABALVER=1.24 GHCVER=7.6.3
+      compiler: ": #GHC 7.6.3"
+      addons: {apt: {packages: [cabal-install-1.24,ghc-7.6.3], sources: [hvr-ghc]}}
+    - env: CABALVER=1.24 GHCVER=7.8.4
+      compiler: ": #GHC 7.8.4"
+      addons: {apt: {packages: [cabal-install-1.24,ghc-7.8.4], sources: [hvr-ghc]}}
+    - env: CABALVER=1.24 GHCVER=7.10.3
+      compiler: ": #GHC 7.10.3"
+      addons: {apt: {packages: [cabal-install-1.24,ghc-7.10.3], sources: [hvr-ghc]}}
+    - env: CABALVER=1.24 GHCVER=8.0.1
+      compiler: ": #GHC 8.0.1"
+      addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.1], sources: [hvr-ghc]}}
+    - env: CABALVER=head GHCVER=head
+      compiler: ": #GHC head"
+      addons: {apt: {packages: [cabal-install-head,ghc-head], sources: [hvr-ghc]}}
+
+  allow_failures:
+    - env: CABALVER=head GHCVER=head
+
+before_install:
+ - unset CC
+ - export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:$PATH
+
+install:
+ - cabal --version
+ - BENCH=${BENCH---enable-benchmarks}
+ - TEST=${TEST---enable-tests}
+ - echo "$(ghc --version) [$(ghc --print-project-git-commit-id 2> /dev/null || echo '?')]"
+ - if [ -f $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz ];
+   then
+     zcat $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz >
+          $HOME/.cabal/packages/hackage.haskell.org/00-index.tar;
+   fi
+ - travis_retry cabal update -v
+ - sed -i 's/^jobs:/-- jobs:/' ${HOME}/.cabal/config
+ - cabal new-build ${TEST} ${BENCH} --dep
+
+# Here starts the actual work to be performed for the package under test;
+# any command which exits with a non-zero exit code causes the build to fail.
+script:
+ - if [ -f configure.ac ]; then autoreconf -i; fi
+ # this builds all libraries and executables (including tests/benchmarks)
+ - cabal new-build ${TEST} ${BENCH} -v2  # -v2 provides useful information for debugging
+
+ # there's no 'cabal new-test' yet, so let's emulate for now
+ - TESTS=( $(awk 'tolower($0) ~ /^test-suite / { print $2 }' *.cabal) );
+   RC=true; for T in ${TESTS[@]}; do echo "== $T ==";
+   if dist-newstyle/build/*/build/$T/$T; then echo "= $T OK =";
+   else echo "= $T FAILED ="; RC=false; fi; done; $RC
+ - cabal sdist # test that a source-distribution can be generated
+
+ # Check that the resulting source distribution can be built w/o and w tests
+ - SRC_BASENAME=$(cabal info . | awk '{print $2;exit}')
+ - tar -C dist/ -xf dist/$SRC_BASENAME.tar.gz
+ - "echo 'packages: *.cabal' > dist/$SRC_BASENAME/cabal.project"
+ - cd dist/$SRC_BASENAME/
+ - cabal new-build --disable-tests --disable-benchmarks
+ - rm -rf ./dist-newstyle
+ - cabal new-build ${TEST} ${BENCH}
+
+# EOF
diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,26 @@
+# Revision history for monad-ste
+
+## 0.1.0.0  -- 2016-05-03
+
+* First hackage release
+
+* Added support for GHC 7.4 through 7.8 along with preexisting support for
+7.10 and 8.0
+
+* Added MonadFix instance
+
+* Moved the definitions and unsafe code to .STE.Internal and marked the
+  .STE module which only provides safe exports as Trustworthy
+
+* Added a number of unsafe helper functions such as `unsafeInterleaveSTE`
+to the Internal module, as well as exposing
+
+## pre 0.1.0.0
+
+* Thanks to Duncan Coutts for design feedback that using the
+raw `raiseIO#` and `catch#` primitives would simplify the core code
+
+* Thanks to Brian Schroeder and Joel Burget for helping debug and improve
+the code.
+
+* Originally a module in the Hopper project.
diff --git a/Hlint.hs b/Hlint.hs
new file mode 100644
--- /dev/null
+++ b/Hlint.hs
@@ -0,0 +1,10 @@
+import "hint" HLint.HLint
+
+ignore "Reduce duplication"
+ignore "Redundant lambda"
+ignore "Use >=>"
+ignore "Use const"
+ignore "Avoid lambda"
+ignore "Redundant flip"
+ignore "Use let"
+ignore "Redundant $"
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,26 @@
+Copyright (c) 2016, Carter Tazio Schonwald
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the
+   distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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/cabal.project b/cabal.project
new file mode 100644
--- /dev/null
+++ b/cabal.project
@@ -0,0 +1,1 @@
+packages: monad-ste.cabal
diff --git a/monad-ste.cabal b/monad-ste.cabal
new file mode 100644
--- /dev/null
+++ b/monad-ste.cabal
@@ -0,0 +1,98 @@
+-- Initial monad-ste.cabal generated by cabal init.  For further
+-- documentation, see http://haskell.org/cabal/users-guide/
+
+-- The name of the package.
+name:                monad-ste
+
+-- The package version.  See the Haskell package versioning policy (PVP)
+-- for standards guiding when and how versions should be incremented.
+-- https://wiki.haskell.org/Package_versioning_policy
+-- PVP summary:      +-+------- breaking API changes
+--                   | | +----- non-breaking API additions
+--                   | | | +--- code changes with no API change
+version:             0.1.0.0
+
+-- A short (one-line) description of the package.
+synopsis:            ST monad with efficient explicit errors
+
+-- A longer description of the package.
+description: STE is a sibling to the ST monad that provides more efficient
+  abortive errors than a standard EitherT or ExceptT monad stack.
+
+-- URL for the project homepage or repository.
+homepage:            http://github.com/cartazio/monad-ste
+
+-- The license under which the package is released.
+license:             BSD2
+
+-- The file containing the license text.
+license-file:        LICENSE
+
+-- The package author(s).
+author:              Carter Tazio Schonwald
+
+-- An email address to which users can send suggestions, bug reports, and
+-- patches.
+maintainer:          carter at wellposed dot com
+
+-- A copyright notice.
+-- copyright:
+
+category:            Control
+
+tested-with:  GHC==8.0.1,  GHC==8.1.* , GHC==7.10.3, GHC == 7.4.2, GHC == 7.6.3, GHC == 7.8.4
+
+build-type:          Simple
+
+-- Extra files to be distributed with the package, such as examples or a
+-- README.
+extra-source-files:  ChangeLog.md
+                    .travis.yml
+                    .gitignore
+                    Hlint.hs
+                    readme.md
+                    cabal.project
+
+-- Constraint on the version of Cabal needed to build this package.
+cabal-version:       >=1.10
+
+source-repository head
+  type:     git
+  location: https://github.com/cartazio/monad-ste
+
+library
+  -- Modules exported by the library.
+  exposed-modules:      Control.Monad.STE
+                        Control.Monad.STE.Internal
+
+  ghc-options: -O2
+  -- Modules included in this library but not exported.
+  -- other-modules:
+
+  -- LANGUAGE extensions used by modules in this package.
+  -- other-extensions:
+
+  -- Other library packages from which modules are imported.
+  build-depends:      base >=4.3 && < 5
+                      ,primitive >= 0.6 && < 0.7
+                      ,exceptions >= 0.8 && < 0.9
+                      ,ghc-prim
+
+
+  -- Directories containing source files.
+  hs-source-dirs:      src
+
+  -- Base language which the package is written in.
+  default-language:    Haskell2010
+
+test-suite hspec
+  type: exitcode-stdio-1.0
+  main-is: Hspec.hs
+  ghc-options: -Wall  -O2
+  hs-source-dirs: tests
+  default-language: Haskell2010
+  build-depends:
+      base
+      ,hspec >= 2.1 && < 2.3
+      ,HUnit
+      ,monad-ste
diff --git a/readme.md b/readme.md
new file mode 100644
--- /dev/null
+++ b/readme.md
@@ -0,0 +1,5 @@
+[![Build Status](https://travis-ci.org/cartazio/monad-ste.svg?branch=master)](https://travis-ci.org/cartazio/monad-ste)
+
+# STE Monad
+an ST monad sibling with efficient typed aborting exceptions that can only be
+handled at the `runSTE`/`handleSTE` toplevel runner.
diff --git a/src/Control/Monad/STE.hs b/src/Control/Monad/STE.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/STE.hs
@@ -0,0 +1,11 @@
+{-#  LANGUAGE Trustworthy #-}
+module Control.Monad.STE
+(
+  STE
+  ,runSTE
+  ,throwSTE
+  ,handleSTE
+  )
+
+  where
+import Control.Monad.STE.Internal
diff --git a/src/Control/Monad/STE/Internal.hs b/src/Control/Monad/STE/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/STE/Internal.hs
@@ -0,0 +1,223 @@
+{-# LANGUAGE MagicHash, UnboxedTuples, RankNTypes #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE Unsafe #-}
+module Control.Monad.STE.Internal
+(
+  STE(..)
+  ,unSTE
+  ,STERep
+  ,STEret(..)
+  ,runSTE
+  ,throwSTE
+  ,handleSTE
+  ----
+  ,unsafeInterleaveSTE
+  ,liftSTE
+  ,fixSTE
+  ,runBasicSTE
+  ,RealWorld
+  ,unsafeIOToSTE
+  ,unsafeSTEToIO
+  )
+
+  where
+
+#if MIN_VERSION_ghc_prim(0,5,0)
+import GHC.Prim (State#, raiseIO#, catch#)
+#else
+import GHC.Prim (State#, raiseIO#, catch#, realWorld#)
+#endif
+
+import qualified Control.Monad.Catch as CMC
+import Control.Exception as Except
+import Control.Monad (ap)
+import qualified Control.Monad.Fix as MF
+import Control.Monad.Primitive
+import Data.Typeable
+import Unsafe.Coerce (unsafeCoerce)
+import GHC.IO(IO(..))
+
+#if !MIN_VERSION_base(4,8,0)
+import Control.Applicative
+#endif
+
+#if MIN_VERSION_ghc_prim(0,5,0)
+import GHC.Magic(runRW#)
+#endif
+
+
+newtype STE e s a = STE  (STERep s a)
+
+unSTE :: STE e s a -> STERep s a
+unSTE = \(STE a) ->  a
+
+type STERep s a = State# s -> (# State# s, a #)
+
+data STEret s a = STEret (State# s) a
+
+-- liftSTE and STEret is useful when we want a lifted result from an STE computation.  See
+-- fixSTE below.
+liftSTE :: STE e s a -> State# s -> STEret s a
+liftSTE (STE m) = \s -> case m s of (# s', r #) -> STEret s' r
+
+{-# NOINLINE unsafeInterleaveSTE #-}
+unsafeInterleaveSTE :: STE e s a -> STE e s a
+unsafeInterleaveSTE (STE m) = STE ( \ s ->
+    let
+        r = case m s of (# _, res #) -> res
+    in
+    (# s, r #)
+  )
+
+-- | Allow the result of a state transformer computation to be used (lazily)
+-- inside the computation.
+-- Note that if @f@ is strict, @'fixSTE' f = _|_@.
+fixSTE :: (a -> STE e s a) -> STE e s a
+fixSTE k = STE $ \ s ->
+    let ans       = liftSTE (k r) s
+        STEret _ r = ans
+    in
+    case ans of STEret s' x -> (# s', x #)
+
+
+instance Functor (STE e s) where
+    fmap f (STE m) = STE $ \ s ->
+      case (m s) of { (# new_s, r #) ->
+      (# new_s, f r #) }
+
+instance Applicative (STE e s) where
+    {-# INLINE pure  #-}
+    {-# INLINE (<*>) #-}
+    {-# INLINE (*> ) #-}
+    pure = return
+    (*>) = \ m k ->  m >>= \ _ -> k
+    (<*>) = ap
+
+instance Monad (STE e s) where
+    {-# INLINE return #-}
+    {-# INLINE (>>)   #-}
+    {-# INLINE (>>=)  #-}
+    return x = STE (\ s -> (# s, x #))
+    m >> k   = m >>= \ _ -> k
+    (STE m) >>= k
+      = STE (\ s ->
+        case (m s) of { (# new_s, r #) ->
+        case (k r) of { STE k2 ->
+        (k2 new_s) }})
+
+instance MF.MonadFix (STE e s) where
+  mfix = fixSTE
+
+instance PrimMonad (STE e s) where
+  type PrimState (STE e s) = s
+  primitive = \ m ->  STE m
+  {-# INLINE primitive #-}
+instance PrimBase (STE e s) where
+  internal (STE p) = \ s# -> case p s# of
+                          (# a , b #) -> (# a , b #)
+  {-# INLINE internal #-}
+
+-- this isn't terribly useful, but it is the only valid instance STE can have for
+-- MonadThrow and be well behaved, though this may be replaced with
+-- an
+instance (Except.SomeException ~ err) =>  CMC.MonadThrow (STE err s) where
+  throwM x = throwSTE  $ toException x
+
+
+{-# INLINE runSTE #-} -- this may not be needed and may make code closer when its a small STE computation (though we're using it for small stuff )
+-- | 'runSTE' is the workhorse of the STE monad. Runs an STE computation, and
+-- also does the toplevel handling of the abortive throwSTE operator.
+-- The naive way to handle errors is to simply write @'handleSTE' 'id' md@.
+-- 'runSTE' does not and cannot (by design) handle pure or async exceptions.
+runSTE ::  (forall s. STE e s a) -> (Either e a  -> b) -> b
+runSTE = \ st  f -> f  $
+            runBasicSTE (privateCatchSTE st)
+
+{-# INLINE handleSTE #-}
+-- | 'handleSTE' is a flipped convenience function version of 'runSTE'
+handleSTE :: (Either e a -> b) -> (forall s. STE e s a)  -> b
+handleSTE f st = runSTE st f
+
+-- |  'throwSTE' is the 'STE' sibling of 'throwIO', and its argument
+-- must match the @e@ parameter in @'STE' e s a@. There is also no Exception e
+-- constraint.
+-- `throwSTE` should be thought of as an "abort" operation which is guaranteed to be
+-- caught/handled by runSTE.
+throwSTE :: forall e s a .  e -> STE e s a
+throwSTE err = unsafeIOToSTE  $
+    IO (raiseIO# (toException $ STException $ ( Box $ unsafeCoerce err)))
+
+-- | privateCatchSTE is NOT exported
+-- we copy the machinery from
+-- catchException so that pure errors aren't mishandled by
+-- the catchSTE machinery when handling STE errors
+privateCatchSTE:: forall e s b . STE e s b  -> STE e s (Either e b)
+privateCatchSTE = \ steAct  ->
+      unsafeIOToSTE $
+        IO  (catch# (unsafeCoerce $ unSTE $ fmap Right steAct) handler')
+  where
+    --- need to handle pure exceptions too!
+    handler' :: SomeException -> STERep RealWorld (Either e b)
+    handler' e = case (fromException e) of
+        Just (STException (Box val)) -> \ s -> (# s , Left $ unsafeCoerce val #)
+        Nothing -> raiseIO# e
+
+{-
+catchAny :: IO a -> (forall e . Exception e => e -> IO a) -> IO a
+catchAny (IO io) handler = IO $ catch# io handler'
+    where handler' (SomeException e) = unIO (handler e)
+
+catchException :: Exception e => IO a -> (e -> IO a) -> IO a
+catchException (IO io) handler = IO $ catch# io handler'
+    where handler' e = case fromException e of
+                       Just e' -> unIO (handler e')
+                       Nothing -> raiseIO# e
+
+
+see https://phabricator.haskell.org/D1973 and
+https://ghc.haskell.org/trac/ghc/ticket/11555
+for information on tradeoffs in strictness
+
+-}
+
+
+unsafeIOToSTE        :: IO a -> STE e s a
+unsafeIOToSTE (IO io) = STE $ \ s -> (unsafeCoerce io) s
+
+unsafeSTEToIO :: STE e s a -> IO a
+unsafeSTEToIO (STE m) = IO (unsafeCoerce m)
+
+
+--- this results in WAY better perf when available
+#if MIN_VERSION_ghc_prim(0,5,0)
+runBasicSTE :: (forall s. STE e s a) -> a
+runBasicSTE (STE st_rep) = case runRW# st_rep of (# _, a #) -> a
+{-# INLINE runBasicSTE #-}
+#else
+runBasicSTE :: (forall s. STE e s a) -> a
+runBasicSTE st = runSTERep (case st of { STE st_rep -> st_rep })
+{-# INLINE runBasicSTE #-}
+
+runSTERep :: (forall s. STERep  s a) -> a
+runSTERep st_rep = case st_rep realWorld# of
+                        (# _, r #) -> r
+{-# NOINLINE runSTERep #-}
+#endif
+
+
+#if MIN_VERSION_base(4,8,0)
+data Box a = Box {-# NOUNPACK #-} a
+#else
+data Box a = Box  a
+#endif
+
+-- | STException
+data STException = STException  (Box ())
+  deriving Typeable
+instance Show (STException ) where
+  show (STException _) = "STException(..)! did you use the Unsafe/internal STE interface?"
+instance Exception (STException)
diff --git a/tests/Hspec.hs b/tests/Hspec.hs
new file mode 100644
--- /dev/null
+++ b/tests/Hspec.hs
@@ -0,0 +1,14 @@
+module Main where
+import Test.Hspec
+--import Control.Exception
+import Control.Monad.STE
+
+main ::  IO ()
+main = hspec  spec
+
+spec :: Spec
+spec = describe "STE Spec " $ do
+  it "catches errors" $
+    Left "some error" == handleSTE id (do  _ <- throwSTE "some error"; return (1 :: Int ))
+  it "returns stuff" $
+    (1 :: Int) == (either (error "fail") id $ handleSTE id (return (1 :: Int )))
