diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,9 @@
 # Revision history for avro
 
+## HEAD
+
+- Replace `entropy` library with `tf-random`, which is easier to use with ghcjs
+
 ## 0.4.1.1
 
 - Fixed bugs in handling of namespaces when parsing and printing avro types
diff --git a/avro.cabal b/avro.cabal
--- a/avro.cabal
+++ b/avro.cabal
@@ -4,15 +4,15 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 0368e22fa6552aa4d9b3ada7a95e8210af8b40090f3244fe99d68ca30f606e8d
+-- hash: ca29cdadb7a7a9edda357686a62ea84b9122a6bedb7fe04890a5d1fcc8719127
 
 name:           avro
-version:        0.4.1.1
+version:        0.4.1.2
 synopsis:       Avro serialization support for Haskell
 description:    Avro serialization and deserialization support for Haskell
 category:       Data
-homepage:       https://github.com/GaloisInc/avro#readme
-bug-reports:    https://github.com/GaloisInc/avro/issues
+homepage:       https://github.com/haskell-works/avro#readme
+bug-reports:    https://github.com/haskell-works/avro/issues
 author:         Thomas M. DuBuisson
 maintainer:     Alexey Raga <alexey.raga@gmail.com>
 license:        BSD3
@@ -29,6 +29,7 @@
     test/data/record.avsc
     test/data/reused.avsc
     test/data/small.avsc
+    test/data/unions-no-namespace.avsc
     test/data/unions.avsc
     test/data/enums-object.json
     test/data/namespace-inference.json
@@ -42,7 +43,7 @@
 
 source-repository head
   type: git
-  location: https://github.com/GaloisInc/avro
+  location: https://github.com/haskell-works/avro
 
 flag dev
   description: Use development GHC flags
@@ -98,7 +99,6 @@
     , bytestring
     , containers
     , data-binary-ieee754
-    , entropy
     , fail
     , hashable
     , mtl
@@ -107,6 +107,7 @@
     , semigroups
     , tagged
     , text
+    , tf-random
     , unordered-containers
     , vector
   if flag(templatehaskell)
@@ -169,7 +170,6 @@
     , bytestring
     , containers
     , directory
-    , entropy
     , extra
     , fail
     , hashable
@@ -182,6 +182,7 @@
     , semigroups
     , tagged
     , text
+    , tf-random
     , transformers
     , unordered-containers
     , vector
diff --git a/src/Data/Avro/Encode.hs b/src/Data/Avro/Encode.hs
--- a/src/Data/Avro/Encode.hs
+++ b/src/Data/Avro/Encode.hs
@@ -52,8 +52,9 @@
 import qualified Data.Vector                as V
 import qualified Data.Vector.Unboxed        as U
 import           Data.Word
+import           System.Random.TF.Init      (initTFGen)
+import           System.Random.TF.Instances (randoms)
 import           Prelude                    as P
-import           System.Entropy             (getEntropy)
 
 import Data.Avro.EncodeRaw
 import Data.Avro.HasAvroSchema
@@ -67,7 +68,7 @@
 
 -- | Generates a new synchronization marker for encoding Avro containers
 newSyncBytes :: IO BL.ByteString
-newSyncBytes = BL.fromStrict <$> getEntropy 16
+newSyncBytes = BL.pack . DL.take 16 . randoms <$> initTFGen
 
 -- |Encode chunks of objects into a container, using 16 random bytes for
 -- the synchronization markers.
diff --git a/src/Data/Avro/JSON.hs b/src/Data/Avro/JSON.hs
--- a/src/Data/Avro/JSON.hs
+++ b/src/Data/Avro/JSON.hs
@@ -96,11 +96,14 @@
           fail "Invalid encoding of union: object with too many fields."
       | otherwise      =
           let
+            canonicalize name
+              | Just _ <- Schema.primitiveType name = name
+              | otherwise = Schema.renderFullname $ Schema.parseFullname name
             branch =
-              head (HashMap.keys obj)
+              head $ HashMap.keys obj
             names =
               HashMap.fromList [(Schema.typeName t, t) | t <- NE.toList schemas]
-          in case HashMap.lookup branch names of
+          in case HashMap.lookup (canonicalize branch) names of
             Just t  -> do
               nested <- parseAvroJSON union env t (obj ! branch)
               return (Avro.Union schemas t nested)
