diff --git a/dist/build/testsStub/testsStub-tmp/testsStub.hs b/dist/build/testsStub/testsStub-tmp/testsStub.hs
deleted file mode 100644
--- a/dist/build/testsStub/testsStub-tmp/testsStub.hs
+++ /dev/null
@@ -1,5 +0,0 @@
-module Main ( main ) where
-import Distribution.Simple.Test.LibV09 ( stubMain )
-import Tests ( tests )
-main :: IO ()
-main = stubMain tests
diff --git a/purescript-bridge.cabal b/purescript-bridge.cabal
--- a/purescript-bridge.cabal
+++ b/purescript-bridge.cabal
@@ -10,7 +10,7 @@
 -- PVP summary:      +-+------- breaking API changes
 --                   | | +----- non-breaking API additions
 --                   | | | +--- code changes with no API change
-version:             0.1.0.0
+version:             0.3.0.0
 
 -- A short (one-line) description of the package.
 synopsis:            Generate PureScript data types from Haskell data types
@@ -51,12 +51,13 @@
 
 library
   -- Modules exported by the library.
-  exposed-modules: PureScript.Bridge.SumType
-                , PureScript.Bridge.TypeInfo
-                , PureScript.Bridge.Tuple
-                , PureScript.Bridge.Primitives
-                , PureScript.Bridge
-                , PureScript.Bridge.Printer
+  exposed-modules: Language.PureScript.Bridge.SumType
+                , Language.PureScript.Bridge.TypeInfo
+                , Language.PureScript.Bridge.Tuple
+                , Language.PureScript.Bridge.Primitives
+                , Language.PureScript.Bridge
+                , Language.PureScript.Bridge.Printer
+                , Language.PureScript.Bridge.TypeParameters
 
   -- Modules included in this library but not exported.
   -- other-modules:
@@ -67,6 +68,7 @@
   -- Other library packages from which modules are imported.
   build-depends:       base >=4.8 && <4.9
                      , containers
+                     , directory
                      , filepath
                      , text
                      , generic-deriving
@@ -82,7 +84,8 @@
 Test-Suite tests
     type:       detailed-0.9
     test-module: Tests
-    build-depends: base, Cabal >= 1.9.2
+    build-depends: base
+                , Cabal >= 1.9.2
                 , HUnit
                 , purescript-bridge
     hs-source-dirs: test
