diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,5 @@
+# Changelog for base-compat-migrate
+
+## 0.1.0.0
+
+* Initial release
diff --git a/Generate.hs b/Generate.hs
new file mode 100644
--- /dev/null
+++ b/Generate.hs
@@ -0,0 +1,97 @@
+#!/usr/bin/env stack
+-- stack script --resolver nightly-2018-04-14
+
+{-# OPTIONS -Wall #-}
+{-# LANGUAGE NoMonomorphismRestriction #-}
+{-# LANGUAGE OverloadedStrings #-}
+module Main (main) where
+
+import Control.Monad (unless)
+import Data.String (fromString)
+import Data.String.Conversions (cs)
+import Distribution.ModuleName (ModuleName, components, fromComponents)
+import Distribution.PackageDescription.Parsec (parseGenericPackageDescription, readGenericPackageDescription, runParseResult)
+import Distribution.PackageDescription.PrettyPrint (writeGenericPackageDescription)
+import Distribution.Types.CondTree (condTreeData)
+import Distribution.Types.GenericPackageDescription (GenericPackageDescription, condLibrary)
+import Distribution.Types.Library (exposedModules, reexportedModules)
+import Distribution.Types.ModuleReexport (ModuleReexport (..))
+import Distribution.Types.PackageName (PackageName)
+import Distribution.Verbosity (silent)
+import Network.HTTP.Simple (getResponseBody, getResponseHeader, getResponseStatusCode, httpLBS)
+import System.Directory (createDirectoryIfMissing, doesFileExist)
+import qualified Data.ByteString.Lazy.Char8 as L8
+
+getExposedModules :: GenericPackageDescription -> [ModuleName]
+getExposedModules pd =
+  case condLibrary pd of
+    Just x -> exposedModules (condTreeData x)
+    Nothing -> error "No library"
+
+downloadFile :: String -> FilePath -> IO [ModuleName]
+downloadFile from to = do
+  ex <- doesFileExist to
+  bs <- if ex
+  then do
+    putStrLn $ "Re-using existing " ++ to
+    L8.readFile to
+  else do
+    putStrLn $ "Downloading: " ++ from
+    response <- httpLBS $ fromString from
+    putStrLn $ "Status: " ++ show (getResponseStatusCode response)
+    print $ getResponseHeader "Content-Type" response
+    let body = getResponseBody response
+    L8.writeFile to body
+    pure body
+  case runParseResult (parseGenericPackageDescription (cs bs)) of
+    (_, Right res) -> do
+      putStrLn $ "Parsed " ++ to
+      pure $ getExposedModules res
+    err -> error $ "parse error: " ++ show err
+
+setReexportedModules :: GenericPackageDescription -> [ModuleReexport] -> GenericPackageDescription
+setReexportedModules pd mods =
+  pd
+    { condLibrary =
+      case condLibrary pd of
+        Just cn -> Just cn { condTreeData = (condTreeData cn) { reexportedModules = mods } }
+        Nothing -> Nothing
+    }
+
+mkReexport :: PackageName -> ModuleName -> ModuleReexport
+mkReexport pkg m = ModuleReexport (Just pkg) m m
+
+cabalFileUrl :: String -> String -> String
+cabalFileUrl name version
+  =  "http://raw.githubusercontent.com/commercialhaskell/all-cabal-files/hackage/"
+  ++ name
+  ++ "/" ++ version
+  ++ "/" ++ name ++ ".cabal"
+
+migratePath :: FilePath
+migratePath = "base-compat-migrate.cabal"
+
+baseVersion :: String
+baseVersion = "4.11.0.0"
+
+baseCompatVersion :: String
+baseCompatVersion = "0.10.1"
+
+main :: IO ()
+main = do
+  ex <- doesFileExist migratePath
+  unless ex $
+    error $ "Couldn't find " ++ migratePath ++ ", are you in the repository root?"
+  createDirectoryIfMissing False "tmp"
+  allBaseModules                <- downloadFile
+    (cabalFileUrl "base" baseVersion)
+    ("tmp/base-" ++ baseVersion ++ ".cabal")
+  allBaseCompatModules          <- downloadFile
+    (cabalFileUrl "base-compat" baseCompatVersion)
+    ("tmp/base-compat-" ++ baseCompatVersion ++ ".cabal")
+  let compatModules              = filter ((== "Compat") . last . components) allBaseCompatModules
+  let compatModulesWithoutCompat = fromComponents . init . components <$> compatModules
+  let baseModules                = filter (`notElem` compatModulesWithoutCompat) allBaseModules
+  pd <- readGenericPackageDescription silent migratePath
+  let pd' = setReexportedModules pd $ map (mkReexport "base") baseModules ++ map (mkReexport "base-compat") compatModules
+  writeGenericPackageDescription migratePath pd'
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Adam Bergmark (c) 2018
+
+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.
+
+    * Neither the name of Adam Bergmark nor the names of other
+      contributors may 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/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,51 @@
+# base-compat-migrate [![Hackage](https://img.shields.io/hackage/v/base-compat-migrate.svg)](https://hackage.haskell.org/package/base-compat-migrate) [![Build Status](https://travis-ci.org/bergmark/base-compat-migrate.svg)](https://travis-ci.org/bergmark/base-compat-migrate)
+
+This library is meant as a temporary migration library when moving a
+library to
+[base-compat](http://hackage.haskell.org/package/base-compat) or
+upgrading it. Replace `base-compat` with
+[base-compat-batteries](https://hackage.haskell.org/package/base-compat-batteries)
+in the rest of the README if you want to use that library instead.
+
+`base-compat` defines backwards compatible versions of some base
+modules; If you for example want to make sure `import Prelude` does
+the same thing on all GHC versions you can instead `import
+Prelude.Compat`. If a Compat module exists it means it has some
+backwards compatibility fix, it also re-exports everything that is
+unchanged from the corresponding base module.
+
+base-compat notably does not have Compat modules for every base module
+so you often need to depend on both base and base-compat. The standard
+recommended work-flow is to build your project with the oldest GHC you
+want to support and add Compat imports accordingly.
+
+If you don't have quick access to old GHCs it can be error-prone to
+migrate to upgrade base-compat since you need to look through all base
+imports to see if you should be using Compat versions instead.
+
+## Workflow
+
+This library offers a different work flow:
+
+1. Make sure you are using a GHC version compatible with this project
+   (At the time of writing it is GHC 8.4.1)
+1. Replace any `base` and `base-compat` dependencies in your project
+   with `base-compat-migrate`.
+1. Add `default-extensions: NoImplicitPrelude` to each build component
+   (libraries, executables, test suites, benchmarks).
+1. Compile your project and fix issues:
+  * Add any needed `Prelude.Compat` imports
+  * If a `base` module can't be found change the import to the
+    `Compat` version instead.
+1. Finally, replace the `base-compat-migrate` dependency with `base`
+   and `base-compat`.
+
+Whenever you wish to support newer versions of `base` or `base-compat`
+you can repeat these steps.
+
+## Dependencies
+
+Since `base-compat-migrate` re-exports modules, we depend on minor
+versions of `base` and `base-compat`. A new minor version of either
+may require a new release of this library. This project's cabal file
+is generated by running `generate-library/Main.hs`.
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/base-compat-migrate.cabal b/base-compat-migrate.cabal
new file mode 100644
--- /dev/null
+++ b/base-compat-migrate.cabal
@@ -0,0 +1,257 @@
+cabal-version: 1.21
+name: base-compat-migrate
+version: 0.1.0.0
+license: BSD3
+license-file: LICENSE
+copyright: (c) 2018 Adam Bergmark
+maintainer: adam@bergmark.nl
+author: Adam Bergmark
+tested-with: ghc ==8.4.1
+homepage: https://github.com/bergmark/base-compat-migrate#readme
+bug-reports: https://github.com/bergmark/base-compat-migrate/issues
+synopsis: Helps migrating projects to base-compat(-batteries).
+description:
+    Please see the included README or visit <https://github.com/bergmark/base-compat-migrate#readme>.
+category: Development
+build-type: Simple
+extra-source-files:
+    CHANGELOG.md
+    README.md
+
+source-repository head
+    type: git
+    location: https://github.com/bergmark/base-compat-migrate
+
+flag exe
+    default: False
+    manual: True
+
+library
+    reexported-modules: base:Control.Applicative,
+                        base:Control.Arrow,
+                        base:Control.Category,
+                        base:Control.Concurrent.Chan,
+                        base:Control.Concurrent.QSem,
+                        base:Control.Concurrent.QSemN,
+                        base:Control.Exception,
+                        base:Control.Exception.Base,
+                        base:Control.Monad.Fix,
+                        base:Control.Monad.Instances,
+                        base:Control.Monad.ST,
+                        base:Control.Monad.ST.Lazy,
+                        base:Control.Monad.ST.Lazy.Safe,
+                        base:Control.Monad.ST.Safe,
+                        base:Control.Monad.ST.Strict,
+                        base:Control.Monad.Zip,
+                        base:Data.Char,
+                        base:Data.Coerce,
+                        base:Data.Data,
+                        base:Data.Dynamic,
+                        base:Data.Eq,
+                        base:Data.Fixed,
+                        base:Data.Functor.Classes,
+                        base:Data.Int,
+                        base:Data.Ix,
+                        base:Data.Kind,
+                        base:Data.Maybe,
+                        base:Data.Ord,
+                        base:Data.STRef.Lazy,
+                        base:Data.STRef.Strict,
+                        base:Data.Traversable,
+                        base:Data.Tuple,
+                        base:Data.Type.Bool,
+                        base:Data.Type.Equality,
+                        base:Data.Typeable,
+                        base:Data.Unique,
+                        base:Foreign.C,
+                        base:Foreign.C.Error,
+                        base:Foreign.C.String,
+                        base:Foreign.C.Types,
+                        base:Foreign.Concurrent,
+                        base:Foreign.Marshal.Error,
+                        base:Foreign.Marshal.Pool,
+                        base:Foreign.Ptr,
+                        base:Foreign.Safe,
+                        base:Foreign.StablePtr,
+                        base:Foreign.Storable,
+                        base:GHC.Arr,
+                        base:GHC.Base,
+                        base:GHC.ByteOrder,
+                        base:GHC.Char,
+                        base:GHC.Clock,
+                        base:GHC.Conc,
+                        base:GHC.Conc.IO,
+                        base:GHC.Conc.Signal,
+                        base:GHC.Conc.Sync,
+                        base:GHC.ConsoleHandler,
+                        base:GHC.Constants,
+                        base:GHC.Desugar,
+                        base:GHC.Enum,
+                        base:GHC.Environment,
+                        base:GHC.Err,
+                        base:GHC.Exception,
+                        base:GHC.ExecutionStack,
+                        base:GHC.ExecutionStack.Internal,
+                        base:GHC.Exts,
+                        base:GHC.Fingerprint,
+                        base:GHC.Fingerprint.Type,
+                        base:GHC.Float,
+                        base:GHC.Float.ConversionUtils,
+                        base:GHC.Float.RealFracMethods,
+                        base:GHC.Foreign,
+                        base:GHC.ForeignPtr,
+                        base:GHC.GHCi,
+                        base:GHC.Generics,
+                        base:GHC.IO,
+                        base:GHC.IO.Buffer,
+                        base:GHC.IO.BufferedIO,
+                        base:GHC.IO.Device,
+                        base:GHC.IO.Encoding,
+                        base:GHC.IO.Encoding.CodePage,
+                        base:GHC.IO.Encoding.Failure,
+                        base:GHC.IO.Encoding.Iconv,
+                        base:GHC.IO.Encoding.Latin1,
+                        base:GHC.IO.Encoding.Types,
+                        base:GHC.IO.Encoding.UTF16,
+                        base:GHC.IO.Encoding.UTF32,
+                        base:GHC.IO.Encoding.UTF8,
+                        base:GHC.IO.Exception,
+                        base:GHC.IO.FD,
+                        base:GHC.IO.Handle,
+                        base:GHC.IO.Handle.FD,
+                        base:GHC.IO.Handle.Internals,
+                        base:GHC.IO.Handle.Lock,
+                        base:GHC.IO.Handle.Text,
+                        base:GHC.IO.Handle.Types,
+                        base:GHC.IO.IOMode,
+                        base:GHC.IO.Unsafe,
+                        base:GHC.IOArray,
+                        base:GHC.IORef,
+                        base:GHC.Int,
+                        base:GHC.List,
+                        base:GHC.MVar,
+                        base:GHC.Natural,
+                        base:GHC.Num,
+                        base:GHC.OldList,
+                        base:GHC.OverloadedLabels,
+                        base:GHC.PArr,
+                        base:GHC.Pack,
+                        base:GHC.Profiling,
+                        base:GHC.Ptr,
+                        base:GHC.Read,
+                        base:GHC.Real,
+                        base:GHC.Records,
+                        base:GHC.RTS.Flags,
+                        base:GHC.ST,
+                        base:GHC.StaticPtr,
+                        base:GHC.STRef,
+                        base:GHC.Show,
+                        base:GHC.Stable,
+                        base:GHC.Stack,
+                        base:GHC.Stack.CCS,
+                        base:GHC.Stack.Types,
+                        base:GHC.Stats,
+                        base:GHC.Storable,
+                        base:GHC.TopHandler,
+                        base:GHC.TypeLits,
+                        base:GHC.TypeNats,
+                        base:GHC.Unicode,
+                        base:GHC.Weak,
+                        base:GHC.Word,
+                        base:System.CPUTime,
+                        base:System.Console.GetOpt,
+                        base:System.Environment.Blank,
+                        base:System.IO,
+                        base:System.IO.Error,
+                        base:System.Info,
+                        base:System.Mem,
+                        base:System.Mem.StableName,
+                        base:System.Mem.Weak,
+                        base:System.Posix.Internals,
+                        base:System.Posix.Types,
+                        base:System.Timeout,
+                        base:Text.ParserCombinators.ReadP,
+                        base:Text.ParserCombinators.ReadPrec,
+                        base:Text.Printf,
+                        base:Text.Read.Lex,
+                        base:Text.Show,
+                        base:Text.Show.Functions,
+                        base:Type.Reflection.Unsafe,
+                        base:Unsafe.Coerce,
+                        base-compat:Control.Concurrent.Compat,
+                        base-compat:Control.Concurrent.MVar.Compat,
+                        base-compat:Control.Monad.Compat,
+                        base-compat:Control.Monad.Fail.Compat,
+                        base-compat:Control.Monad.IO.Class.Compat,
+                        base-compat:Control.Monad.ST.Lazy.Unsafe.Compat,
+                        base-compat:Control.Monad.ST.Unsafe.Compat,
+                        base-compat:Data.Bifoldable.Compat,
+                        base-compat:Data.Bifunctor.Compat,
+                        base-compat:Data.Bitraversable.Compat,
+                        base-compat:Data.Bits.Compat,
+                        base-compat:Data.Bool.Compat,
+                        base-compat:Data.Complex.Compat,
+                        base-compat:Data.Either.Compat,
+                        base-compat:Data.Foldable.Compat,
+                        base-compat:Data.Function.Compat,
+                        base-compat:Data.Functor.Compat,
+                        base-compat:Data.Functor.Compose.Compat,
+                        base-compat:Data.Functor.Const.Compat,
+                        base-compat:Data.Functor.Identity.Compat,
+                        base-compat:Data.Functor.Product.Compat,
+                        base-compat:Data.Functor.Sum.Compat,
+                        base-compat:Data.IORef.Compat,
+                        base-compat:Data.List.Compat,
+                        base-compat:Data.List.NonEmpty.Compat,
+                        base-compat:Data.Monoid.Compat,
+                        base-compat:Data.Proxy.Compat,
+                        base-compat:Data.Ratio.Compat,
+                        base-compat:Data.Semigroup.Compat,
+                        base-compat:Data.STRef.Compat,
+                        base-compat:Data.String.Compat,
+                        base-compat:Data.Type.Coercion.Compat,
+                        base-compat:Data.Version.Compat,
+                        base-compat:Data.Void.Compat,
+                        base-compat:Data.Word.Compat,
+                        base-compat:Debug.Trace.Compat,
+                        base-compat:Foreign.Compat,
+                        base-compat:Foreign.ForeignPtr.Compat,
+                        base-compat:Foreign.ForeignPtr.Safe.Compat,
+                        base-compat:Foreign.ForeignPtr.Unsafe.Compat,
+                        base-compat:Foreign.Marshal.Alloc.Compat,
+                        base-compat:Foreign.Marshal.Array.Compat,
+                        base-compat:Foreign.Marshal.Compat,
+                        base-compat:Foreign.Marshal.Safe.Compat,
+                        base-compat:Foreign.Marshal.Unsafe.Compat,
+                        base-compat:Foreign.Marshal.Utils.Compat,
+                        base-compat:Numeric.Compat,
+                        base-compat:Numeric.Natural.Compat,
+                        base-compat:Prelude.Compat,
+                        base-compat:System.Environment.Compat,
+                        base-compat:System.Exit.Compat,
+                        base-compat:System.IO.Unsafe.Compat,
+                        base-compat:Text.Read.Compat,
+                        base-compat:Type.Reflection.Compat
+    other-modules:
+        Paths_base_compat_migrate
+    default-language: Haskell2010
+    build-depends:
+        base ==4.11.0.*,
+        base-compat ==0.10.1.*
+
+executable base-compat-migrate-generate
+    main-is: Generate.hs
+    hs-source-dirs: .
+    default-language: Haskell2010
+    ghc-options: -Wall
+
+    if flag(exe)
+        build-depends:
+            base -any,
+            directory >=1.3.1 && <1.4,
+            bytestring >=0.10.8 && <0.11,
+            Cabal >=2.2.0 && <2.3,
+            http-conduit >=2.3.1 && <2.4,
+            string-conversions >=0.4.0 && <0.5
+    else
+        buildable: False
