diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2020, Pepe Iborra
+
+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 Pepe Iborra 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,3 @@
+# ghc-check
+
+Use Template Haskell to record the ghc api version at compile time and detect mismatches with the run time version.
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/ghc-check.cabal b/ghc-check.cabal
new file mode 100644
--- /dev/null
+++ b/ghc-check.cabal
@@ -0,0 +1,25 @@
+cabal-version:       2.4
+
+name:                ghc-check
+version:             0.1.0.0
+synopsis:            detect mismatches between compile-time and run-time versions of the ghc api
+description:         detect mismatches between compile-time and run-time versions of the ghc api
+bug-reports:         https://github.com/pepeiborra/ghc-check/issues
+license:             BSD-3-Clause
+license-file:        LICENSE
+author:              Pepe Iborra
+maintainer:          pepeiborra@gmail.com
+category:            Development
+extra-source-files:  README.md
+
+library
+  exposed-modules:     GHC.Check, GHC.Check.Internal
+  -- other-modules:
+  other-extensions:    TemplateHaskell
+  build-depends:       base >=4.10.0.0 && < 5.0,
+                       ghc,
+                       ghc-paths,
+                       template-haskell,
+                       transformers
+  hs-source-dirs:      src
+  default-language:    Haskell2010
diff --git a/src/GHC/Check.hs b/src/GHC/Check.hs
new file mode 100644
--- /dev/null
+++ b/src/GHC/Check.hs
@@ -0,0 +1,21 @@
+{-# LANGUAGE TemplateHaskell #-}
+module GHC.Check (checkGhcVersion, compileTimeVersion, runTimeVersion) where
+
+import GHC
+import GHC.Check.Internal
+import Language.Haskell.TH
+import Language.Haskell.TH.Syntax (lift)
+import Data.Version (Version)
+import GHC.Exts (toList, IsList(fromList))
+
+compileTimeVersion :: Version
+compileTimeVersion = fromList $(lift =<< toList <$> runIO getGHCVersionIO)
+
+runTimeVersion :: Ghc (Maybe Version)
+runTimeVersion = getGHCVersion
+
+-- | Returns 'True' if the run-time version of the 'ghc' package matches the compile-time version
+checkGhcVersion :: Ghc Bool
+checkGhcVersion = do
+    v <- getPackageVersion "ghc"
+    return (Just compileTimeVersion == v)
diff --git a/src/GHC/Check/Internal.hs b/src/GHC/Check/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/GHC/Check/Internal.hs
@@ -0,0 +1,42 @@
+{-# LANGUAGE OverloadedStrings #-}
+module GHC.Check.Internal where
+
+import Control.Applicative
+import GHC
+import GHC.Paths
+import Data.Version (makeVersion, Version)
+import Data.Maybe (fromMaybe)
+import System.Environment (lookupEnv)
+import Packages (initPackages, lookupInstalledPackage, lookupPackageName, lookupPackage)
+import PackageConfig (PackageName(PackageName))
+import Maybes (runMaybeT, MaybeT(MaybeT))
+import Module (componentIdToInstalledUnitId)
+import Control.Monad.Trans.Class (MonadTrans(lift))
+import Packages (InstalledPackageInfo(packageVersion))
+import Control.Monad (join)
+import Data.String (IsString(fromString))
+
+-- Set the GHC libdir to the nix libdir if it's present.
+getLibdir :: IO FilePath
+getLibdir = fromMaybe GHC.Paths.libdir <$> lookupEnv "NIX_GHC_LIBDIR"
+
+getPackageVersion :: String -> Ghc (Maybe Version)
+getPackageVersion packageName = runMaybeT $ do
+    dflags <- lift getSessionDynFlags
+    component <- MaybeT $ return $ lookupPackageName dflags $ PackageName $ fromString packageName
+    p <- MaybeT $ return $ lookupInstalledPackage dflags (componentIdToInstalledUnitId component)
+    return $ packageVersion p
+
+getGHCVersion :: Ghc (Maybe Version)
+getGHCVersion = getPackageVersion "ghc"
+
+getGHCVersionIO :: IO Version
+getGHCVersionIO = do
+    libdir <- getLibdir
+    runGhc (Just libdir) $ do
+        dflags <- getSessionDynFlags
+        _ <- setSessionDynFlags dflags
+        ghcV <- getGHCVersion
+        case ghcV of
+            Just v -> return v
+            Nothing -> error "Cannot get version of ghc package"
