diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+# 0.3.8
+
+- Re-implement `withNumber`
+- Add `withEmbeddedJSON`
+
 # 0.3.7
 
 - Use `attoparsec-iso8601` time parsers.
diff --git a/aeson-compat.cabal b/aeson-compat.cabal
--- a/aeson-compat.cabal
+++ b/aeson-compat.cabal
@@ -1,5 +1,5 @@
 name:           aeson-compat
-version:        0.3.7.1
+version:        0.3.8
 synopsis:       Compatibility layer for aeson
 description:    Compatibility layer for @aeson@
 category:       Web
@@ -16,7 +16,8 @@
   GHC==7.8.4,
   GHC==7.10.3,
   GHC==8.0.2,
-  GHC==8.2.1
+  GHC==8.2.2,
+  GHC==8.4.3
 
 extra-source-files:
     CHANGELOG.md
@@ -31,14 +32,14 @@
       src
   ghc-options: -Wall
   build-depends:
-      base                     >=4.6  && <4.11
-    , base-compat              >=0.6.0 && <0.10
-    , aeson                    >=0.7.0.6 && <1.3
+      base                     >=4.6  && <4.12
+    , base-compat              >=0.6.0 && <0.11
+    , aeson                    >=0.7.0.6 && <1.5
     , attoparsec               >=0.12 && <0.14
     , attoparsec-iso8601       >=1.0.0.0 && <1.1
     , bytestring               >=0.10 && <0.11
     , containers               >=0.5  && <0.6
-    , exceptions               >=0.8  && <0.9
+    , exceptions               >=0.8  && <0.11
     , hashable                 >=1.2  && <1.3
     , scientific               >=0.3  && <0.4
     , text                     >=1.2  && <1.3
@@ -82,11 +83,11 @@
     , vector
     , tagged
     , aeson-compat
-    , base-orphans          >=0.4.5 && <0.7
-    , tasty                 >=0.10 && <0.12
-    , tasty-hunit           >=0.9  && <0.10
-    , tasty-quickcheck      >=0.8  && <0.10
-    , QuickCheck            >=2.10 && <2.11
+    , base-orphans          >=0.4.5 && <0.8
+    , tasty                 >=0.10 && <1.2
+    , tasty-hunit           >=0.9  && <0.11
+    , tasty-quickcheck      >=0.8  && <0.11
+    , QuickCheck            >=2.10 && <2.12
     , quickcheck-instances  >=0.3.16  && <0.4
 
   if !impl(ghc >= 8.0)
diff --git a/src/Data/Aeson/Compat.hs b/src/Data/Aeson/Compat.hs
--- a/src/Data/Aeson/Compat.hs
+++ b/src/Data/Aeson/Compat.hs
@@ -74,6 +74,7 @@
     withNumber,
     withScientific,
     withBool,
+    withEmbeddedJSON,
     -- * Constructors and accessors
 #if MIN_VERSION_aeson(0,10,0)
     Series,
@@ -101,6 +102,9 @@
 #if !MIN_VERSION_aeson (0,9,0)
   , eitherDecode, eitherDecode', eitherDecodeStrict, eitherDecodeStrict'
 #endif
+#if !MIN_VERSION_aeson (1,4,0)
+  , withNumber
+#endif
   )
 
 import           Data.Aeson.Parser (value, value')
@@ -112,12 +116,13 @@
 #endif
 
 import           Control.Monad.Catch (MonadThrow (..), Exception)
-import           Data.Aeson.Types hiding ((.:?))
+import           Data.Aeson.Types (Parser, modifyFailure, typeMismatch, defaultOptions)
 import           Data.ByteString as B
 import qualified Data.Scientific as Scientific
 import           Data.ByteString.Lazy as L
 import qualified Data.HashMap.Strict as H
 import           Data.Text as T
+import qualified Data.Text.Encoding as TE
 import           Data.Typeable (Typeable)
 
 #if !MIN_VERSION_aeson(0,10,0)
@@ -146,6 +151,8 @@
 import qualified Data.Vector        as V
 #endif
 
+import Data.Attoparsec.Number (Number (..))
+
 -- | Exception thrown by 'decode' - family of functions in this module.
 newtype AesonException = AesonException String
   deriving (Show, Typeable)
@@ -421,4 +428,33 @@
       where
         ne []     = fail "Expected a NonEmpty but got an empty list"
         ne (x:xs) = pure (x :| xs)
+#endif
+
+-------------------------------------------------------------------------------
+-- with*
+-------------------------------------------------------------------------------
+
+-- | @'withNumber' expected f value@ applies @f@ to the 'Number' when @value@
+-- is a 'Number' and fails using @'typeMismatch' expected@ otherwise.
+withNumber :: String -> (Number -> Parser a) -> Value -> Parser a
+withNumber expected f = withScientific expected (f . scientificToNumber)
+{-# INLINE withNumber #-}
+{-# DEPRECATED withNumber "Use withScientific instead" #-}
+
+scientificToNumber :: Scientific.Scientific -> Number
+scientificToNumber s
+    | e < 0 || e > 1024 = D $ Scientific.toRealFloat s
+    | otherwise         = I $ c * 10 ^ e
+  where
+    e = Scientific.base10Exponent s
+    c = Scientific.coefficient s
+{-# INLINE scientificToNumber #-}
+
+#if !MIN_VERSION_aeson(1,2,3)
+-- | Decode a nested JSON-encoded string.
+withEmbeddedJSON :: String -> (Value -> Parser a) -> Value -> Parser a
+withEmbeddedJSON _ innerParser (String txt) =
+    either fail innerParser $ eitherDecode (L.fromStrict $ TE.encodeUtf8 txt)
+withEmbeddedJSON name _ v = typeMismatch name v
+{-# INLINE withEmbeddedJSON #-}
 #endif
