diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -5,17 +5,37 @@
 `/dev/urandom`. Hardware RNGs (currently RDRAND, patches welcome) are supported
 via the `hardwareRNG` function.
 
-If you wish to obtain an XOR of the hardware and system RNG consider:
+## Quick Start
 
+To simply get random bytes use `getEntropy`:
+
 ```
-import           Data.Bits (xor)
+#!/usr/bin/env cabal
+{- cabal:
+    build-depends: base, entropy, bytestring
+-}
+import qualified Data.ByteString as BS
+import           System.Entropy
+
+main :: IO ()
+main = print . BS.unpack =<< getEntropy 16
+-- Example output: [241,191,215,193,225,27,121,244,16,155,252,41,131,38,6,100]
+```
+
+## Faster Randoms from Hardware
+
+Most x86 systems include a hardware random number generator.  These can be
+faster but require more trust in the platform:
+
+```
 import qualified Data.ByteString as B
-import qualified Control.Exception as X
+import           System.Entropy
 
-xorRNG sz = do hw  <- hardwareRNG sz
-               h   <- openHandle
-               sys <- hGetEntropy h `X.finally` closeHandle h
-               pure $ B.pack $ B.zipWith xor hw sys
+eitherRNG :: Int -> IO B.ByteString
+eitherRNG sz = maybe (getEntropy sz) pure =<< getHardwareEntropy sz
+
+main :: IO ()
+main = print . B.unpack =<< eitherRNG 32
 ```
 
 This package supports Windows, {li,u}nix, QNX, and has preliminary support for HaLVM.
diff --git a/System/Entropy.hs b/System/Entropy.hs
--- a/System/Entropy.hs
+++ b/System/Entropy.hs
@@ -12,6 +12,7 @@
     - *nix systems via @\/dev\/urandom@
        - Includes QNX
     - Xen (only when RDRAND is available)
+    - ghcjs/browser via JavaScript crypto API.
 -}
 
 module System.Entropy
@@ -22,21 +23,22 @@
           hGetEntropy,
           closeHandle
         ) where
-#if defined(isWindows)
+
+#ifdef ghcjs_HOST_OS
+import System.EntropyGhcjs
+#elif defined(isWindows)
 import System.EntropyWindows
-#else
-#ifdef XEN
+#elif XEN
 import System.EntropyXen
 #else
 import System.EntropyNix
 #endif
-#endif
 
 import qualified Data.ByteString as B
 import Control.Exception (bracket)
 
 -- |Get a specific number of bytes of cryptographically
--- secure random data using the *system-specific* sources. 
+-- secure random data using the *system-specific* sources.
 -- (As of 0.4.  Verions <0.4 mixed system and hardware sources)
 --
 -- The returned random value is considered cryptographically secure but not true entropy.
diff --git a/System/EntropyGhcjs.hs b/System/EntropyGhcjs.hs
new file mode 100644
--- /dev/null
+++ b/System/EntropyGhcjs.hs
@@ -0,0 +1,51 @@
+{-|
+ Maintainer: Thomas.DuBuisson@gmail.com
+ Stability: beta
+ Portability: portable
+
+ Obtain entropy from system sources or x86 RDRAND when available.
+
+-}
+
+module System.EntropyGhcjs
+        ( CryptHandle
+        , openHandle
+        , hGetEntropy
+        , closeHandle
+        , hardwareRandom
+        ) where
+
+import Data.ByteString as B
+import GHCJS.DOM.Crypto as Crypto
+import GHCJS.DOM.Types (ArrayBufferView (..), fromJSValUnchecked)
+import GHCJS.DOM.GlobalCrypto (getCrypto)
+import GHCJS.DOM (currentWindowUnchecked)
+import Language.Javascript.JSaddle.Object as JS
+
+
+-- |Handle for manual resource management
+newtype CryptHandle = CH Crypto
+
+-- | Get random values from the hardward RNG or return Nothing if no
+-- supported hardware RNG is available.
+--
+-- Not supported on ghcjs.
+hardwareRandom :: Int -> IO (Maybe B.ByteString)
+hardwareRandom _ = pure Nothing
+
+-- |Open a `CryptHandle`
+openHandle :: IO CryptHandle
+openHandle = do
+  w <- currentWindowUnchecked
+  CH <$> getCrypto w
+
+-- |Close the `CryptHandle`
+closeHandle :: CryptHandle -> IO ()
+closeHandle _ = pure ()
+
+-- |Read random data from a `CryptHandle`
+hGetEntropy :: CryptHandle -> Int -> IO B.ByteString
+hGetEntropy (CH h) n = do
+  arr <- JS.new (jsg "Int8Array") [n]
+  getRandomValues_ h (ArrayBufferView arr)
+  B.pack <$> fromJSValUnchecked arr
diff --git a/entropy.cabal b/entropy.cabal
--- a/entropy.cabal
+++ b/entropy.cabal
@@ -1,6 +1,6 @@
 name:           entropy
