diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,11 @@
 
 See full history at: <https://github.com/faylang/fay/commits>
 
+### 0.23.2.0
+
+* GHC 8.2 support
+* Use traverse-with-class 1.0.*, and as a result drop support for GHC < 8.
+
 #### 0.23.1.16
 
 * Fix build on GHC 7.4
diff --git a/fay.cabal b/fay.cabal
--- a/fay.cabal
+++ b/fay.cabal
@@ -1,5 +1,5 @@
 name:                fay
-version:             0.23.1.16
+version:             0.23.2.0
 synopsis:            A compiler for Fay, a Haskell subset that compiles to JavaScript.
 description:         Fay is a proper subset of Haskell which is type-checked
                      with GHC, and compiled to JavaScript. It is lazy, pure, has a Fay monad,
@@ -133,38 +133,36 @@
     Language.Haskell.Names.SyntaxUtils
     Language.Haskell.Names.Types
     Paths_fay
-
   build-depends:
-      base >= 4.5 && < 4.10
+      base >= 4.9 && < 4.11
     , base-compat >= 0.8 && < 0.10
-    , aeson > 0.6 && < 1.1
+    , aeson > 0.6 && < 1.3
     , bytestring >= 0.9 && < 0.11
     , containers >= 0.4 && < 0.6
     , data-default >= 0.2 && < 0.8
     , data-lens-light == 0.1.*
-    , directory >= 1.1 && < 1.3
+    , directory >= 1.1 && < 1.4
     , filepath >= 1.3 && < 1.5
     , ghc-paths == 0.1.*
-    , haskell-src-exts >= 1.18.1 && < 1.19
+    , haskell-src-exts >= 1.18.1 && < 1.20
     , language-ecmascript >= 0.15 && < 0.18
     , mtl >= 2.1 && < 2.3
     , mtl-compat >= 0.1 && < 0.3
-    , process >= 1.1 && < 1.5
+    , process >= 1.1 && < 1.7
     , safe >= 0.2 && < 0.4
     , sourcemap == 0.1.*
     , split >= 0.1 && < 0.3
     , spoon >= 0.1 && < 0.4
-    , syb >= 0.3 && < 0.7
+    , syb >= 0.3 && < 0.8
     , text >= 0.11 && < 1.3
-    , time >= 1.4 && < 1.7
+    , time >= 1.4 && < 1.9
     , transformers >= 0.3 && < 0.4 || > 0.4.1 && < 0.7
     , transformers-compat >= 0.3 && < 0.6
-    , traverse-with-class >= 0.1 && < 0.3
-    , type-eq >= 0.1 && < 0.6
+    , traverse-with-class >= 1.0 && < 1.1
     , uniplate >= 1.6.11 && < 1.7
     , unordered-containers == 0.2.*
     , utf8-string >= 0.1 && < 1.1
-    , vector < 0.12
+    , vector < 0.13
 
   if impl(ghc < 7.8)
     build-depends: tagged
@@ -177,9 +175,10 @@
       base
     , fay
     , mtl
-    , optparse-applicative >= 0.11 && < 0.14
+    , optparse-applicative >= 0.11 && < 0.15
     , split
-
+  other-modules:
+    Paths_fay
 executable fay-tests
   ghc-options:       -O2 -Wall -threaded -with-rtsopts=-N
   hs-source-dirs:    src/tests
@@ -191,6 +190,7 @@
       Test.Convert
       Test.Desugar
       Test.Util
+      Paths_fay
     build-depends:
         base
       , aeson
@@ -203,7 +203,7 @@
       , haskell-src-exts
       , random >= 1.0 && < 1.2
       , tasty >= 0.9 && < 0.12
-      , tasty-hunit >= 0.8 && < 0.10
+      , tasty-hunit >= 0.8 && < 0.11
       , tasty-th == 0.1.*
       , text
       , utf8-string