diff --git a/src/Language/PureScript/Bridge.hs b/src/Language/PureScript/Bridge.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/PureScript/Bridge.hs
@@ -0,0 +1,98 @@
+{-# LANGUAGE OverloadedStrings #-}
+module Language.PureScript.Bridge (
+    bridgeSumType
+  , defaultBridge
+  , module Bridge
+  , writePSTypes
+ ) where
+
+
+import qualified Data.Text as T
+
+import Language.PureScript.Bridge.SumType as Bridge
+import Language.PureScript.Bridge.TypeInfo as Bridge
+import Language.PureScript.Bridge.Tuple as Bridge
+import Language.PureScript.Bridge.Primitives as Bridge
+import Language.PureScript.Bridge.Printer as Bridge
+
+
+
+import Control.Applicative
+import qualified Data.Map as M
+import Data.Maybe
+
+-- | Your entry point to this library and quite likely all you will need.
+-- | Make sure all your types derive Generic and Typeable.
+-- | Typeable is not needed from ghc-7.10 on.
+-- | Then call 'writePSTypes' like this:
+-- | @
+-- |   let myTypes = [
+-- |        'toSumType' ('Proxy' :: 'Proxy' MyType1)
+-- |      , 'toSumType' ('Proxy' :: 'Proxy' MyType2)
+-- |     ]
+-- |   'writePSTypes' 'defaultBridge' "path/to/you/purescript/project" myTypes
+-- | @
+-- | You can add new type mappings, like this:
+-- | @
+-- |   myBridge = 'defaultBridge' <|> mySpecialTypeBridge
+-- | @
+-- | Find examples for implementing your own type bridges in: 'Language.PureScript.Bridge.Primitives'
+-- | A real world use case of this library can be found <https://github.com/gonimo/gonimo-back/blob/master/src/MkFrontendTypes.hs here>.
+-- | Last but not least:
+-- | WARNING: This function overwrites files - make backups or use version control!
+writePSTypes :: TypeBridge -> FilePath -> [SumType] -> IO ()
+writePSTypes br root sts = do
+    let bridged = map (bridgeSumType br) sts
+    let modules = M.elems $ sumTypesToModules M.empty bridged
+    mapM_ (printModule root) modules
+
+bridgeSumType :: TypeBridge -> SumType -> SumType
+bridgeSumType br (SumType t cs) = SumType t $ map (bridgeConstructor br) cs
+
+{--
+ -- Optimistically and recursively translate types: If the passed TypeBridge returns Nothing,
+ -- then the original TypeInfo is returned with the typePackage field cleared.
+ -- You don't need to call this function directly, just use bridgeSumType with your TypeBridge
+--}
+doBridge :: TypeBridge -> TypeInfo -> TypeInfo
+doBridge br info = let
+    translated = info { typePackage = "" }
+    res = fixTypeParameters $ fromMaybe translated (br info)
+  in
+    res {
+      typeParameters = map (doBridge br) . typeParameters $ res
+    }
+
+-- | Default bridge for mapping primitive/common types:
+-- | You can append your own bridges like this:
+-- | defaultBridge <|> myBridge1 <|> myBridge2
+defaultBridge :: TypeBridge
+defaultBridge t = stringBridge t
+  <|> listBridge t
+  <|> maybeBridge t
+  <|> eitherBridge t
+  <|> boolBridge t
+  <|> intBridge t
+  <|> tupleBridge t
+
+bridgeConstructor :: TypeBridge -> DataConstructor -> DataConstructor
+bridgeConstructor br (DataConstructor name (Left infos)) =
+    DataConstructor name . Left $ map (doBridge br) infos
+bridgeConstructor br (DataConstructor name (Right record)) =
+    DataConstructor name . Right $ map (bridgeRecordEntry br) record
+
+bridgeRecordEntry :: TypeBridge -> RecordEntry -> RecordEntry
+bridgeRecordEntry br (RecordEntry label value) = RecordEntry label $ doBridge br value
+
+-- | Translate types that come from any module named "Something.TypeParameters" to lower case:
+-- | Also drop the 1 at the end if present
+fixTypeParameters :: TypeInfo -> TypeInfo
+fixTypeParameters t
+  | T.isSuffixOf "TypeParameters" (typeModule t) = t {
+      typePackage = "" -- Don't suggest any packages
+    , typeModule = "" -- Don't import any modules
+    , typeName = stripNum . T.toLower $ typeName t
+    }
+  | otherwise = t
+  where
+    stripNum v = fromMaybe v (T.stripSuffix "1" v)
diff --git a/src/Language/PureScript/Bridge/Primitives.hs b/src/Language/PureScript/Bridge/Primitives.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/PureScript/Bridge/Primitives.hs
@@ -0,0 +1,64 @@
+{-# LANGUAGE OverloadedStrings #-}
+module Language.PureScript.Bridge.Primitives where
+
+
+import Language.PureScript.Bridge.TypeInfo
+
+boolBridge :: TypeBridge
+boolBridge t
+  | eqTypeName "Bool" t = Just $ t {
+      typePackage = "purescript-prim"
+    , typeModule = "Prim"
+    , typeName = "Boolean"
+    , typeParameters = []
+    }
+  | otherwise = Nothing
+
+intBridge :: TypeBridge
+intBridge t
+  | eqTypeName "Int" t = Just $ t {
+      typePackage = "purescript-prim"
+    , typeModule = "Prim"
+    }
+  | otherwise = Nothing
+
+
+stringBridge :: TypeBridge
+stringBridge t
+  | isStringLike = Just $ t {
+      typePackage = "purescript-prim"
+    , typeModule = "Prim"
+    , typeName = "String"
+    , typeParameters = []
+    }
+  | otherwise = Nothing
+  where
+    isStringLike = isText || isString
+    isText = typeName t == "Text"
+    isString = typeName t == "[]" && all ((==) "Char" . typeName) (typeParameters t)
+
+listBridge :: TypeBridge
+listBridge t
+  | eqTypeName "[]" t = Just $ t {
+      typePackage = "purescript-prim"
+    , typeModule = "Prim"
+    , typeName = "Array"
+    }
+  | otherwise = Nothing
+
+maybeBridge :: TypeBridge
+maybeBridge t
+  | eqTypeName "Maybe" t = Just $ t {
+      typePackage = "purescript-maybe"
+    , typeModule = "Data.Maybe"
+    }
+  | otherwise = Nothing
+
+
+eitherBridge :: TypeBridge
+eitherBridge t
+  | eqTypeName "Either" t = Just $ t {
+      typePackage = "purescript-either"
+    , typeModule = "Data.Either"
+    }
+  | otherwise = Nothing
diff --git a/src/Language/PureScript/Bridge/Printer.hs b/src/Language/PureScript/Bridge/Printer.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/PureScript/Bridge/Printer.hs
@@ -0,0 +1,111 @@
+{-# LANGUAGE OverloadedStrings #-}
+module Language.PureScript.Bridge.Printer where
+
+import Data.Map.Strict (Map)
+import qualified Data.Map.Strict as M
+import Data.Monoid
+import Data.Set (Set)
+import qualified Data.Set as S
+import Data.Text (Text)
+import qualified Data.Text as T
+import qualified Data.Text.IO as T
+import System.Directory
+import System.FilePath
+import Control.Monad
+
+
+import Language.PureScript.Bridge.SumType
+import Language.PureScript.Bridge.TypeInfo
+
+
+data PSModule = PSModule {
+  psModuleName :: !Text
+, psImportLines :: !(Map Text ImportLine)
+, psTypes :: ![SumType]
+} deriving Show
+
+data ImportLine = ImportLine {
+  importModule :: !Text
+, importTypes :: !(Set Text)
+} deriving Show
+
+type Modules = Map Text PSModule
+type ImportLines = Map Text ImportLine
+
+printModule :: FilePath -> PSModule -> IO ()
+printModule root m = do
+  unlessM (doesDirectoryExist mDir) $ createDirectoryIfMissing True mDir
+  T.writeFile mPath . moduleToText $ m
+  where
+    mFile = (joinPath . map T.unpack . T.splitOn "." $ psModuleName m) <> ".purs"
+    mPath = root </> mFile
+    mDir = takeDirectory mPath
+
+moduleToText :: PSModule -> Text
+moduleToText m = T.unlines $
+  "module " <> psModuleName m <> " where\n"
+  : map importLineToText (M.elems (psImportLines m))
+  ++ [ "\nimport Data.Generic (class Generic)\n\n" ]
+  ++ map sumTypeToText (psTypes m)
+
+
+importLineToText :: ImportLine -> Text
+importLineToText l = "import " <> importModule l <> " (" <> typeList <> ")"
+  where
+    typeList = T.intercalate ", " (S.toList (importTypes l))
+
+sumTypeToText :: SumType -> Text
+sumTypeToText (SumType t cs) = T.unlines $
+    "data " <> typeName t <> " ="
+  :  [ "    " <> T.intercalate "\n  | " (map (constructorToText 4) cs) ]
+  ++ [ "\nderive instance generic" <> typeName t <> " :: Generic " <> typeName t <> "\n" ]
+
+
+constructorToText :: Int -> DataConstructor -> Text
+constructorToText _ (DataConstructor n (Left ts))  = n <> " " <> T.intercalate " " (map typeInfoToText ts)
+constructorToText indentation (DataConstructor n (Right rs)) = T.unlines $
+      n <> " {"
+    :  [ spaces (indentation + 2) <> T.intercalate intercalation (map recordEntryToText rs) ]
+    ++ [ spaces indentation <> "}" ]
+  where
+    intercalation = "\n" <> spaces indentation <> "," <> " "
+    spaces c = T.replicate c " "
+
+recordEntryToText :: RecordEntry -> Text
+recordEntryToText e = recLabel e <> " :: " <> typeInfoToText (recValue e)
+
+
+typeInfoToText :: TypeInfo -> Text
+typeInfoToText t = if length textParameters > 1 then "(" <> inner <> ")" else inner
+  where
+    inner = typeName t <> T.intercalate " " textParameters
+    textParameters = map typeInfoToText (typeParameters t)
+
+sumTypesToModules :: Modules -> [SumType] -> Modules
+sumTypesToModules = foldr sumTypeToModule
+
+sumTypeToModule :: SumType -> Modules -> Modules
+sumTypeToModule st@(SumType t _) = M.alter (Just. updateModule) (typeModule t)
+  where
+    updateModule Nothing = PSModule {
+          psModuleName = typeModule t
+        , psImportLines = dropSelf $ typesToImportLines M.empty (getUsedTypes st)
+        , psTypes = [st]
+        }
+    updateModule (Just m) = m {
+        psImportLines = dropSelf $ typesToImportLines (psImportLines m) (getUsedTypes st)
+      , psTypes = st : psTypes m
+      }
+    dropSelf = M.delete (typeModule t)
+
+typesToImportLines :: ImportLines -> [TypeInfo] -> ImportLines
+typesToImportLines = foldr typeToImportLines
+
+typeToImportLines :: TypeInfo -> ImportLines -> ImportLines
+typeToImportLines t = M.alter (Just . updateLine) (typeModule t)
+  where
+    updateLine Nothing = ImportLine (typeModule t) (S.singleton (typeName t))
+    updateLine (Just (ImportLine m types)) = ImportLine m $ S.insert (typeName t) types
+
+unlessM :: Monad m => m Bool -> m () -> m ()
+unlessM mbool action = mbool >>= flip unless action
diff --git a/src/Language/PureScript/Bridge/SumType.hs b/src/Language/PureScript/Bridge/SumType.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/PureScript/Bridge/SumType.hs
@@ -0,0 +1,82 @@
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+
+
+{-# LANGUAGE DeriveGeneric #-}
+
+
+module Language.PureScript.Bridge.SumType where
+
+import Generics.Deriving
+import Data.Text (Text)
+import qualified Data.Text as T
+import Data.Proxy
+import Data.Typeable
+
+import Language.PureScript.Bridge.TypeInfo
+
+data SumType = SumType TypeInfo [DataConstructor] deriving Show
+
+data DataConstructor = DataConstructor {
+  sigConstructor :: !Text
+, sigValues :: !(Either [TypeInfo] [RecordEntry])
+} deriving Show
+
+data RecordEntry = RecordEntry {
+  recLabel :: !Text
+, recValue :: !TypeInfo
+} deriving Show
+
+toSumType :: forall t. (Generic t, Typeable t, GDataConstructor (Rep t)) => Proxy t -> SumType
+toSumType p = SumType  (mkTypeInfo p) constructors
+  where
+    constructors = gToConstructors (from (undefined :: t))
+
+class GDataConstructor f where
+  gToConstructors :: f a -> [DataConstructor]
+
+class GRecordEntry f where
+  gToRecordEntries :: f a -> [RecordEntry]
+
+instance (Datatype a, GDataConstructor c) =>  GDataConstructor (D1 a c) where
+  gToConstructors (M1 c) = gToConstructors c
+
+instance (GDataConstructor a, GDataConstructor b) => GDataConstructor (a :+: b) where
+  gToConstructors (_ :: (a :+: b) f) = gToConstructors (undefined :: a f) ++ gToConstructors (undefined :: b f)
+
+instance (Constructor a, GRecordEntry b) => GDataConstructor (C1 a b) where
+  gToConstructors c@(M1 r) = [
+        DataConstructor {
+          sigConstructor = constructor
+        , sigValues = values
+        }
+      ]
+    where
+      constructor = T.pack $ conName c
+      values = if conIsRecord c
+        then Right $ gToRecordEntries r
+        else Left $ map recValue $ gToRecordEntries r
+
+instance (GRecordEntry a, GRecordEntry b) => GRecordEntry (a :*: b) where
+  gToRecordEntries (_ :: (a :*: b) f) = gToRecordEntries (undefined :: a f) ++ gToRecordEntries (undefined :: b f)
+
+
+instance GRecordEntry U1 where
+  gToRecordEntries _ = []
+
+instance (Selector a, Typeable t) => GRecordEntry (S1 a (K1 R t)) where
+  gToRecordEntries e = [
+      RecordEntry { recLabel = T.pack (selName e)
+      , recValue = mkTypeInfo (Proxy :: Proxy t)
+      }
+    ]
+
+getUsedTypes :: SumType -> [TypeInfo]
+getUsedTypes (SumType _ cs) = foldr constructorToType [] cs
+
+constructorToType :: DataConstructor -> [TypeInfo] -> [TypeInfo]
+constructorToType (DataConstructor _ (Left myTs)) ts = concatMap flattenTypeInfo myTs ++ ts
+constructorToType (DataConstructor _ (Right rs))  ts = concatMap (flattenTypeInfo . recValue) rs ++ ts
diff --git a/src/Language/PureScript/Bridge/Tuple.hs b/src/Language/PureScript/Bridge/Tuple.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/PureScript/Bridge/Tuple.hs
@@ -0,0 +1,39 @@
+{-# LANGUAGE OverloadedStrings #-}
+module Language.PureScript.Bridge.Tuple where
+
+import Data.Monoid
+import Data.Text (Text)
+import qualified Data.Text as T
+
+
+import Language.PureScript.Bridge.TypeInfo
+
+data TupleParserState =
+  Start | OpenFound | ColonFound | Tuple | NoTuple deriving (Eq, Show)
+
+
+tupleBridge :: TypeBridge
+tupleBridge t
+  | isTuple (typeName t) = Just $ t {
+      typePackage = "purescript-tuples"
+    , typeModule = if size == 2 then "Data.Tuple" else "Data.Tuple.Nested"
+    , typeName = "Tuple" <> if size == 2 then "" else T.pack (show size)
+    }
+  | otherwise = Nothing
+  where
+    size = length $ typeParameters t
+
+
+step :: TupleParserState -> Char -> TupleParserState
+step Start '(' = OpenFound
+step Start _ = NoTuple
+step OpenFound ',' = ColonFound
+step OpenFound _ = NoTuple
+step ColonFound ',' = ColonFound
+step ColonFound ')' = Tuple
+step ColonFound _ = NoTuple
+step Tuple _ = NoTuple
+step NoTuple _ = NoTuple
+
+isTuple :: Text -> Bool
+isTuple = (== Tuple) . T.foldl' step Start
diff --git a/src/Language/PureScript/Bridge/TypeInfo.hs b/src/Language/PureScript/Bridge/TypeInfo.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/PureScript/Bridge/TypeInfo.hs
@@ -0,0 +1,45 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Language.PureScript.Bridge.TypeInfo where
+
+
+import Data.Text (Text)
+import qualified Data.Text as T
+import Data.Proxy
+import Data.Typeable
+
+
+-- Translates a Haskell type info to a PureScript type info:
+type TypeBridge = TypeInfo -> Maybe TypeInfo
+
+
+-- Basic info about a data type:
+data TypeInfo = TypeInfo {
+  -- | Hackage package
+  typePackage :: !Text
+  -- | Full Module path
+, typeModule :: !Text
+, typeName :: !Text
+, typeParameters :: ![TypeInfo]
+} deriving (Eq, Show)
+
+mkTypeInfo :: Typeable t => Proxy t -> TypeInfo
+mkTypeInfo = mkTypeInfo' . typeRep
+
+mkTypeInfo' :: TypeRep -> TypeInfo
+mkTypeInfo' rep = let
+    con = typeRepTyCon rep
+  in TypeInfo {
+    typePackage = T.pack $ tyConPackage con
+  , typeModule = T.pack $ tyConModule con
+  , typeName = T.pack $ tyConName con
+  , typeParameters = map mkTypeInfo' (typeRepArgs rep)
+  }
+
+-- | Put the TypeInfo in a list together with all its typeParameters (recursively)
+flattenTypeInfo :: TypeInfo -> [TypeInfo]
+flattenTypeInfo t = t : concatMap flattenTypeInfo (typeParameters t)
+
+-- Little helper for type bridge implementers
+eqTypeName :: Text -> TypeInfo -> Bool
+eqTypeName name = (== name) . typeName
diff --git a/src/Language/PureScript/Bridge/TypeParameters.hs b/src/Language/PureScript/Bridge/TypeParameters.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/PureScript/Bridge/TypeParameters.hs
@@ -0,0 +1,74 @@
+-- | As we translate types and not type constructors, we have to pass dummy types
+-- | to any type constructor. doBridge will translate all parameter types which
+-- | come from a module TypeParameters (e.g. this one) to lower case.
+-- | E.g. for translating something like Maybe:
+-- | @
+-- |   data Maybe' a = Nothing' | Just' a
+-- | @
+-- | you would use:
+-- | @
+-- |   import 'Language.PureScript.Bridge'
+-- |   import 'Language.PureScript.Bridge.TypeParameters'
+-- |   toSumType (Proxy :: Proxy (Maybe A)) -- Note the capital A, which comes from the TypeParameters module.
+-- | @
+
+module Language.PureScript.Bridge.TypeParameters where
+
+
+data A
+data B
+data C
+data D
+data E
+data F
+data G
+data H
+data I
+data J
+data K
+data L
+data M
+data N
+data O
+data P
+data Q
+data R
+data S
+data T
+data U
+data V
+data W
+data X
+data Y
+data Z
+
+-- | You can use those if your type parameters are actually type constructors as well:
+-- | @
+-- | toSumType (Proxy :: Proxy ('ReaderT' R M1 A))
+-- | @
+data A1 a
+data B1 a
+data C1 a
+data D1 a
+data E1 a
+data F1 a
+data G1 a
+data H1 a
+data I1 a
+data J1 a
+data K1 a
+data L1 a
+data M1 a
+data N1 a
+data O1 a
+data P1 a
+data Q1 a
+data R1 a
+data S1 a
+data T1 a
+data U1 a
+data V1 a
+data W1 a
+data X1 a
+data Y1 a
+data Z1 a
diff --git a/src/PureScript/Bridge.hs b/src/PureScript/Bridge.hs
deleted file mode 100644
--- a/src/PureScript/Bridge.hs
+++ /dev/null
@@ -1,56 +0,0 @@
-{-# LANGUAGE OverloadedStrings #-}
-module PureScript.Bridge (
-    bridgeSumType
-  , defaultBridge
- ) where
-
-
-import Data.Text (Text)
-import qualified Data.Text as T
-import Data.Monoid
-
-import PureScript.Bridge.SumType
-import PureScript.Bridge.TypeInfo
-import PureScript.Bridge.Tuple
-import PureScript.Bridge.Primitives
-
-
-import Control.Applicative
-import Data.Maybe
-
-bridgeSumType :: TypeBridge -> SumType -> SumType
-bridgeSumType br (SumType t cs) = SumType t . map (bridgeConstructor br) $ cs
-
-{--
- -- Optimistically and recursively translate types: If the passed TypeBridge returns Nothing,
- -- then the original TypeInfo is returned with the typePackage field cleared.
- -- You don't need to call this function directly, just use bridgeSumType with your TypeBridge
---}
-doBridge :: TypeBridge -> TypeInfo -> TypeInfo
-doBridge br info = let
-    translated = info { typePackage = "" }
-    res = fromMaybe translated (br info)
-  in
-    res {
-      typeParameters = map (doBridge br) . typeParameters $ res
-    }
-
--- | Default bridge for mapping primitive/common types:
--- | You can append your own bridges like this:
--- | defaultBridge <|> myBridge1 <|> myBridge2
-defaultBridge :: TypeBridge
-defaultBridge t = stringBridge t
-  <|> listBridge t
-  <|> maybeBridge t
-  <|> eitherBridge t
-  <|> intBridge t
-  <|> tupleBridge t
-
-bridgeConstructor :: TypeBridge -> DataConstructor -> DataConstructor
-bridgeConstructor br (DataConstructor name (Left infos)) =
-    DataConstructor name . Left $ map (doBridge br) infos
-bridgeConstructor br (DataConstructor name (Right record)) =
-    DataConstructor name . Right $ map (bridgeRecordEntry br) record
-
-bridgeRecordEntry :: TypeBridge -> RecordEntry -> RecordEntry
-bridgeRecordEntry br (RecordEntry label value) = RecordEntry label $ doBridge br value
diff --git a/src/PureScript/Bridge/Primitives.hs b/src/PureScript/Bridge/Primitives.hs
deleted file mode 100644
--- a/src/PureScript/Bridge/Primitives.hs
+++ /dev/null
@@ -1,55 +0,0 @@
-{-# LANGUAGE OverloadedStrings #-}
-module PureScript.Bridge.Primitives where
-
-
-import PureScript.Bridge.TypeInfo
-
-
-intBridge :: TypeBridge
-intBridge t
-  | eqTypeName "Int" t = Just $ t {
-      typePackage = "purescript-prim"
-    , typeModule = "Prim"
-    }
-  | otherwise = Nothing
-
-
-stringBridge :: TypeBridge
-stringBridge t
-  | isStringLike = Just $ t {
-      typePackage = "purescript-prim"
-    , typeModule = "Prim"
-    , typeName = "String"
-    , typeParameters = []
-    }
-  | otherwise = Nothing
-  where
-    isStringLike = isText || isString
-    isText = typeName t == "Text" && typePackage t == "text"
-    isString = typeName t == "[]" && all ((==) "Char" . typeName) (typeParameters t)
-
-listBridge :: TypeBridge
-listBridge t
-  | eqTypeName "[]" t = Just $ t {
-      typePackage = "purescript-prim"
-    , typeModule = "Prim"
-    , typeName = "Array"
-    }
-  | otherwise = Nothing
-
-maybeBridge :: TypeBridge
-maybeBridge t
-  | eqTypeName "Maybe" t = Just $ t {
-      typePackage = "purescript-maybe"
-    , typeModule = "Data.Maybe"
-    }
-  | otherwise = Nothing
-
-
-eitherBridge :: TypeBridge
-eitherBridge t
-  | eqTypeName "Either" t = Just $ t {
-      typePackage = "purescript-either"
-    , typeModule = "Data.Either"
-    }
-  | otherwise = Nothing
diff --git a/src/PureScript/Bridge/Printer.hs b/src/PureScript/Bridge/Printer.hs
deleted file mode 100644
--- a/src/PureScript/Bridge/Printer.hs
+++ /dev/null
@@ -1,100 +0,0 @@
-{-# LANGUAGE OverloadedStrings #-}
-module PureScript.Bridge.Printer where
-
-import Data.Map.Strict (Map)
-import qualified Data.Map.Strict as M
-import Data.Monoid
-import Data.Set (Set)
-import qualified Data.Set as S
-import Data.Text (Text)
-import qualified Data.Text as T
-import qualified Data.Text.IO as T
-import System.FilePath
-
-
-import PureScript.Bridge.SumType
-import PureScript.Bridge.TypeInfo
-
-
-data PSModule = PSModule {
-  psModuleName :: Text
-, psImportLines :: Map Text ImportLine
-, psTypes :: [SumType]
-} deriving Show
-
-data ImportLine = ImportLine {
-  importModule :: Text
-, importTypes :: Set Text
-} deriving Show
-
-type Modules = Map Text PSModule
-type ImportLines = Map Text ImportLine
-
-printModule :: FilePath -> PSModule -> IO ()
-printModule root m = T.writeFile mPath . moduleToText $ m
-  where
-    mFile = joinPath . map T.unpack . T.splitOn "." $ psModuleName m
-    mPath = root </> mFile
-
-moduleToText :: PSModule -> Text
-moduleToText m = T.unlines $
-  "module " <> psModuleName m <> "where\n"
-  : map importLineToText (M.elems (psImportLines m))
-  ++ [ "\n\n" ]
-  ++ map sumTypeToText (psTypes m)
-
-
-importLineToText :: ImportLine -> Text
-importLineToText l = "import " <> importModule l <> "(" <> typeList <> ")"
-  where
-    typeList = T.intercalate ", " (S.toList (importTypes l))
-
-sumTypeToText :: SumType -> Text
-sumTypeToText (SumType t cs) = T.unlines $
-    "data " <> typeName t <> "="
-  : [ "    " <> T.intercalate "  | " (map (constructorToText 4) cs) ]
-
-constructorToText :: Int -> DataConstructor -> Text
-constructorToText _ (DataConstructor n (Left ts))  = n <> T.intercalate " " (map typeInfoToText ts)
-constructorToText indentation (DataConstructor n (Right rs)) = T.unlines $
-      n <> " {"
-    : [spaces (indentation + 2) <> T.intercalate intercalation (map recordEntryToText rs)]
-    ++ [ spaces indentation <> "}" ]
-  where
-    intercalation = "\n" <> spaces indentation <> "," <> spaces 2
-    spaces c = T.replicate c " "
-
-recordEntryToText :: RecordEntry -> Text
-recordEntryToText e = recLabel e <> " :: " <> typeInfoToText (recValue e)
-
-
-typeInfoToText :: TypeInfo -> Text
-typeInfoToText t = if length textParameters > 1 then "(" <> inner <> ")" else inner
-  where
-    inner = typeName t <> T.intercalate " " textParameters
-    textParameters = map typeInfoToText (typeParameters t)
-
-sumTypesToModules :: Modules -> [SumType] -> Modules
-sumTypesToModules = foldr sumTypeToModule
-
-sumTypeToModule :: SumType -> Modules -> Modules
-sumTypeToModule st@(SumType t _) = M.alter (Just. updateModule) (typeModule t)
-  where
-    updateModule Nothing = PSModule {
-          psModuleName = typeModule t
-        , psImportLines = typesToImportLines M.empty (getUsedTypes st)
-        , psTypes = [st]
-        }
-    updateModule (Just m) = m {
-        psImportLines = typesToImportLines (psImportLines m) (getUsedTypes st)
-      , psTypes = st : psTypes m
-      }
-
-typesToImportLines :: ImportLines -> [TypeInfo] -> ImportLines
-typesToImportLines = foldr typeToImportLines
-
-typeToImportLines :: TypeInfo -> ImportLines -> ImportLines
-typeToImportLines t = M.alter (Just . updateLine) (typeModule t)
-  where
-    updateLine Nothing = ImportLine (typeModule t) (S.singleton (typeName t))
-    updateLine (Just (ImportLine m types)) = ImportLine m $ S.insert (typeName t) types
diff --git a/src/PureScript/Bridge/SumType.hs b/src/PureScript/Bridge/SumType.hs
deleted file mode 100644
--- a/src/PureScript/Bridge/SumType.hs
+++ /dev/null
@@ -1,85 +0,0 @@
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TypeOperators #-}
-{-# LANGUAGE TypeSynonymInstances #-}
-
-
-{-# LANGUAGE DeriveGeneric #-}
-
-
-module PureScript.Bridge.SumType where
-
-import Generics.Deriving
-import Data.Text (Text)
-import qualified Data.Text as T
-import Data.Proxy
-import Data.Typeable
-
-import PureScript.Bridge.TypeInfo
-
-data SumType = SumType TypeInfo [DataConstructor] deriving Show
-
-data DataConstructor = DataConstructor {
-  sigConstructor :: Text
-, sigValues :: Either [TypeInfo] [RecordEntry]
-} deriving Show
-
-data RecordEntry = RecordEntry {
-  recLabel :: Text
-, recValue :: TypeInfo
-} deriving Show
-
-toSumType :: forall t. (Generic t, Typeable t, GDataConstructor (Rep t)) => Proxy t -> SumType
-toSumType p = SumType  (mkTypeInfo p) constructors
-  where
-    constructors = gToConstructors (from (undefined :: t))
-
-class GDataConstructor f where
-  gToConstructors :: f a -> [DataConstructor]
-
-class GRecordEntry f where
-  gToRecordEntries :: f a -> [RecordEntry]
-
-instance (Datatype a, GDataConstructor c) =>  GDataConstructor (D1 a c) where
-  gToConstructors (M1 c) = gToConstructors c
-
-instance (GDataConstructor a, GDataConstructor b) => GDataConstructor (a :+: b) where
-  gToConstructors (_ :: (a :+: b) f) = gToConstructors (undefined :: a f) ++ gToConstructors (undefined :: b f)
-
-instance (Constructor a, GRecordEntry b) => GDataConstructor (C1 a b) where
-  gToConstructors c@(M1 r) = [
-        DataConstructor {
-          sigConstructor = constructor
-        , sigValues = values
-        }
-      ]
-    where
-      constructor = T.pack $ conName c
-      values = if conIsRecord c
-        then Right $ gToRecordEntries r
-        else Left $ map recValue $ gToRecordEntries r
-
-instance (GRecordEntry a, GRecordEntry b) => GRecordEntry (a :*: b) where
-  gToRecordEntries (_ :: (a :*: b) f) = gToRecordEntries (undefined :: a f) ++ gToRecordEntries (undefined :: b f)
-
-
-instance GRecordEntry U1 where
-  gToRecordEntries _ = []
-
-instance (Selector a, Typeable t) => GRecordEntry (S1 a (K1 R t)) where
-  gToRecordEntries e = [
-      RecordEntry { recLabel = T.pack (selName e)
-      , recValue = mkTypeInfo (Proxy :: Proxy t)
-      }
-    ]
-
-getUsedTypes :: SumType -> [TypeInfo]
-getUsedTypes (SumType _ cs) = foldr constructorToType [] cs
-
-constructorToType :: DataConstructor -> [TypeInfo] -> [TypeInfo]
-constructorToType (DataConstructor _ (Left myTs)) ts = concatMap flattenTypeInfo myTs ++ ts
-constructorToType (DataConstructor _ (Right rs))  ts = concatMap (flattenTypeInfo . recValue) rs ++ ts
-
-flattenTypeInfo :: TypeInfo -> [TypeInfo]
-flattenTypeInfo t = t : concatMap flattenTypeInfo (typeParameters t)
diff --git a/src/PureScript/Bridge/Tuple.hs b/src/PureScript/Bridge/Tuple.hs
deleted file mode 100644
--- a/src/PureScript/Bridge/Tuple.hs
+++ /dev/null
@@ -1,39 +0,0 @@
-{-# LANGUAGE OverloadedStrings #-}
-module PureScript.Bridge.Tuple where
-
-import Data.Monoid
-import Data.Text (Text)
-import qualified Data.Text as T
-
-
-import PureScript.Bridge.TypeInfo
-
-data TupleParserState =
-  Start | OpenFound | ColonFound | Tuple | NoTuple deriving (Eq, Show)
-
-
-tupleBridge :: TypeBridge
-tupleBridge t
-  | isTuple (typeName t) = Just $ t {
-      typePackage = "purescript-tuples"
-    , typeModule = if size == 2 then "Data.Tuple" else "Data.Tuple.Nested"
-    , typeName = "Tuple" <> if size == 2 then "" else T.pack (show size)
-    }
-  | otherwise = Nothing
-  where
-    size = length $ typeParameters t
-
-
-step :: TupleParserState -> Char -> TupleParserState
-step Start '(' = OpenFound
-step Start _ = NoTuple
-step OpenFound ',' = ColonFound
-step OpenFound _ = NoTuple
-step ColonFound ',' = ColonFound
-step ColonFound ')' = Tuple
-step ColonFound _ = NoTuple
-step Tuple _ = NoTuple
-step NoTuple _ = NoTuple
-
-isTuple :: Text -> Bool
-isTuple = (== Tuple) . T.foldl' step Start
diff --git a/src/PureScript/Bridge/TypeInfo.hs b/src/PureScript/Bridge/TypeInfo.hs
deleted file mode 100644
--- a/src/PureScript/Bridge/TypeInfo.hs
+++ /dev/null
@@ -1,44 +0,0 @@
-{-# LANGUAGE OverloadedStrings #-}
-
-module PureScript.Bridge.TypeInfo where
-
-
-import Data.Text (Text)
-import qualified Data.Text as T
-import Data.Maybe
-import Data.Proxy
-import Data.Typeable
-
-
--- Translates a Haskell type info to a PureScript type info:
-type TypeBridge = TypeInfo -> Maybe TypeInfo
-
-
--- Basic info about a data type:
-data TypeInfo = TypeInfo {
-  -- | Hackage package
-  typePackage :: Text
-  -- | Full Module path
-, typeModule :: Text
-, typeName :: Text
-, typeParameters :: [TypeInfo]
-} deriving (Eq, Show)
-
-mkTypeInfo :: Typeable t => Proxy t -> TypeInfo
-mkTypeInfo = mkTypeInfo' . typeRep
-
-mkTypeInfo' :: TypeRep -> TypeInfo
-mkTypeInfo' rep = let
-    con = typeRepTyCon rep
-  in TypeInfo {
-    typePackage = T.pack $ tyConPackage con
-  , typeModule = T.pack $ tyConModule con
-  , typeName = T.pack $ tyConName con
-  , typeParameters = map mkTypeInfo' (typeRepArgs rep)
-  }
-
-
-
--- Little helper for type bridge implementers
-eqTypeName :: Text -> TypeInfo -> Bool
-eqTypeName name = (== name) . typeName
diff --git a/test/Tests.hs b/test/Tests.hs
--- a/test/Tests.hs
+++ b/test/Tests.hs
@@ -7,7 +7,7 @@
 
 
 import Data.Proxy
-import PureScript.Bridge.TypeInfo
+import Language.PureScript.Bridge.TypeInfo
 
 
 testTypeInfo :: IO Progress
