diff --git a/prim.cabal b/prim.cabal
--- a/prim.cabal
+++ b/prim.cabal
@@ -1,7 +1,7 @@
 cabal-version: 2.4
 name: prim
 homepage: https://github.com/daig/prim#readme
-version: 0.1.0.2
+version: 0.1.0.3
 category: Prelude
 synopsis: An ergonomic but conservative interface to ghc-prim
 description: 
@@ -32,14 +32,13 @@
                     , KindSignatures, PolyKinds, ConstraintKinds, TypeOperators, RankNTypes
                     , BlockArguments
   hs-source-dirs: src
-  other-modules: Prelude
   reexported-modules: GHC.Tuple as Tuple
   exposed-modules: Char
                  , I64, I32, I16, I8
                  , U64, U32, U16, U8
                  , B, B8, B16, B32, B64
                  , F64, F32
-                 , ST,ST.IO, ST.IO.STM
+                 , IO, IO.STM
                  , Ref
                  , Ref.Weak, Ref.Stable, Ref.Stable.Name, Ref.Byte
                  , Ref.Char8, Ref.Char
@@ -70,4 +69,5 @@
                  , Nat
                  , Stock
                  , Syntax.ImplicitParam
+                 , Prelude
   build-depends: ghc-prim ^>= 0.6.1
diff --git a/src/IO.hs b/src/IO.hs
new file mode 100644
--- /dev/null
+++ b/src/IO.hs
@@ -0,0 +1,6 @@
+module IO where
+--import GHC.Types (TYPE)
+import GHC.Magic
+
+run :: forall (r :: RuntimeRep) (o :: TYPE r). (Token (☸) -> o) -> o
+run = runRW#
diff --git a/src/IO/STM.hs b/src/IO/STM.hs
new file mode 100644
--- /dev/null
+++ b/src/IO/STM.hs
@@ -0,0 +1,20 @@
+module IO.STM where
+import IO
+import GHC.Prim
+
+type STM (a :: TYPE r) = IO a
+type STM_ = IO_
+
+run :: STM a -> IO a
+run = atomically#
+
+-- | Retry execution of the current memory transaction because it has seen values in TVars which mean that it should not continue (e.g. the TVars represent a shared buffer that is now empty).
+-- The implementation may block the thread until one of the TVars that it has read from has been updated.
+retry :: STM a
+retry = retry#
+
+catch :: STM a -> (e -> STM a) -> STM a
+catch = catchSTM#
+
+catch_ :: STM a -> STM a -> STM a
+catch_ = catchRetry#
diff --git a/src/Prelude.hs b/src/Prelude.hs
--- a/src/Prelude.hs
+++ b/src/Prelude.hs
@@ -1,11 +1,10 @@
 {-# OPTIONS_HADDOCK not-home  #-}
 {-# language TypeOperators #-}
-module Prelude (module Prelude, module X) where
+module Prelude (module Prelude, module X, type TYPE) where
 import GHC.Prim as X
 import           GHC.Types as X (TYPE)
 import qualified GHC.Types as GHC
-import ST as X (ST,ST_)
-import ST.IO as X
+import Rep.RTS as X (RuntimeRep)
 
 -- TODO: use hsboot instead of this file
 -- TODO: add safe versions of the sized numbers
@@ -35,6 +34,13 @@
 
 type Maybe# (a :: TYPE r) = (# B, a #)
 
-
 type T = GHC.Type
 type C = GHC.Constraint
+
+type Token = State#
+type ST_ s = Token s -> Token s
+type ST s (a :: TYPE r) = Token s -> (# Token s, a #)
+
+type (☸) = RealWorld
+type IO (a :: TYPE r) = ST (☸) a
+type IO_ = ST_ (☸)
diff --git a/src/ST.hs b/src/ST.hs
deleted file mode 100644
--- a/src/ST.hs
+++ /dev/null
@@ -1,7 +0,0 @@
-{-# language NoImplicitPrelude #-}
-module ST ( ST, ST_) where
-import GHC.Prim (State#, TYPE )
-
-type Token = State#
-type ST_ s = Token s -> Token s
-type ST s (a :: TYPE r) = Token s -> (# Token s, a #)
diff --git a/src/ST/IO.hs b/src/ST/IO.hs
deleted file mode 100644
--- a/src/ST/IO.hs
+++ /dev/null
@@ -1,9 +0,0 @@
-{-# language NoImplicitPrelude #-}
-module ST.IO where
-import GHC.Prim (RealWorld,TYPE)
-import ST (ST,ST_)
-
-
-type (☸) = RealWorld
-type IO (a :: TYPE r) = ST (☸) a
-type IO_ = ST_ (☸)
diff --git a/src/ST/IO/STM.hs b/src/ST/IO/STM.hs
deleted file mode 100644
--- a/src/ST/IO/STM.hs
+++ /dev/null
@@ -1,21 +0,0 @@
-{-# language NoImplicitPrelude #-}
-module ST.IO.STM where
-import ST.IO
-import GHC.Prim
-
-type STM (a :: TYPE r) = IO a
-type STM_ = IO_
-
-atomically :: STM a -> IO a
-atomically = atomically#
-
--- | Retry execution of the current memory transaction because it has seen values in TVars which mean that it should not continue (e.g. the TVars represent a shared buffer that is now empty).
--- The implementation may block the thread until one of the TVars that it has read from has been updated.
-retry :: STM a
-retry = retry#
-
-catch :: STM a -> (e -> STM a) -> STM a
-catch = catchSTM#
-
-catch_ :: STM a -> STM a -> STM a
-catch_ = catchRetry#