diff --git a/src/Fay/Compiler/Desugar.hs b/src/Fay/Compiler/Desugar.hs
--- a/src/Fay/Compiler/Desugar.hs
+++ b/src/Fay/Compiler/Desugar.hs
@@ -2,6 +2,8 @@
 {-# LANGUAGE FlexibleContexts      #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE NoImplicitPrelude     #-}
+{-# LANGUAGE MonoLocalBinds        #-}
+
 module Fay.Compiler.Desugar
   ( desugar
   , desugar'
diff --git a/src/Fay/Compiler/Print.hs b/src/Fay/Compiler/Print.hs
--- a/src/Fay/Compiler/Print.hs
+++ b/src/Fay/Compiler/Print.hs
@@ -13,7 +13,7 @@
 import           Fay.Compiler.PrimOp
 import           Fay.Types
 
-import           Data.Aeson.Encode
+import           Data.Aeson
 import qualified Data.ByteString.Lazy.UTF8       as UTF8
 import           Language.Haskell.Exts hiding (alt, name, op, sym)
 
diff --git a/src/haskell-names/Language/Haskell/Names/Annotated.hs b/src/haskell-names/Language/Haskell/Names/Annotated.hs
--- a/src/haskell-names/Language/Haskell/Names/Annotated.hs
+++ b/src/haskell-names/Language/Haskell/Names/Annotated.hs
@@ -6,7 +6,6 @@
 {-# LANGUAGE GADTs                 #-}
 {-# LANGUAGE ImplicitParams        #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE OverlappingInstances  #-}
 {-# LANGUAGE PatternGuards         #-}
 {-# LANGUAGE ScopedTypeVariables   #-}
 {-# LANGUAGE TypeOperators         #-}
@@ -28,7 +27,7 @@
 import           Data.Lens.Light
 import           Data.Proxy
 import           Language.Haskell.Exts
-import           Type.Eq
+import           Data.Typeable ( eqT, (:~:)(Refl) )
 
 annotate
   :: forall a l .
@@ -44,18 +43,18 @@
   go :: forall a . Resolvable a => Scope -> a -> a
   go sc a
     | ReferenceV <- getL nameCtx sc
-    , Just (Eq :: QName (Scoped l) :~: a) <- dynamicEq
+    , Just (Refl :: QName (Scoped l) :~: a) <- eqT
       = lookupValue (fmap sLoc a) sc <$ a
     | ReferenceT <- getL nameCtx sc
-    , Just (Eq :: QName (Scoped l) :~: a) <- dynamicEq
+    , Just (Refl :: QName (Scoped l) :~: a) <- eqT
       = lookupType (fmap sLoc a) sc <$ a
     | BindingV <- getL nameCtx sc
-    , Just (Eq :: Name (Scoped l) :~: a) <- dynamicEq
+    , Just (Refl :: Name (Scoped l) :~: a) <- eqT
       = Scoped ValueBinder (sLoc . ann $ a) <$ a
     | BindingT <- getL nameCtx sc
-    , Just (Eq :: Name (Scoped l) :~: a) <- dynamicEq
+    , Just (Refl :: Name (Scoped l) :~: a) <- eqT
       = Scoped TypeBinder (sLoc . ann $ a) <$ a
-    | Just (Eq :: FieldUpdate (Scoped l) :~: a) <- dynamicEq
+    | Just (Refl :: FieldUpdate (Scoped l) :~: a) <- eqT
       = case a of
           FieldPun l n -> FieldPun l (lookupValue (sLoc <$> n) sc <$ n)
           FieldWildcard l ->
@@ -70,7 +69,7 @@
                   namesUnres
             in FieldWildcard $ Scoped (RecExpWildcard namesRes) (sLoc l)
           _ -> rmap go sc a
-    | Just (Eq :: PatField (Scoped l) :~: a) <- dynamicEq
+    | Just (Refl :: PatField (Scoped l) :~: a) <- eqT
     , PFieldWildcard l <- a
       = PFieldWildcard $
           Scoped
diff --git a/src/haskell-names/Language/Haskell/Names/GlobalSymbolTable.hs-boot b/src/haskell-names/Language/Haskell/Names/GlobalSymbolTable.hs-boot
--- a/src/haskell-names/Language/Haskell/Names/GlobalSymbolTable.hs-boot
+++ b/src/haskell-names/Language/Haskell/Names/GlobalSymbolTable.hs-boot
@@ -2,9 +2,9 @@
 
 import Data.Data
 
-data Table
+data Table deriving Typeable
 instance Eq   Table
 instance Ord  Table
 instance Show Table
 instance Data Table
-instance Typeable Table
+
diff --git a/src/haskell-names/Language/Haskell/Names/Open/Base.hs b/src/haskell-names/Language/Haskell/Names/Open/Base.hs
--- a/src/haskell-names/Language/Haskell/Names/Open/Base.hs
+++ b/src/haskell-names/Language/Haskell/Names/Open/Base.hs
@@ -12,11 +12,13 @@
 {-# LANGUAGE KindSignatures        #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE NoImplicitPrelude     #-}
-{-# LANGUAGE OverlappingInstances  #-}
 {-# LANGUAGE RankNTypes            #-}
 {-# LANGUAGE ScopedTypeVariables   #-}
 {-# LANGUAGE TemplateHaskell       #-}
 {-# LANGUAGE UndecidableInstances  #-}
+{-# LANGUAGE TypeApplications      #-}
+{-# LANGUAGE MonoLocalBinds        #-}
+
 module Language.Haskell.Names.Open.Base
   ( Resolvable (..)
   , intro
@@ -95,7 +97,7 @@
   => a -> Scope -> f a
 defaultRtraverse a sc =
   let ?c = ConstraintProxy :: ConstraintProxy Resolvable
-  in gtraverse (\a -> alg a sc) a
+  in gtraverse @Resolvable (\a -> alg a sc) a
 
 -- | A type that implements 'Resolvable' provides a way to perform
 -- a shallow scope-aware traversal.
diff --git a/src/haskell-names/Language/Haskell/Names/Open/Instances.hs b/src/haskell-names/Language/Haskell/Names/Open/Instances.hs
--- a/src/haskell-names/Language/Haskell/Names/Open/Instances.hs
+++ b/src/haskell-names/Language/Haskell/Names/Open/Instances.hs
@@ -37,7 +37,7 @@
 sc -: b = (b, sc)
 infix 5 -:
 
-instance (Resolvable l, SrcInfo l, Data l) => Resolvable (Decl l) where
+instance {-# OVERLAPPING #-} (Resolvable l, SrcInfo l, Data l) => Resolvable (Decl l) where
   rtraverse e sc =
     case e of
       -- N.B. We do not add pat to the local scope.
@@ -65,10 +65,10 @@
           <| sc       -: ty
       _ -> defaultRtraverse e sc
 
-instance (Resolvable l, SrcInfo l, Data l) => Resolvable (Type l) where
+instance {-# OVERLAPPING #-} (Resolvable l, SrcInfo l, Data l) => Resolvable (Type l) where
   rtraverse e sc = defaultRtraverse e (exprT sc)
 
-instance (Resolvable l, SrcInfo l, Data l) => Resolvable (DeclHead l) where
+instance {-# OVERLAPPING #-} (Resolvable l, SrcInfo l, Data l) => Resolvable (DeclHead l) where
   rtraverse e sc =
     case e of
       DHead l name ->
@@ -82,7 +82,7 @@
           <| binderT sc -: name
       _ -> defaultRtraverse e sc
 
-instance (Resolvable l, SrcInfo l, Data l) => Resolvable (ConDecl l) where
+instance {-# OVERLAPPING #-} (Resolvable l, SrcInfo l, Data l) => Resolvable (ConDecl l) where
   rtraverse e sc =
     case e of
       ConDecl l name tys ->
@@ -103,7 +103,7 @@
           <| sc -: fields
 
 
-instance (Resolvable l, SrcInfo l, Data l) => Resolvable (FieldDecl l) where
+instance {-# OVERLAPPING #-} (Resolvable l, SrcInfo l, Data l) => Resolvable (FieldDecl l) where
   rtraverse e sc =
     case e of
       FieldDecl l name tys ->
@@ -112,7 +112,7 @@
           <| binderV sc -: name
           <| sc -: tys
 
-instance (Resolvable l, SrcInfo l, Data l) => Resolvable (Pat l) where
+instance {-# OVERLAPPING #-} (Resolvable l, SrcInfo l, Data l) => Resolvable (Pat l) where
   rtraverse e sc =
     case e of
       PVar l name ->
@@ -156,7 +156,7 @@
           <| sc       -: pat
       _ -> defaultRtraverse e sc
 
-instance (Resolvable l, SrcInfo l, Data l) => Resolvable (PatField l) where
+instance {-# OVERLAPPING #-} (Resolvable l, SrcInfo l, Data l) => Resolvable (PatField l) where
   rtraverse e sc =
     case e of
       PFieldPat l qn pat ->
@@ -193,7 +193,7 @@
         (ps', sc'') = chain ps sc'
       in ((:) <$> p' <*> ps', sc'')
 
-instance (Resolvable l, SrcInfo l, Data l) => Resolvable (Match l) where
+instance {-# OVERLAPPING #-} (Resolvable l, SrcInfo l, Data l) => Resolvable (Match l) where
   rtraverse e sc =
     case e of
       Match l name pats rhs mbWhere ->
@@ -219,7 +219,7 @@
 
 -- NB: there is an inefficiency here (and in similar places), because we
 -- call intro on the same subtree several times. Maybe tackle it later.
-instance (Resolvable l, SrcInfo l, Data l) => Resolvable (Binds l) where
+instance {-# OVERLAPPING #-} (Resolvable l, SrcInfo l, Data l) => Resolvable (Binds l) where
   rtraverse e sc =
     case e of
       BDecls l decls ->
@@ -230,7 +230,7 @@
           <| scWithBinds -: decls
       _ -> defaultRtraverse e sc
 
-instance (Resolvable l, SrcInfo l, Data l) => Resolvable (Exp l) where
+instance {-# OVERLAPPING #-} (Resolvable l, SrcInfo l, Data l) => Resolvable (Exp l) where
   rtraverse e sc =
     case e of
       Let l bnds body ->
@@ -294,7 +294,7 @@
 
       _ -> defaultRtraverse e sc
 
-instance (Resolvable l, SrcInfo l, Data l) => Resolvable (Alt l) where
+instance {-# OVERLAPPING #-} (Resolvable l, SrcInfo l, Data l) => Resolvable (Alt l) where
   rtraverse e sc =
     case e of
       Alt l pat guardedAlts mbWhere ->
@@ -308,7 +308,7 @@
           <| scWithBinds -: guardedAlts
           <| scWithBinds -: mbWhere
 
-instance (Resolvable l, SrcInfo l, Data l) => Resolvable (GuardedRhs l) where
+instance {-# OVERLAPPING #-} (Resolvable l, SrcInfo l, Data l) => Resolvable (GuardedRhs l) where
   rtraverse e sc =
     case e of
       GuardedRhs l stmts exp ->
@@ -319,11 +319,11 @@
           <*> stmts'
           <|  scWithStmts -: exp
 
-instance (Resolvable l, SrcInfo l, Data l) => Resolvable [Stmt l] where
+instance {-# OVERLAPPING #-} (Resolvable l, SrcInfo l, Data l) => Resolvable [Stmt l] where
   rtraverse e sc =
     fst $ chain e sc
 
-instance (Resolvable l, SrcInfo l, Data l) => Resolvable (QualStmt l) where
+instance {-# OVERLAPPING #-} (Resolvable l, SrcInfo l, Data l) => Resolvable (QualStmt l) where
   rtraverse e sc =
     case e of
       QualStmt {} -> defaultRtraverse e sc
@@ -351,9 +351,11 @@
 -}
 
 -- Some road-block Resolvable instances
-instance Typeable a => Resolvable (Scoped a) where
+instance {-# OVERLAPPING #-} Typeable a => Resolvable (Scoped a) where
   rtraverse = flip $ const pure
-instance Resolvable SrcSpan where
+instance {-# OVERLAPPING #-} Resolvable SrcSpan where
   rtraverse = flip $ const pure
-instance Resolvable SrcSpanInfo where
+instance {-# OVERLAPPING #-} Resolvable SrcSpanInfo where
   rtraverse = flip $ const pure
+
+
diff --git a/src/tests/Test/CommandLine.hs b/src/tests/Test/CommandLine.hs
--- a/src/tests/Test/CommandLine.hs
+++ b/src/tests/Test/CommandLine.hs
@@ -39,4 +39,6 @@
   whatAGreatFramework <- fmap (lookup "HASKELL_PACKAGE_SANDBOX") getEnvironment
   res <- compileFile (["--include=tests", "tests/RecordImport_Import.hs","--no-ghc"] ++
                       ["--package-conf=" ++ packageConf | Just packageConf <- [whatAGreatFramework] ])
-  assertBool (fromLeft res) (isRight res)
+  case res of
+    Left  e -> assertFailure $ "Compilation failed: " ++ e
+    Right _ -> assertBool "impossible" True
diff --git a/src/tests/Test/Util.hs b/src/tests/Test/Util.hs
--- a/src/tests/Test/Util.hs
+++ b/src/tests/Test/Util.hs
@@ -2,8 +2,6 @@
 {-# LANGUAGE NoImplicitPrelude #-}
 module Test.Util
   ( fayPath
-  , isRight
-  , fromLeft
   , getRecursiveContents
   ) where
 
@@ -32,10 +30,6 @@
 hush :: Either a b -> Maybe b
 hush = either (const Nothing) Just
 
-fromLeft :: Either a b -> a
-fromLeft (Left a) = a
-fromLeft (Right _) = error "fromLeft got Right"
-
 -- | Get all files in a folder and its subdirectories.
 -- Taken from Real World Haskell
 -- http://book.realworldhaskell.org/read/io-case-study-a-library-for-searching-the-filesystem.html
@@ -50,9 +44,3 @@
       then getRecursiveContents path
       else return [path]
   return (concat paths)
-
-#if !MIN_VERSION_base(4,7,0)
-isRight :: Either a b -> Bool
-isRight Right{} = True
-isRight Left{} = False
-#endif
