diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,14 +1,15 @@
-Revision History for zxcvbn-hs
-==============================
+# Revision History
 
-0.2.1.0 (September 25, 2019)
-----------------------------
+## 0.3.0.0 (October 29, 2020)
 
+  * Added a `ToJSON` instance to the `Score` type.
+
+## 0.2.1.0 (September 25, 2019)
+
   * Export the entire `HasConfig` class so external code can use the
     `config` lens.
 
-0.2.0.0 (September 12, 2019)
-----------------------------
+## 0.2.0.0 (September 12, 2019)
 
   * Make it possible for external projects to use the code generation
     tool (`zxcvbn-tools`)
@@ -16,7 +17,6 @@
   * Due to the `binary-orphans -> binary-instances` rename this
     package now only compiles under `nixpkgs-unstable`.
 
-0.1.0.0 (September 10, 2019)
-----------------------------
+## 0.1.0.0 (September 10, 2019)
 
   * Initial (unreleased) version
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2019 Peter J. Jones <pjones@devalot.com>
+Copyright (c) 2019-2020 Peter J. Jones <pjones@devalot.com>
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,13 +1,17 @@
-What?
------
+# Password Strength Estimation
 
+[![CI](https://github.com/sthenauth/zxcvbn-hs/workflows/CI/badge.svg)](https://github.com/sthenauth/zxcvbn-hs/actions)
+[![GitHub tag (latest by date)](https://img.shields.io/github/v/tag/sthenauth/zxcvbn-hs?label=release)](https://github.com/pjones/nix-hs/releases)
+[![Hackage](https://img.shields.io/hackage/v/zxcvbn-hs)](https://hackage.haskell.org/package/zxcvbn-hs)
+
+## What?
+
 This is a native Haskell implementation of the [zxcvbn][] password
 strength estimation algorithm as it appears in the 2016 USENIX
 Security [paper and presentation][paper] (with some small
 modifications).
 
-Why?
-----
+## Why?
 
 The [zxcvbn][] algorithm is a major improvement over traditional
 password strength estimators.  Instead of counting the occurrence of
@@ -15,8 +19,7 @@
 zxcvbn analyzes a plain text password and estimates the number of
 guesses that an attacker would need to make in order to crack it.
 
-How?
-----
+## How?
 
 A plain text password is broken into a list of substrings called
 tokens and each token is analyzed as follows:
@@ -43,8 +46,7 @@
 of guesses and then the entire password is scored based on the weakest
 path.
 
-Usage
------
+## Usage
 
 A complete example can be found in the
 [example/Main.hs](example/Main.hs) file.  That said, it's pretty easy
@@ -65,14 +67,12 @@
   print (strength guesses) -- Sum type describing the password strength (Risky)
 ```
 
-Demo App
---------
+## Demo App
 
 If you want to play with an interactive demo take a look at the
 [zxcvbn-ws repository][zxcvbn-ws].
 
-Customization
--------------
+## Customization
 
 You'll most likely want to add custom words to the frequency
 dictionaries.  For example, the name of your application, your domain
@@ -83,7 +83,7 @@
 `addCustomFrequencyList` function which can be used to easily add
 words to the frequency dictionary.
 
-### Localization ###
+### Localization
 
 Unlike other implementations of the [zxcvbn][] algorithm, this version
 fully supports localization.  It's easy to augment or completely
@@ -112,12 +112,11 @@
 
   * Number pad keyboard layout
 
-### Existing Localization Packages ###
+### Existing Localization Packages
 
   * [zxcvbn-dvorak][] Dvorak keyboard layout
 
-Performance
------------
+## Performance
 
 It takes approximately 1.5 ms to process a 30-character password.
 Performance degrades as the length of the password increases (e.g., a
diff --git a/src/Text/Password/Strength.hs b/src/Text/Password/Strength.hs
--- a/src/Text/Password/Strength.hs
+++ b/src/Text/Password/Strength.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE OverloadedStrings #-}
+
 {-|
 
 Copyright:
@@ -23,7 +25,7 @@
 module Text.Password.Strength (
   -- * Estimating Guesses
   score,
-  Search.Score(..),
+  Score(..),
 
   -- * Calculating Password Strength
   strength,
@@ -38,6 +40,8 @@
 -- Library Imports:
 import Data.Text (Text)
 import Data.Time.Calendar (Day)
+import Data.Aeson (ToJSON(..), (.=))
+import qualified Data.Aeson as Aeson
 
 --------------------------------------------------------------------------------
 -- Project Imports:
@@ -45,13 +49,25 @@
 import qualified Text.Password.Strength.Internal.Search as Search
 
 --------------------------------------------------------------------------------
+-- | A score is an estimate of the number of guesses it would take to
+-- crack a password.
+newtype Score = Score { getScore :: Integer }
+  deriving (Show, Eq, Ord)
+
+instance ToJSON Score where
+  toJSON s = Aeson.object
+    [ "score"    .= getScore s
+    , "strength" .= show (strength s)
+    ]
+
+--------------------------------------------------------------------------------
 -- | Estimate the number of guesses an attacker would need to make to
 -- crack the given password.
 score :: Config -- ^ Which dictionaries, keyboards, etc. to use.
       -> Day    -- ^ Reference day for date matches (should be current day).
       -> Text   -- ^ The password to score.
-      -> Search.Score -- ^ Estimate.
-score c d p = Search.score (Search.graph c d p)
+      -> Score  -- ^ Estimate.
+score c d p = Score $ Search.score (Search.graph c d p)
 
 --------------------------------------------------------------------------------
 -- | Measurement of password strength.
@@ -79,8 +95,8 @@
 
 --------------------------------------------------------------------------------
 -- | Calculate the strength of a password given its score.
-strength :: Search.Score -> Strength
-strength (Search.Score n)
+strength :: Score -> Strength
+strength (Score n)
   | n < 10 ^ ( 3 :: Int) = Risky
   | n < 10 ^ ( 6 :: Int) = Weak
   | n < 10 ^ ( 8 :: Int) = Moderate
diff --git a/src/Text/Password/Strength/Internal/Date.hs b/src/Text/Password/Strength/Internal/Date.hs
--- a/src/Text/Password/Strength/Internal/Date.hs
+++ b/src/Text/Password/Strength/Internal/Date.hs
@@ -30,8 +30,7 @@
 import Control.Lens ((&), (^.), (+~), _1)
 import Control.Lens.TH (makeLenses)
 import qualified Data.Attoparsec.Text as Atto
-import Data.Char (isDigit)
-import Data.Char (isSpace)
+import Data.Char (isDigit, isSpace)
 import Data.Function (on)
 import Data.List (sortBy)
 import Data.Maybe (catMaybes, listToMaybe)
diff --git a/src/Text/Password/Strength/Internal/L33t.hs b/src/Text/Password/Strength/Internal/L33t.hs
--- a/src/Text/Password/Strength/Internal/L33t.hs
+++ b/src/Text/Password/Strength/Internal/L33t.hs
@@ -67,7 +67,7 @@
     hasSubs L33t{..} = _l33tSub > 0 || _l33tUnsub > 0
 
     chars :: Text
-    chars = (token ^. tokenLower)
+    chars = token ^. tokenLower
 
     trans :: [(Token, Text)]
     trans  = case translateMap l33t2Eng chars of
diff --git a/src/Text/Password/Strength/Internal/Search.hs b/src/Text/Password/Strength/Internal/Search.hs
--- a/src/Text/Password/Strength/Internal/Search.hs
+++ b/src/Text/Password/Strength/Internal/Search.hs
@@ -24,7 +24,6 @@
   edges,
   bfEdges,
   graph,
-  Score(..),
   score,
   shortestPath
   ) where
@@ -114,7 +113,7 @@
 -- list.  In the guessing graph the nodes are the characters in the
 -- password and the edges are the estimated guesses.
 graph :: Config -> Day -> Text -> Graph
-graph config day password =
+graph cfg day password =
     Graph exit edges' (Graph.mkGraph nodes (flatten edges'))
   where
     exit :: Int
@@ -125,23 +124,17 @@
 
     edges' :: Map (Int, Int) Integer
     edges' =
-      let es = edges config day password
+      let es = edges cfg day password
       in es `Map.union` Map.fromList (bfEdges password es)
 
     flatten :: Map (Int, Int) Integer -> [(Int, Int, Integer)]
     flatten = map (\((x, y), z) -> (x, y, z)) . Map.assocs
 
 --------------------------------------------------------------------------------
--- | A score is an estimate of the number of guesses it would take to
--- crack a password.
-newtype Score = Score { getScore :: Integer }
-  deriving (Show, Eq, Ord)
-
---------------------------------------------------------------------------------
 -- | Collapse a graph down to a single score which represents the
 -- estimated number of guesses it would take to crack the password.
-score :: Graph -> Score
-score g@Graph{..} = Score $
+score :: Graph -> Integer
+score g@Graph{..} =
   case shortestPath g of
     Nothing   -> worstCase
     Just path -> maybe worstCase product (scores (nodes path))
diff --git a/zxcvbn-hs.cabal b/zxcvbn-hs.cabal
--- a/zxcvbn-hs.cabal
+++ b/zxcvbn-hs.cabal
@@ -1,18 +1,21 @@
-cabal-version: 2.2
-
---------------------------------------------------------------------------------
-name:          zxcvbn-hs
-version:       0.2.1.0
-synopsis:      Password strength estimation based on zxcvbn.
-description:   Please see the README below.
-license:       MIT
-license-file:  LICENSE
-author:        Peter Jones <pjones@devalot.com>
-maintainer:    Peter Jones <pjones@devalot.com>
-copyright:     Copyright (c) 2019 Peter Jones
-homepage:      https://code.devalot.com/sthenauth/zxcvbn-hs
-bug-reports:   https://github.com/sthenauth/zxcvbn-hs/issues
-category:      System
+cabal-version:      2.2
+name:               zxcvbn-hs
+version:            0.3.0.0
+synopsis:           Password strength estimation based on zxcvbn.
+license:            MIT
+license-file:       LICENSE
+author:             Peter Jones <pjones@devalot.com>
+maintainer:         Peter Jones <pjones@devalot.com>
+copyright:          Copyright (c) 2019-2020 Peter Jones
+homepage:           https://github.com/sthenauth/zxcvbn-hs
+bug-reports:        https://github.com/sthenauth/zxcvbn-hs/issues
+category:           System
+tested-with:        GHC ==8.6.5 || ==8.8.4 || ==8.10.2
+description:
+  This is a native Haskell implementation of the zxcvbn password
+  strength estimation algorithm as it appears in the 2016 USENIX Security
+  <https://www.usenix.org/conference/usenixsecurity16/technical-sessions/presentation/wheeler paper>
+  and presentation (with some small modifications).
 
 --------------------------------------------------------------------------------
 extra-source-files:
@@ -22,62 +25,62 @@
 --------------------------------------------------------------------------------
 flag tools
   description: Build the data processing tools (i.e. dictionary compilers)
-  default: False
-  manual: True
+  default:     False
+  manual:      True
 
 --------------------------------------------------------------------------------
 source-repository head
-  type: git
-  location: https://code.devalot.com/sthenauth/zxcvbn-hs.git
+  type:     git
+  location: https://github.com/sthenauth/zxcvbn-hs.git
 
 --------------------------------------------------------------------------------
 common options
   default-language: Haskell2010
-  ghc-options: -Wall
-               -Werror=incomplete-record-updates
-               -Werror=incomplete-uni-patterns
-               -Werror=missing-home-modules
-               -Widentities
-               -Wmissing-export-lists
-               -Wredundant-constraints
+  ghc-options:
+    -Wall -Werror=incomplete-record-updates
+    -Werror=incomplete-uni-patterns -Werror=missing-home-modules
+    -Widentities -Wmissing-export-lists -Wredundant-constraints
 
 --------------------------------------------------------------------------------
 common dependencies
-  build-depends: base                        >= 4.9   && < 5.0
-               , attoparsec                  >= 0.13  && < 0.14
-               , base64-bytestring           >= 1.0   && < 1.1
-               , binary                      >= 0.8   && < 0.11
-               , binary-instances            >= 0.1   && < 1.0
-               , containers                  >= 0.6   && < 0.7
-               , fgl                         >= 5.7   && < 5.8
-               , lens                        >= 4.17  && < 4.18
-               , math-functions              >= 0.3   && < 0.4
-               , text                        >= 1.2   && < 1.3
-               , time                        >= 1.8   && < 2.0
-               , unordered-containers        >= 0.2   && < 0.3
-               , vector                      >= 0.12  && < 0.13
-               , zlib                        >= 0.6   && < 0.7
+  build-depends:
+    , aeson                 >=1.3  && <1.6
+    , attoparsec            ^>=0.13
+    , base                  >=4.9  && <5.0
+    , base64-bytestring     >=1.0  && <1.3
+    , binary                >=0.8  && <0.11
+    , binary-instances      ^>=1
+    , containers            ^>=0.6
+    , fgl                   ^>=5.7
+    , lens                  >=4.17 && <5
+    , math-functions        ^>=0.3
+    , text                  ^>=1.2
+    , time                  >=1.8  && <2.0
+    , unordered-containers  ^>=0.2
+    , vector                ^>=0.12
+    , zlib                  ^>=0.6
 
 --------------------------------------------------------------------------------
 common tool-dependencies
-  build-depends: filepath                    >= 1.4   && < 1.5
-               , mtl                         >= 2.2   && < 2.3
-               , optparse-applicative        >= 0.14  && < 0.15
-               , pipes                       >= 4.3   && < 4.4
-               , pipes-safe                  >= 2.3   && < 2.4
-               , pipes-text                  >= 0.0   && < 0.1
+  build-depends:
+    , filepath              ^>=1.4
+    , mtl                   ^>=2.2
+    , optparse-applicative  >=0.14 && <0.16
+    , pipes                 ^>=4.3
+    , pipes-safe            ^>=2.3
+    , pipes-text            >=0.0  && <1.1
 
 --------------------------------------------------------------------------------
 library
-  import: options, dependencies
-  -- ghc-prof-options: -fprof-auto -fprof-cafs
-  hs-source-dirs: src
+  import:          options, dependencies
 
+  -- ghc-prof-options: -fprof-auto -fprof-cafs
+  hs-source-dirs:  src
   exposed-modules:
     Text.Password.Strength
     Text.Password.Strength.Config
-    Text.Password.Strength.Types
     Text.Password.Strength.Internal
+    Text.Password.Strength.Types
 
   other-modules:
     Text.Password.Strength.Generated.Adjacency
@@ -98,37 +101,40 @@
 
 --------------------------------------------------------------------------------
 executable zxcvbn-tools
-  import: options, dependencies, tool-dependencies
-  main-is: Main.hs
+  import:         options, dependencies, tool-dependencies
+  main-is:        Main.hs
   hs-source-dirs: tools
   other-modules:
     Zxcvbn.Adjacency
     Zxcvbn.Encode
     Zxcvbn.Freq
     Zxcvbn.Global
-  build-depends: zxcvbn-hs
+
+  build-depends:  zxcvbn-hs
+
   if !flag(tools)
     buildable: False
 
 --------------------------------------------------------------------------------
 executable zxcvbn-example
-  import: options, dependencies
-  main-is: Main.hs
-  hs-source-dirs: example
+  import:           options, dependencies
+  main-is:          Main.hs
+  hs-source-dirs:   example
   ghc-prof-options: -rtsopts
-  build-depends: zxcvbn-hs
+  build-depends:    zxcvbn-hs
 
 --------------------------------------------------------------------------------
 test-suite test
-  import: options, dependencies
-  type: exitcode-stdio-1.0
+  import:         options, dependencies
+  type:           exitcode-stdio-1.0
   hs-source-dirs: test
-  main-is: Main.hs
-  build-depends: hedgehog       >= 0.6  && < 1.1
-               , tasty          >= 1.1  && < 1.3
-               , tasty-hedgehog >= 0.2  && < 1.1
-               , tasty-hunit    >= 0.10 && < 0.11
-               , zxcvbn-hs
+  main-is:        Main.hs
+  build-depends:
+    , hedgehog        >=0.6  && <1.1
+    , tasty           >=1.1  && <1.5
+    , tasty-hedgehog  >=0.2  && <1.1
+    , tasty-hunit     ^>=0.10
+    , zxcvbn-hs
 
   other-modules:
     Zxcvbn.Adjacency
@@ -141,10 +147,11 @@
 
 --------------------------------------------------------------------------------
 benchmark bench
-  import: options, dependencies
-  type: exitcode-stdio-1.0
-  hs-source-dirs: benchmark
-  main-is: Main.hs
+  import:           options, dependencies
+  type:             exitcode-stdio-1.0
+  hs-source-dirs:   benchmark
+  main-is:          Main.hs
   ghc-prof-options: -rtsopts
-  build-depends: criterion >= 1.5 && < 1.6
-               , zxcvbn-hs
+  build-depends:
+    , criterion  ^>=1.5
+    , zxcvbn-hs
