diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,15 @@
 # Changelog for password-instances
 
+## 2.0.0.0
+
+-   No longer re-exports anything from `password` to be
+    more predictable and in line with other `...-instances`
+    packages like `quickcheck-instances` and `vector-instances`.
+    [#8](https://github.com/cdepillabout/password/pull/8)
+-   Added instances for "forbidden" type classes with custom type errors.
+    [#8](https://github.com/cdepillabout/password/pull/8)
+-   GHC versions < 8.2 are no longer actively supported. (Tested to work for GHC 8.2.2)
+
 ## 1.0.0.0
 
 -   Various changes re-exported from the `password` package.
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright Dennis Gosnell (c) 2019
+Copyright (c) Dennis Gosnell, 2019; Felix Paulusma, 2020
 
 All rights reserved.
 
@@ -13,9 +13,9 @@
       disclaimer in the documentation and/or other materials provided
       with the distribution.
 
-    * Neither the name of Dennis Gosnell nor the names of other
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
+    * Neither the name of Dennis Gosnell, Felix Paulusma 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
diff --git a/README b/README
new file mode 100644
--- /dev/null
+++ b/README
@@ -0,0 +1,11 @@
+# password-instances
+
+[![Build Status](https://secure.travis-ci.org/cdepillabout/password.svg)](http://travis-ci.org/cdepillabout/password)
+[![Hackage](https://img.shields.io/hackage/v/password-instances.svg)](https://hackage.haskell.org/package/password-instances)
+[![Stackage LTS](http://stackage.org/package/password-instances/badge/lts)](http://stackage.org/lts/package/password-instances)
+[![Stackage Nightly](http://stackage.org/package/password-instances/badge/nightly)](http://stackage.org/nightly/package/password-instances)
+[![BSD3 license](https://img.shields.io/badge/license-BSD3-blue.svg)](./LICENSE)
+
+This package provides various typeclass instances for the plain-text password
+and hashed password datatypes from the
+[password](https://hackage.haskell.org/package/password) package.
diff --git a/README.md b/README.md
deleted file mode 100644
--- a/README.md
+++ /dev/null
@@ -1,10 +0,0 @@
-# password-instances
-
-[![Build Status](https://secure.travis-ci.org/cdepillabout/password.svg)](http://travis-ci.org/cdepillabout/password)
-[![Hackage](https://img.shields.io/hackage/v/password-instances.svg)](https://hackage.haskell.org/package/password-instances)
-[![Stackage LTS](http://stackage.org/package/password-instances/badge/lts)](http://stackage.org/lts/package/password-instances)
-[![Stackage Nightly](http://stackage.org/package/password-instances/badge/nightly)](http://stackage.org/nightly/package/password-instances)
-[![BSD3 license](https://img.shields.io/badge/license-BSD3-blue.svg)](./LICENSE)
-
-This package provides various typeclass instances for the plain-text password
-and hashed password datatypes from the [password](../password) package.
diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -1,2 +1,33 @@
+{-# LANGUAGE CPP #-}
+{-# OPTIONS_GHC -Wall #-}
+module Main (main) where
+
+#ifndef MIN_VERSION_cabal_doctest
+#define MIN_VERSION_cabal_doctest(x,y,z) 0
+#endif
+
+#if MIN_VERSION_cabal_doctest(1,0,0)
+
+import Distribution.Extra.Doctest ( defaultMainWithDoctests )
+main :: IO ()
+main = defaultMainWithDoctests "doctests"
+
+#else
+
+#ifdef MIN_VERSION_Cabal
+-- If the macro is defined, we have new cabal-install,
+-- but for some reason we don't have cabal-doctest in package-db
+--
+-- Probably we are running cabal sdist, when otherwise using new-build
+-- workflow
+#warning You are configuring this package without cabal-doctest installed. \
+         The doctests test-suite will not work as a result. \
+         To fix this, install cabal-doctest before configuring.
+#endif
+
 import Distribution.Simple
+
+main :: IO ()
 main = defaultMain
+
+#endif
diff --git a/password-instances.cabal b/password-instances.cabal
--- a/password-instances.cabal
+++ b/password-instances.cabal
@@ -1,26 +1,32 @@
 cabal-version: 1.12
 
 name:           password-instances
-version:        1.0.0.0
+version:        2.0.0.0
 category:       Data
 synopsis:       typeclass instances for password package
 description:    A library providing typeclass instances for common libraries for the types from the password package.
 homepage:       https://github.com/cdepillabout/password/password-instances#readme
 bug-reports:    https://github.com/cdepillabout/password/issues
-author:         Dennis Gosnell
-maintainer:     cdep.illabout@gmail.com
-copyright:      Copyright (c) 2019 Dennis Gosnell
+author:         Dennis Gosnell, Felix Paulusma
+maintainer:     cdep.illabout@gmail.com, felix.paulusma@gmail.com
+copyright:      Copyright (c) Dennis Gosnell, 2019; Felix Paulusma, 2020
 license:        BSD3
 license-file:   LICENSE
-build-type:     Simple
+build-type:     Custom
 extra-source-files:
-    README.md
+    README
     ChangeLog.md
 
 source-repository head
   type: git
   location: https://github.com/cdepillabout/password
 
+custom-setup
+  setup-depends:
+      base
+    , Cabal
+    , cabal-doctest  >=1.0.6 && <1.1
+
 library
   hs-source-dirs:
       src
@@ -29,17 +35,18 @@
   other-modules:
       Paths_password_instances
   build-depends:
-      base >=4.7 && <5
-    , aeson
+      base          >= 4.9 && < 5
+    , aeson         >= 0.2
     , http-api-data
-    , password
-    , persistent
+    , password      >= 2
+    , persistent    >= 1.2
+    , text
   ghc-options:
       -Wall
   default-language:
       Haskell2010
 
-test-suite password-instances-doctest
+test-suite doctests
   type:
       exitcode-stdio-1.0
   hs-source-dirs:
@@ -49,10 +56,13 @@
   ghc-options:
       -threaded -rtsopts -with-rtsopts=-N
   build-depends:
-      base >=4.7 && <5
+      base >=4.9 && <5
+    , base-compat
     , doctest
+    , password-instances
     , QuickCheck
     , quickcheck-instances
+    , template-haskell
   default-language:
       Haskell2010
 
@@ -66,7 +76,16 @@
   ghc-options:
       -threaded -rtsopts -with-rtsopts=-N
   build-depends:
-      base >=4.7 && <5
+      base >=4.9 && <5
     , password-instances
+    , password
+    , aeson
+    , http-api-data
+    , persistent
+    , quickcheck-instances
+    , tasty
+    , tasty-hunit
+    , tasty-quickcheck
+    , text
   default-language:
       Haskell2010
diff --git a/src/Data/Password/Instances.hs b/src/Data/Password/Instances.hs
--- a/src/Data/Password/Instances.hs
+++ b/src/Data/Password/Instances.hs
@@ -1,103 +1,114 @@
+{-# LANGUAGE DataKinds #-}
 {-# LANGUAGE DerivingStrategies #-}
 {-# LANGUAGE InstanceSigs #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE StandaloneDeriving #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 
 {-|
 Module      : Data.Password.Instances
-Copyright   : (c) Dennis Gosnell, 2019
+Copyright   : (c) Dennis Gosnell, 2019; Felix Paulusma, 2020
 License     : BSD-style (see LICENSE file)
 Maintainer  : cdep.illabout@gmail.com
 Stability   : experimental
 Portability : POSIX
 
-This module provides the same interface as "Data.Password", but it also
-provides additional typeclass instances for 'Pass' and 'PassHash'.
+This module provides additional typeclass instances
+for 'Password' and 'PasswordHash'.
 
 See the "Data.Password" module for more information.
 -}
 
-module Data.Password.Instances
-  (
-    -- * Plaintext Password
-    Pass
-  , mkPass
-    -- * Hashed Password
-  , PassHash(..)
-  , Salt(..)
-    -- * Functions for Hashing Plaintext Passwords
-  , hashPass
-  , hashPassWithSalt
-  , newSalt
-    -- * Functions for Checking Plaintext Passwords Against Hashed Passwords
-  , checkPass
-  , PassCheck(..)
-    -- * Unsafe Debugging Functions for Showing a Password
-  , unsafeShowPassword
-  , unsafeShowPasswordText
-  , -- * Setup for doctests.
-    -- $setup
-  ) where
+module Data.Password.Instances () where
 
-import Data.Aeson (FromJSON(..))
-import Data.Password
-import Database.Persist.Class (PersistField)
-import Database.Persist.Sql (PersistFieldSql)
-import Web.HttpApiData (FromHttpApiData(..))
+import Data.Aeson (FromJSON(..), ToJSON(..))
+import Data.Password (Password, PasswordHash(..), mkPassword)
+import Data.Text.Encoding as TE (decodeUtf8)
+import Database.Persist (PersistValue(..))
+import Database.Persist.Class (PersistField(..))
+import Database.Persist.Sql (PersistFieldSql(..))
+import GHC.TypeLits (TypeError, ErrorMessage(..))
+import Web.HttpApiData (FromHttpApiData(..), ToHttpApiData(..))
 
 
 -- $setup
 -- >>> :set -XOverloadedStrings
+-- >>> :set -XDataKinds
 --
 -- Import needed functions.
 --
 -- >>> import Data.Aeson (decode)
+-- >>> import Data.Password (Salt(..), unsafeShowPassword)
+-- >>> import Data.Password.Scrypt (defaultParams, hashPasswordWithSalt)
 -- >>> import Database.Persist.Class (PersistField(toPersistValue))
 -- >>> import Web.HttpApiData (parseUrlPiece)
 
--- | This instance allows a 'Pass' to be created from a JSON blob.
+-- | This instance allows a 'Password' to be created from a JSON blob.
 --
--- >>> let maybePass = decode "\"foobar\"" :: Maybe Pass
--- >>> fmap unsafeShowPassword maybePass
+-- >>> let maybePassword = decode "\"foobar\"" :: Maybe Password
+-- >>> fmap unsafeShowPassword maybePassword
 -- Just "foobar"
 --
--- There is no instance for 'ToJSON' for 'Pass' because we don't want to
--- accidentally encode a plain-text 'Pass' to JSON and send it to the end-user.
+-- There is no instance for 'ToJSON' for 'Password' because we don't want to
+-- accidentally encode a plain-text 'Password' to JSON and send it to the end-user.
 --
--- Similarly, there is no 'ToJSON' and 'FromJSON' instance for 'PassHash'
+-- Similarly, there is no 'ToJSON' and 'FromJSON' instance for 'PasswordHash'
 -- because we don't want to accidentally send the password hash to the end
 -- user.
-instance FromJSON Pass where
-  parseJSON = fmap mkPass . parseJSON
+instance FromJSON Password where
+  parseJSON = fmap mkPassword . parseJSON
 
--- | This instance allows a 'Pass' to be created with functions like
+type ErrMsg e = 'Text "Warning! Tried to convert plain-text Password to " ':<>: 'Text e ':<>: 'Text "!"
+          ':$$: 'Text "  This is likely a security leak. Please make sure whether this was intended."
+          ':$$: 'Text "  If this is intended, please use 'unsafeShowPassword' before converting to " ':<>: 'Text e
+          ':$$: 'Text ""
+
+-- | Type error! Do not use 'toJSON' on a 'Password'!
+instance TypeError (ErrMsg "JSON") => ToJSON Password where
+  toJSON = error "unreachable"
+
+-- | This instance allows a 'Password' to be created with functions like
 -- 'Web.HttpApiData.parseUrlPiece' or 'Web.HttpApiData.parseQueryParam'.
 --
--- >>> let eitherPass = parseUrlPiece "foobar"
--- >>> fmap unsafeShowPassword eitherPass
+-- >>> let eitherPassword = parseUrlPiece "foobar"
+-- >>> fmap unsafeShowPassword eitherPassword
 -- Right "foobar"
-instance FromHttpApiData Pass where
-  parseUrlPiece = fmap mkPass . parseUrlPiece
+instance FromHttpApiData Password where
+  parseUrlPiece = fmap mkPassword . parseUrlPiece
 
--- | This instance allows a 'PassHash' to be stored as a field in a database using
+-- | Type error! Do not transmit plain-text 'Password's over HTTP!
+instance TypeError (ErrMsg "HttpApiData") => ToHttpApiData Password where
+  toUrlPiece = error "unreachable"
+
+-- | This instance allows a 'PasswordHash' to be stored as a field in a database using
 -- "Database.Persist".
 --
 -- >>> let salt = Salt "abcdefghijklmnopqrstuvwxyz012345"
--- >>> let pass = mkPass "foobar"
--- >>> let hashedPassword = hashPassWithSalt salt pass
+-- >>> let pass = mkPassword "foobar"
+-- >>> let hashedPassword = hashPasswordWithSalt defaultParams salt pass
 -- >>> toPersistValue hashedPassword
 -- PersistText "14|8|1|YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU=|nENDaqWBmPKapAqQ3//H0iBImweGjoTqn5SvBS8Mc9FPFbzq6w65maYPZaO+SPamVZRXQjARQ8Y+5rhuDhjIhw=="
 --
 -- In the example above, the long 'PersistText' will be the value you store in
 -- the database.
 --
--- We don't provide an instance of 'PersistField' for 'Pass', because we don't
+-- We don't provide an instance of 'PersistField' for 'Password', because we don't
 -- want to make it easy to store a plain-text password in the database.
-deriving newtype instance PersistField PassHash
+instance PersistField (PasswordHash a) where
+  toPersistValue (PasswordHash hpw) = PersistText hpw
+  fromPersistValue (PersistText txt) = Right $ PasswordHash txt
+  fromPersistValue (PersistByteString bs) = Right $ PasswordHash $ TE.decodeUtf8 bs
+  fromPersistValue _ = Left "did not parse PasswordHash from PersistValue"
 
--- | This instance allows a 'PassHash' to be stored as a field in an SQL
+-- | This instance allows a 'PasswordHash' to be stored as a field in an SQL
 -- database in "Database.Persist.Sql".
-deriving newtype instance PersistFieldSql PassHash
+deriving newtype instance PersistFieldSql (PasswordHash a)
+
+-- | Type error! Do not store plain-text 'Password's in your database!
+instance TypeError (ErrMsg "PersistValue") => PersistField Password where
+  toPersistValue = error "unreachable"
+  fromPersistValue = error "unreachable"
diff --git a/test/doctest/doctest.hs b/test/doctest/doctest.hs
--- a/test/doctest/doctest.hs
+++ b/test/doctest/doctest.hs
@@ -1,7 +1,14 @@
-
-module Main (main) where
+module Main where
 
-import Test.DocTest
+import Build_doctests (flags, pkgs, module_sources)
+-- import Data.Foldable (traverse_)
+import System.Environment.Compat (unsetEnv)
+import Test.DocTest (doctest)
 
 main :: IO ()
-main = doctest ["src"]
+main = do
+  -- traverse_ putStrLn args
+  unsetEnv "GHC_ENVIRONMENT"
+  doctest args
+  where
+    args = flags ++ pkgs ++ module_sources
diff --git a/test/tasty/Spec.hs b/test/tasty/Spec.hs
--- a/test/tasty/Spec.hs
+++ b/test/tasty/Spec.hs
@@ -1,2 +1,55 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+import Data.Aeson
+import Data.Aeson.Types (parseMaybe)
+import Data.Text (Text)
+import Database.Persist.Class (PersistField(..))
+import Test.Tasty
+import Test.Tasty.HUnit
+import Test.Tasty.QuickCheck
+import Test.QuickCheck.Instances.Text ()
+import Web.HttpApiData (FromHttpApiData(..))
+
+import Data.Password (Password, PasswordHash(..), unsafeShowPassword)
+import Data.Password.Instances()
+
+
 main :: IO ()
-main = putStrLn "Test suite not yet implemented"
+main = defaultMain $ testGroup "Password Instances"
+  [ aesonTest
+  , fromHttpApiDataTest
+  , persistTest
+  ]
+
+data TestUser = TestUser {
+  name :: Text,
+  password :: Password
+} deriving (Show)
+
+instance FromJSON TestUser where
+  parseJSON = withObject "TestUser" $ \o ->
+    TestUser <$> o .: "name" <*> o .: "password"
+
+
+aesonTest :: TestTree
+aesonTest = testCase "Password (Aeson)" $
+    assertEqual "password doesn't match" (Just testPassword) $
+      unsafeShowPassword . password <$> parseMaybe parseJSON testUser
+  where
+    testPassword = "testpass"
+    testUser = object
+      [ "name" .= String "testname"
+      , "password" .= String testPassword
+      ]
+
+fromHttpApiDataTest :: TestTree
+fromHttpApiDataTest = testCase "Password (FromHttpApiData)" $
+    assertEqual "password doesn't match" (Right testPassword) $
+      unsafeShowPassword <$> parseUrlPiece testPassword
+  where
+    testPassword = "passtest"
+
+persistTest :: TestTree
+persistTest = testProperty "PasswordHash (PersistField)" $ \pass ->
+    let pwd = PasswordHash pass
+    in fromPersistValue (toPersistValue pwd) === Right pwd