-version:        0.4.1.4
-description:    A mostly platform independent (not GHCJS) method to obtain cryptographically strong entropy
+version:        0.4.1.5
+description:    A mostly platform independent method to obtain cryptographically strong entropy
                 (RDRAND, urandom, CryptAPI, and patches welcome)
                 Users looking for cryptographically strong (number-theoretically
                 sound) PRNGs should see the 'DRBG' package too.
@@ -14,9 +14,11 @@
 homepage:       https://github.com/TomMD/entropy
 bug-reports:    https://github.com/TomMD/entropy/issues
 stability:      stable
+
 -- build-type:  Simple
 -- ^^ Used for HaLVM
 build-type:     Custom
+
 -- ^^ Test for RDRAND support using 'ghc'
 cabal-version:  >=1.10
 tested-with:    GHC == 8.2.2
@@ -32,7 +34,7 @@
 
 
 custom-setup
-  setup-depends: Cabal >= 1.10 && < 2.5
+  setup-depends: Cabal >= 1.10 && < 3.1
                , base < 5
                , filepath < 1.5
                , directory < 1.4
@@ -41,38 +43,51 @@
 library
   ghc-options:  -O2
   exposed-modules: System.Entropy
-  if os(windows)
-    other-modules: System.EntropyWindows
+  if impl(ghcjs)
+    other-modules: System.EntropyGhcjs
   else {
-       if os(halvm)
-         other-modules: System.EntropyXen
-       else
-         other-modules: System.EntropyNix
+    if os(windows)
+      other-modules: System.EntropyWindows
+    else {
+         if os(halvm)
+           other-modules: System.EntropyXen
+         else
+           other-modules: System.EntropyNix
+    }
   }
   other-extensions:    CPP, ForeignFunctionInterface, BangPatterns,
                        ScopedTypeVariables
   build-depends:       base >= 4.8 && < 5, bytestring
+
   default-language:    Haskell2010
-  if(os(halvm))
-    cpp-options: -DXEN -DHAVE_RDRAND
-    cc-options:  -DXEN -DHAVE_RDRAND
-  if arch(x86_64)
-    cpp-options: -Darch_x86_64
-    cc-options:  -Darch_x86_64 -O2
-    -- gcc 4.8.2 on i386 fails to compile rdrand.c when using -fPIC!
-    c-sources:    cbits/rdrand.c
-    include-dirs: cbits
-  if arch(i386)
-    cpp-options: -Darch_i386
-    cc-options:  -Darch_i386 -O2
-  if os(windows)
-    build-depends: Win32
-    cpp-options: -DisWindows
-    cc-options:  -DisWindows
-    extra-libraries: advapi32
-  else
-    if !os(halvm)
-       Build-Depends: unix
+  
+  if impl(ghcjs) {
+    build-depends:     ghcjs-dom
+                     , jsaddle
+  }
+  else {
+    if(os(halvm))
+      cpp-options: -DXEN -DHAVE_RDRAND
+      cc-options:  -DXEN -DHAVE_RDRAND
+    if arch(x86_64)
+      cpp-options: -Darch_x86_64
+      cc-options:  -Darch_x86_64 -O2
+      -- gcc 4.8.2 on i386 fails to compile rdrand.c when using -fPIC!
+      c-sources:    cbits/rdrand.c
+      include-dirs: cbits
+    if arch(i386)
+      cpp-options: -Darch_i386
+      cc-options:  -Darch_i386 -O2
+    if os(windows)
+      build-depends: Win32 >= 2.5
+      cpp-options: -DisWindows
+      cc-options:  -DisWindows
+      extra-libraries: advapi32
+    else
+      if !os(halvm)
+         Build-Depends: unix
+  }
+
 
 source-repository head
     type:       git
