diff --git a/core-data.cabal b/core-data.cabal
--- a/core-data.cabal
+++ b/core-data.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           core-data
-version:        0.3.1.1
+version:        0.3.2.1
 synopsis:       Convenience wrappers around common data structures and encodings
 description:    Wrappers around common data structures and encodings.
                 .
diff --git a/lib/Core/Encoding/Json.hs b/lib/Core/Encoding/Json.hs
--- a/lib/Core/Encoding/Json.hs
+++ b/lib/Core/Encoding/Json.hs
@@ -99,6 +99,8 @@
 #else
 import qualified Data.HashMap.Strict as HashMap
 #endif
+
+import Data.Aeson (FromJSON, Value (String))
 import Data.Coerce
 import Data.Hashable (Hashable)
 import qualified Data.List as List
@@ -176,13 +178,26 @@
     closebracket = singletonRope ']'
 
 {- |
--- Escape any quotes in a JsonString.
+Escape any quotes or backslashes in a JsonString.
 -}
 escapeString :: Rope -> Rope
 escapeString text =
+    let text1 = escapeBackslashes text
+        text2 = escapeQuotes text1
+      in text2
+{-# INLINEABLE escapeString #-}
+
+escapeBackslashes :: Rope -> Rope
+escapeBackslashes text =
+     let pieces = breakPieces (== '\\') text
+     in mconcat (List.intersperse "\\\\" pieces)
+{-# INLINEABLE escapeBackslashes #-}
+
+escapeQuotes :: Rope -> Rope
+escapeQuotes text =
     let pieces = breakPieces (== '"') text
      in mconcat (List.intersperse "\\\"" pieces)
-{-# INLINEABLE escapeString #-}
+{-# INLINEABLE escapeQuotes #-}
 
 {- |
 Given an array of bytes, attempt to decode it as a JSON value.
@@ -413,3 +428,12 @@
         ds = fmap pretty ts
      in hcat (punctuate (annotate EscapeToken "\\\"") ds)
 {-# INLINEABLE escapeText #-}
+
+--
+-- Orphan instance; ideally we wouldn't need this anywhere but people are
+-- asking for it and the relevant symbols are imported here.
+--
+
+instance FromJSON Rope where
+    parseJSON (String text) = pure (intoRope text)
+    parseJSON _ = fail "Can't parse this non-textual field as a Rope"
