diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,31 @@
+Copyright (c) 2009, Henning Thielemann
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * 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.
+
+    * The names of contributors may not be used to endorse or promote
+      products derived from this software without specific prior
+      written permission.
+
+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.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,3 @@
+#! /usr/bin/env runhaskell
+> import Distribution.Simple
+> main = defaultMain
diff --git a/src/Control/Monad/ST.hs b/src/Control/Monad/ST.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/ST.hs
@@ -0,0 +1,3 @@
+module Control.Monad.ST (module Control.Monad.ST.Strict) where
+
+import Control.Monad.ST.Strict
diff --git a/src/Control/Monad/ST/Lazy.hs b/src/Control/Monad/ST/Lazy.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/ST/Lazy.hs
@@ -0,0 +1,113 @@
+{-# LANGUAGE Rank2Types #-}
+module Control.Monad.ST.Lazy (
+   ST, runST, fixST,
+
+   RealWorld, stToIO,
+
+   strictToLazyST, lazyToStrictST,
+
+   unsafeInterleaveST,
+   unsafeIOToST
+   ) where
+
+
+import qualified Control.Monad.ST.Strict as Strict
+import Control.Monad.Trans.State (StateT(StateT), mapStateT, evalStateT, )
+import Control.Monad.Trans (lift, )
+import Control.Monad.Fix (MonadFix, mfix, )
+import Control.Applicative (Applicative(pure, (<*>)), )
+import System.IO.Unsafe (unsafePerformIO, unsafeInterleaveIO, )
+
+
+
+-- * The 'ST' Monad
+
+{- |
+The lazy state thread monad provides a weak form of sequencing:
+If action A is written before B, then A will be run before B.
+Generally an action is run whenever its result is needed
+or when a subsequent action must be run.
+
+This sequencing is necessary,
+in order to run 'writeSTRef' actions at all
+and run them in the right order and interleaving with 'readSTRef'.
+
+I used the same idea in the @lazyio@ package.
+-}
+newtype ST s a = ST {unST :: StateT (State s) IO a}
+
+data State s = State
+
+
+instance Functor (ST s) where
+   fmap f (ST st) = ST (fmap f st)
+
+instance Applicative (ST s) where
+   pure f = ST (pure f)
+   ST f <*> ST x = ST $
+      mapStateT unsafeInterleaveIO f <*>
+      mapStateT unsafeInterleaveIO x
+
+instance Monad (ST s) where
+   return f = ST (return f)
+   fail str = ST (fail str)
+   ST x >> ST y = ST $
+      mapStateT unsafeInterleaveIO x >>
+      mapStateT unsafeInterleaveIO y
+   ST x >>= k = ST $
+      mapStateT unsafeInterleaveIO . unST . k =<<
+      mapStateT unsafeInterleaveIO x
+
+
+runST :: (forall s. ST s a) -> a
+runST st = unsafePerformIO (evalStateT (unST st) State)
+
+fixST :: (a -> ST s a) -> ST s a
+fixST f = ST (mfix (unST . f))
+
+instance MonadFix (ST s) where
+   mfix = fixST
+
+
+-- * Converting 'ST' to 'IO'
+
+data RealWorld = RealWorld
+
+stToIO :: ST RealWorld a -> IO a
+stToIO = flip evalStateT State . unST
+
+
+-- * Converting between strict and lazy 'ST'
+
+strictToLazyST :: Strict.ST s a -> ST s a
+strictToLazyST =
+   unsafeIOToST . Strict.unsafeSTToIO
+
+{-
+ToDo:
+Do we also have to bring the monadic result into some evaluated form?
+Shall we also trigger all ST actions by a 'seq'ing on the final 'State'?
+-}
+lazyToStrictST :: ST s a -> Strict.ST s a
+lazyToStrictST =
+   Strict.unsafeIOToST . flip evalStateT State . unST
+
+
+-- * Unsafe operations
+
+unsafeInterleaveST :: ST s a -> ST s a
+unsafeInterleaveST (ST st) =
+   ST $ StateT $ \_ -> fmap (\x->(x,State)) (evalStateT st State)
+
+{-
+Explicitly matching the @State@ constructor
+forces former actions to be run.
+-}
+unsafeIOToST :: IO a -> ST s a
+unsafeIOToST m =
+   ST $ StateT $ \State -> fmap (\x->(x,State)) m
+
+{-
+unsafeSTToIO :: ST s a -> IO a
+unsafeSTToIO = unST
+-}
diff --git a/src/Control/Monad/ST/Strict.hs b/src/Control/Monad/ST/Strict.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/ST/Strict.hs
@@ -0,0 +1,64 @@
+{-# LANGUAGE Rank2Types #-}
+module Control.Monad.ST.Strict (
+   ST, runST, fixST,
+
+   RealWorld, stToIO,
+
+   unsafeInterleaveST,
+   unsafeIOToST,
+   unsafeSTToIO,
+   ) where
+
+import Control.Monad.Fix (MonadFix, mfix, )
+import Control.Applicative (Applicative(pure, (<*>)), )
+import System.IO.Unsafe (unsafePerformIO, unsafeInterleaveIO, )
+import System.IO (fixIO, )
+
+
+-- * The 'ST' Monad
+
+newtype ST s a = ST {unST :: IO a}
+
+instance Functor (ST s) where
+   fmap f (ST st) = ST (fmap f st)
+
+instance Applicative (ST s) where
+   pure f = ST (pure f)
+   ST f <*> ST x = ST (f <*> x)
+
+instance Monad (ST s) where
+   return f = ST (return f)
+   fail str = ST (fail str)
+   ST x >> ST y = ST (x >> y)
+   ST x >>= k = ST (unST . k =<< x)
+
+
+runST :: (forall s. ST s a) -> a
+runST st = unsafePerformIO (unST st)
+
+fixST :: (a -> ST s a) -> ST s a
+fixST f = ST (fixIO (unST . f))
+
+instance MonadFix (ST s) where
+   mfix = fixST
+
+
+-- * Converting 'ST' to 'IO'
+
+data RealWorld = RealWorld
+
+stToIO :: ST RealWorld a -> IO a
+stToIO = unST
+
+
+-- * Unsafe operations
+
+unsafeInterleaveST :: ST s a -> ST s a
+unsafeInterleaveST (ST st) =
+   ST (unsafeInterleaveIO st)
+
+unsafeIOToST :: IO a -> ST s a
+unsafeIOToST = ST
+
+unsafeSTToIO :: ST s a -> IO a
+unsafeSTToIO = unST
diff --git a/src/Data/STRef.hs b/src/Data/STRef.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/STRef.hs
@@ -0,0 +1,3 @@
+module Data.STRef (module Data.STRef.Strict) where
+
+import Data.STRef.Strict
diff --git a/src/Data/STRef/Lazy.hs b/src/Data/STRef/Lazy.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/STRef/Lazy.hs
@@ -0,0 +1,22 @@
+module Data.STRef.Lazy (
+   STRef,
+   newSTRef,
+   readSTRef,
+   writeSTRef,
+   modifySTRef,
+   ) where
+
+import Control.Monad.ST.Lazy (ST, strictToLazyST, )
+import Data.STRef.Strict (STRef, )
+import qualified Data.STRef.Strict as ST
+
+
+newSTRef    :: a -> ST s (STRef s a)
+readSTRef   :: STRef s a -> ST s a
+writeSTRef  :: STRef s a -> a -> ST s ()
+modifySTRef :: STRef s a -> (a -> a) -> ST s ()
+
+newSTRef   = strictToLazyST . ST.newSTRef
+readSTRef  = strictToLazyST . ST.readSTRef
+writeSTRef r a = strictToLazyST (ST.writeSTRef r a)
+modifySTRef r f = strictToLazyST (ST.modifySTRef r f)
diff --git a/src/Data/STRef/Strict.hs b/src/Data/STRef/Strict.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/STRef/Strict.hs
@@ -0,0 +1,31 @@
+module Data.STRef.Strict (
+   STRef,
+   newSTRef,
+   readSTRef,
+   writeSTRef,
+   modifySTRef,
+   ) where
+
+import Control.Monad.ST.Strict (ST, )
+import qualified Control.Monad.ST.Strict as Strict
+import qualified Data.IORef as IORef
+
+
+newtype STRef s a = STRef {unSTRef :: IORef.IORef a}
+
+
+newSTRef :: a -> ST s (STRef s a)
+newSTRef a =
+   Strict.unsafeIOToST (fmap STRef (IORef.newIORef a))
+
+readSTRef :: STRef s a -> ST s a
+readSTRef ref =
+   Strict.unsafeIOToST (IORef.readIORef (unSTRef ref))
+
+writeSTRef :: STRef s a -> a -> ST s ()
+writeSTRef ref a =
+   Strict.unsafeIOToST (IORef.writeIORef (unSTRef ref) a)
+
+modifySTRef :: STRef s a -> (a -> a) -> ST s ()
+modifySTRef ref f =
+   Strict.unsafeIOToST (IORef.modifyIORef (unSTRef ref) f)
diff --git a/statethread.cabal b/statethread.cabal
new file mode 100644
--- /dev/null
+++ b/statethread.cabal
@@ -0,0 +1,40 @@
+Name:           statethread
+Version:        0.1
+License:        BSD3
+License-File:   LICENSE
+Maintainer:     haskell@henning-thielemann.de
+Synopsis:       The ST monad and STRefs
+Category:       Data Structures, Monads
+Description:
+  The ST monad and STRefs in a portable form.
+  This package implements state threads as wrapper around IO and IORefs.
+  Your compiler must support rank-2-types, IORefs,
+  unsafePerformIO and unsafeInterleaveIO.
+  The package can be used as drop-in replacement for the 'st' package.
+Build-Type:     Simple
+Cabal-Version:  >=1.6
+Tested-With:    JHC==0.7.3
+
+Source-Repository this
+  Tag:         0.1
+  Type:        darcs
+  Location:    http://darcs.haskell.org/packages/statethread/
+
+Source-Repository head
+  Type:        darcs
+  Location:    http://darcs.haskell.org/packages/statethread/
+
+Library
+  Build-Depends:
+    transformers >=0.0 && <0.2,
+    applicative >=1.0 && <1.1,
+    base >=1.0 && <2
+  Extensions: Rank2Types
+  Hs-Source-Dirs: src
+  Exposed-Modules:
+    Control.Monad.ST
+    Control.Monad.ST.Lazy
+    Control.Monad.ST.Strict
+    Data.STRef
+    Data.STRef.Lazy
+    Data.STRef.Strict