diff --git a/src/Data/Avro/Schema.hs b/src/Data/Avro/Schema.hs
--- a/src/Data/Avro/Schema.hs
+++ b/src/Data/Avro/Schema.hs
@@ -22,10 +22,12 @@
   , Field(..), Order(..)
   , TypeName(..)
   , renderFullname
+  , parseFullname
   , mkEnum, mkUnion
   , validateSchema
   -- * Lower level utilities
   , typeName
+  , primitiveType
   , buildTypeEnvironment
   , extractBindings
 
@@ -294,6 +296,27 @@
     NamedType name -> renderFullname name
     Union (x:|_) _ -> typeName x
     _              -> renderFullname $ name bt
+
+-- | If the given string is the name of a primitive type, return the
+-- type, otherwise return 'Nothing'.
+--
+-- @
+-- λ> primitiveType "string"
+-- Just String
+-- λ> primitiveType "foo"
+-- Nothing
+-- @
+primitiveType :: Text -> Maybe Type
+primitiveType = \case
+  "null"    -> Just Null
+  "boolean" -> Just Boolean
+  "int"     -> Just Int
+  "long"    -> Just Long
+  "float"   -> Just Float
+  "double"  -> Just Double
+  "bytes"   -> Just Bytes
+  "string"  -> Just String
+  _         -> Nothing
 
 data Field = Field { fldName    :: Text
                    , fldAliases :: [Text]
diff --git a/test/Avro/JSONSpec.hs b/test/Avro/JSONSpec.hs
--- a/test/Avro/JSONSpec.hs
+++ b/test/Avro/JSONSpec.hs
@@ -24,6 +24,7 @@
 deriveAvro "test/data/reused.avsc"
 deriveAvro "test/data/small.avsc"
 deriveAvro "test/data/unions.avsc"
+deriveAvro "test/data/unions-no-namespace.avsc"
 
 spec :: Spec
 spec = describe "Avro.JSONSpec: JSON serialization/parsing" $ do
@@ -95,6 +96,20 @@
   it "should parse (unions)" $ do
     parseJSON unionsJsonA `shouldBe` pure unionsExampleA
     parseJSON unionsJsonB `shouldBe` pure unionsExampleB
+
+  let unionsNoNamespaceA = UnionsNoNamespace (Left TypeA)
+      unionsNoNamespaceB = UnionsNoNamespace (Right TypeB)
+  it "should roundtrip (unions-no-namespace)" $ do
+    parseJSON (Aeson.encode (toJSON unionsNoNamespaceA)) `shouldBe`
+      pure unionsNoNamespaceA
+    parseJSON (Aeson.encode (toJSON unionsNoNamespaceB)) `shouldBe`
+      pure unionsNoNamespaceB
+  let noNamespace = "test/data/unions-no-namespace-object.json"
+      objectA = "{ \"unionField\" : { \"TypeA\" : {} } }"
+      objectB = "{ \"unionField\" : { \"TypeB\" : {} } }"
+  it "should parse (unions-no-namespace)" $ do
+    parseJSON objectA `shouldBe` pure unionsNoNamespaceA
+    parseJSON objectB `shouldBe` pure unionsNoNamespaceB
 
 getFileName :: FilePath -> IO FilePath
 getFileName p = do
diff --git a/test/data/unions-no-namespace.avsc b/test/data/unions-no-namespace.avsc
new file mode 100644
--- /dev/null
+++ b/test/data/unions-no-namespace.avsc
@@ -0,0 +1,24 @@
+{
+  "type" : "record",
+  "name" : "UnionsNoNamespace",
+  "doc" : "An example schema that has a union whose components are types with no namespace. This was causing problems with our JSON parsing code.",
+  "fields" : [
+    {
+      "name" : "unionField",
+      "type" : [
+        {
+          "type" : "record",
+          "name" : "TypeA",
+          "doc" : "TypeA is in the null namespace but has no leading dot in the schema.",
+          "fields" : []
+        },
+        {
+          "type" : "record",
+          "name" : ".TypeB",
+          "doc" : "Note the leading dot—semantically this is the same as having no namespace, but it caused parsing issues in the past.",
+          "fields" : []
+        }
+      ]
+    }
+  ]
+}
