diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2017 Agustin Camino
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,5 @@
+# state-codes
+
+[![Build Status](https://travis-ci.org/acamino/state-codes.svg?branch=master)](https://travis-ci.org/acamino/state-codes)
+
+This package provides the ISO 3166-2:US state codes and i18n names.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/src/Data/StateCodes.hs b/src/Data/StateCodes.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/StateCodes.hs
@@ -0,0 +1,23 @@
+-- | Main entry point, exposing all that needs to be
+
+module Data.StateCodes
+  ( StateCode(..)
+  , allNames
+  , stateList
+  , fromMName
+  , fromMText
+  , fromName
+  , fromText
+  , toName
+  , toText
+  ) where
+
+import           Control.Arrow              ((&&&))
+import           Data.Text                  (Text)
+
+import           Data.StateCodes.ISO31662US
+
+-- | List all codes with names
+
+allNames :: [(StateCode, Text)]
+allNames = map (id &&& toName) $ enumFrom minBound
diff --git a/src/Data/StateCodes/ISO31662US.hs b/src/Data/StateCodes/ISO31662US.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/StateCodes/ISO31662US.hs
@@ -0,0 +1,434 @@
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE OverloadedStrings     #-}
+{-# LANGUAGE PatternGuards         #-}
+
+-- | This file is generated from the Wikipedia page
+-- <https://en.wikipedia.org/wiki/ISO_3166-2:US>
+
+module Data.StateCodes.ISO31662US
+  ( StateCode(..)
+  , stateList
+  , fromMName
+  , fromMText
+  , fromName
+  , fromText
+  , toName
+  , toText
+  ) where
+
+import           Control.Applicative   (pure)
+import           Data.Aeson
+import           Data.Text             (Text)
+import qualified Data.Text             as T
+import           Data.Typeable
+import           Text.Shakespeare.I18N
+
+data StateCode = AL
+               | AK
+               | AZ
+               | AR
+               | CA
+               | CO
+               | CT
+               | DE
+               | FL
+               | GA
+               | HI
+               | ID
+               | IL
+               | IN
+               | IA
+               | KS
+               | KY
+               | LA
+               | ME
+               | MD
+               | MA
+               | MI
+               | MN
+               | MS
+               | MO
+               | MT
+               | NE
+               | NV
+               | NH
+               | NJ
+               | NM
+               | NY
+               | NC
+               | ND
+               | OH
+               | OK
+               | OR
+               | PA
+               | RI
+               | SC
+               | SD
+               | TN
+               | TX
+               | UT
+               | VT
+               | VA
+               | WA
+               | WV
+               | WI
+               | WY
+               | DC
+               | AS
+               | GU
+               | MP
+               | PR
+               | UM
+               | VI
+               deriving (Bounded, Eq, Enum, Show, Read, Ord, Typeable)
+
+
+-- | Maybe get the StateCode from the text code.
+
+fromMText :: Text -> Maybe StateCode
+fromMText "AL" = Just AL
+fromMText "AK" = Just AK
+fromMText "AZ" = Just AZ
+fromMText "AR" = Just AR
+fromMText "CA" = Just CA
+fromMText "CO" = Just CO
+fromMText "CT" = Just CT
+fromMText "DE" = Just DE
+fromMText "FL" = Just FL
+fromMText "GA" = Just GA
+fromMText "HI" = Just HI
+fromMText "ID" = Just ID
+fromMText "IL" = Just IL
+fromMText "IN" = Just IN
+fromMText "IA" = Just IA
+fromMText "KS" = Just KS
+fromMText "KY" = Just KY
+fromMText "LA" = Just LA
+fromMText "ME" = Just ME
+fromMText "MD" = Just MD
+fromMText "MA" = Just MA
+fromMText "MI" = Just MI
+fromMText "MN" = Just MN
+fromMText "MS" = Just MS
+fromMText "MO" = Just MO
+fromMText "MT" = Just MT
+fromMText "NE" = Just NE
+fromMText "NV" = Just NV
+fromMText "NH" = Just NH
+fromMText "NJ" = Just NJ
+fromMText "NM" = Just NM
+fromMText "NY" = Just NY
+fromMText "NC" = Just NC
+fromMText "ND" = Just ND
+fromMText "OH" = Just OH
+fromMText "OK" = Just OK
+fromMText "OR" = Just OR
+fromMText "PA" = Just PA
+fromMText "RI" = Just RI
+fromMText "SC" = Just SC
+fromMText "SD" = Just SD
+fromMText "TN" = Just TN
+fromMText "TX" = Just TX
+fromMText "UT" = Just UT
+fromMText "VT" = Just VT
+fromMText "VA" = Just VA
+fromMText "WA" = Just WA
+fromMText "WV" = Just WV
+fromMText "WI" = Just WI
+fromMText "WY" = Just WY
+fromMText "DC" = Just DC
+fromMText "AS" = Just AS
+fromMText "GU" = Just GU
+fromMText "MP" = Just MP
+fromMText "PR" = Just PR
+fromMText "UM" = Just UM
+fromMText "VI" = Just VI
+fromMText _    = Nothing
+
+
+-- | Get the StateCode from the text code. Errors if the code is unknown
+
+fromText :: Text -> StateCode
+fromText c = case fromMText c of
+               Just sc -> sc
+               _       -> error $ "fromText: Unknown state code:" ++ T.unpack c
+
+
+-- | Get the code as text
+
+toText :: StateCode -> Text
+toText AL = "AL"
+toText AK = "AK"
+toText AZ = "AZ"
+toText AR = "AR"
+toText CA = "CA"
+toText CO = "CO"
+toText CT = "CT"
+toText DE = "DE"
+toText FL = "FL"
+toText GA = "GA"
+toText HI = "HI"
+toText ID = "ID"
+toText IL = "IL"
+toText IN = "IN"
+toText IA = "IA"
+toText KS = "KS"
+toText KY = "KY"
+toText LA = "LA"
+toText ME = "ME"
+toText MD = "MD"
+toText MA = "MA"
+toText MI = "MI"
+toText MN = "MN"
+toText MS = "MS"
+toText MO = "MO"
+toText MT = "MT"
+toText NE = "NE"
+toText NV = "NV"
+toText NH = "NH"
+toText NJ = "NJ"
+toText NM = "NM"
+toText NY = "NY"
+toText NC = "NC"
+toText ND = "ND"
+toText OH = "OH"
+toText OK = "OK"
+toText OR = "OR"
+toText PA = "PA"
+toText RI = "RI"
+toText SC = "SC"
+toText SD = "SD"
+toText TN = "TN"
+toText TX = "TX"
+toText UT = "UT"
+toText VT = "VT"
+toText VA = "VA"
+toText WA = "WA"
+toText WV = "WV"
+toText WI = "WI"
+toText WY = "WY"
+toText DC = "DC"
+toText AS = "AS"
+toText GU = "GU"
+toText MP = "MP"
+toText PR = "PR"
+toText UM = "UM"
+toText VI = "VI"
+
+
+-- | Maybe get the code from the user readable name
+
+fromMName :: Text -> Maybe StateCode
+fromMName "Alabama"                              = Just AL
+fromMName "Alaska"                               = Just AK
+fromMName "Arizona"                              = Just AZ
+fromMName "Arkansas"                             = Just AR
+fromMName "California"                           = Just CA
+fromMName "Colorado"                             = Just CO
+fromMName "Connecticut"                          = Just CT
+fromMName "Delaware"                             = Just DE
+fromMName "Florida"                              = Just FL
+fromMName "Georgia"                              = Just GA
+fromMName "Hawaii"                               = Just HI
+fromMName "Idaho"                                = Just ID
+fromMName "Illinois"                             = Just IL
+fromMName "Indiana"                              = Just IN
+fromMName "Iowa"                                 = Just IA
+fromMName "Kansas"                               = Just KS
+fromMName "Kentucky"                             = Just KY
+fromMName "Louisiana"                            = Just LA
+fromMName "Maine"                                = Just ME
+fromMName "Maryland"                             = Just MD
+fromMName "Massachusetts"                        = Just MA
+fromMName "Michigan"                             = Just MI
+fromMName "Minnesota"                            = Just MN
+fromMName "Mississippi"                          = Just MS
+fromMName "Missouri"                             = Just MO
+fromMName "Montana"                              = Just MT
+fromMName "Nebraska"                             = Just NE
+fromMName "Nevada"                               = Just NV
+fromMName "New Hampshire"                        = Just NH
+fromMName "New Jersey"                           = Just NJ
+fromMName "New Mexico"                           = Just NM
+fromMName "New York"                             = Just NY
+fromMName "North Carolina"                       = Just NC
+fromMName "North Dakota"                         = Just ND
+fromMName "Ohio"                                 = Just OH
+fromMName "Oklahoma"                             = Just OK
+fromMName "Oregon"                               = Just OR
+fromMName "Pennsylvania"                         = Just PA
+fromMName "Rhode Island"                         = Just RI
+fromMName "South Carolina"                       = Just SC
+fromMName "South Dakota"                         = Just SD
+fromMName "Tennessee"                            = Just TN
+fromMName "Texas"                                = Just TX
+fromMName "Utah"                                 = Just UT
+fromMName "Vermont"                              = Just VT
+fromMName "Virginia"                             = Just VA
+fromMName "Washington"                           = Just WA
+fromMName "West Virginia"                        = Just WV
+fromMName "Wisconsin"                            = Just WI
+fromMName "Wyoming"                              = Just WY
+fromMName "District of Columbia"                 = Just DC
+fromMName "American Samoa"                       = Just AS
+fromMName "Guam"                                 = Just GU
+fromMName "Northern Mariana Islands"             = Just MP
+fromMName "Puerto Rico"                          = Just PR
+fromMName "United States Minor Outlying Islands" = Just UM
+fromMName "Virgin Islands, U.S."                 = Just VI
+fromMName _                                      = Nothing
+
+
+-- | Get the StateCode from the user readable name. Errors if the name is unknown
+
+fromName:: Text -> StateCode
+fromName s = case fromMName s of
+               Just sc -> sc
+               _       -> error $ "fromName: Unknown state code:" ++ T.unpack s
+
+
+-- | Get the user readable name
+
+toName :: StateCode -> Text
+toName AL = "Alabama"
+toName AK = "Alaska"
+toName AZ = "Arizona"
+toName AR = "Arkansas"
+toName CA = "California"
+toName CO = "Colorado"
+toName CT = "Connecticut"
+toName DE = "Delaware"
+toName FL = "Florida"
+toName GA = "Georgia"
+toName HI = "Hawaii"
+toName ID = "Idaho"
+toName IL = "Illinois"
+toName IN = "Indiana"
+toName IA = "Iowa"
+toName KS = "Kansas"
+toName KY = "Kentucky"
+toName LA = "Louisiana"
+toName ME = "Maine"
+toName MD = "Maryland"
+toName MA = "Massachusetts"
+toName MI = "Michigan"
+toName MN = "Minnesota"
+toName MS = "Mississippi"
+toName MO = "Missouri"
+toName MT = "Montana"
+toName NE = "Nebraska"
+toName NV = "Nevada"
+toName NH = "New Hampshire"
+toName NJ = "New Jersey"
+toName NM = "New Mexico"
+toName NY = "New York"
+toName NC = "North Carolina"
+toName ND = "North Dakota"
+toName OH = "Ohio"
+toName OK = "Oklahoma"
+toName OR = "Oregon"
+toName PA = "Pennsylvania"
+toName RI = "Rhode Island"
+toName SC = "South Carolina"
+toName SD = "South Dakota"
+toName TN = "Tennessee"
+toName TX = "Texas"
+toName UT = "Utah"
+toName VT = "Vermont"
+toName VA = "Virginia"
+toName WA = "Washington"
+toName WV = "West Virginia"
+toName WI = "Wisconsin"
+toName WY = "Wyoming"
+toName DC = "District of Columbia"
+toName AS = "American Samoa"
+toName GU = "Guam"
+toName MP = "Northern Mariana Islands"
+toName PR = "Puerto Rico"
+toName UM = "United States Minor Outlying Islands"
+toName VI = "Virgin Islands, U.S."
+
+
+-- | List of names sorted by alphabetical order, with state code
+-- this is ready to be used in a yesod selectField, for example
+
+stateList :: [(T.Text, StateCode)]
+stateList = [ ("Alabama", AL)
+            , ("Alaska", AK)
+            , ("Arizona", AZ)
+            , ("Arkansas", AR)
+            , ("California", CA)
+            , ("Colorado", CO)
+            , ("Connecticut", CT)
+            , ("Delaware", DE)
+            , ("Florida", FL)
+            , ("Georgia", GA)
+            , ("Hawaii", HI)
+            , ("Idaho", ID)
+            , ("Illinois", IL)
+            , ("Indiana", IN)
+            , ("Iowa", IA)
+            , ("Kansas", KS)
+            , ("Kentucky", KY)
+            , ("Louisiana", LA)
+            , ("Maine", ME)
+            , ("Maryland", MD)
+            , ("Massachusetts", MA)
+            , ("Michigan", MI)
+            , ("Minnesota", MN)
+            , ("Mississippi", MS)
+            , ("Missouri", MO)
+            , ("Montana", MT)
+            , ("Nebraska", NE)
+            , ("Nevada", NV)
+            , ("New Hampshire", NH)
+            , ("New Jersey", NJ)
+            , ("New Mexico", NM)
+            , ("New York", NY)
+            , ("North Carolina", NC)
+            , ("North Dakota", ND)
+            , ("Ohio", OH)
+            , ("Oklahoma", OK)
+            , ("Oregon", OR)
+            , ("Pennsylvania", PA)
+            , ("Rhode Island", RI)
+            , ("South Carolina", SC)
+            , ("South Dakota", SD)
+            , ("Tennessee", TN)
+            , ("Texas", TX)
+            , ("Utah", UT)
+            , ("Vermont", VT)
+            , ("Virginia", VA)
+            , ("Washington", WA)
+            , ("West Virginia", WV)
+            , ("Wisconsin", WI)
+            , ("Wyoming", WY)
+            , ("District of Columbia", DC)
+            , ("American Samoa", AS)
+            , ("Guam", GU)
+            , ("Northern Mariana Islands", MP)
+            , ("Puerto Rico", PR)
+            , ("United States Minor Outlying Islands", UM)
+            , ("Virgin Islands, U.S.", VI)
+            ]
+
+
+-- | To JSON: as a simple string
+
+instance ToJSON StateCode where
+  toJSON = toJSON . toText
+
+
+-- | From JSON: as a simple string
+
+instance FromJSON StateCode where
+  parseJSON (String s)
+    | Just a <- fromMText s = pure a
+  parseJSON _          = fail "StateCode"
+
+
+-- | Show user readable name, in English (ignoring locale for now)
+
+instance RenderMessage master StateCode where
+  renderMessage _ _ = toName
diff --git a/state-codes.cabal b/state-codes.cabal
new file mode 100644
--- /dev/null
+++ b/state-codes.cabal
@@ -0,0 +1,60 @@
+name:                state-codes
+version:             0.1.0
+synopsis:            ISO 3166-2:US state codes and i18n names
+description:         This package provides the ISO 3166-2:US state codes and i18n names
+homepage:            https://github.com/acamino/state-codes#README
+license:             MIT
+license-file:        LICENSE
+author:              Agustin Camino
+maintainer:          agustin.camino@gmail.com
+copyright:           2017 Agustin Camino
+category:            Data
+build-type:          Simple
+cabal-version:       >=1.10
+extra-source-files:  README.md
+
+
+flag dev
+  description:        Turn on development settings
+  manual:             True
+  default:            False
+
+
+source-repository head
+  type:      git
+  location:  https://github.com/acamino/state-codes.git
+
+
+library
+  hs-source-dirs:   src
+  build-depends:
+      base                 >= 4.7  && < 5
+    , text
+    , aeson
+    , shakespeare
+  if flag(dev)
+    ghc-options:       -Wall -Werror
+  else
+    ghc-options:       -O2 -Wall
+  other-modules:    Data.StateCodes.ISO31662US
+  exposed-modules:  Data.StateCodes
+  default-language: Haskell2010
+
+test-suite state-codes-test
+  main-is:          Spec.hs
+  type:             exitcode-stdio-1.0
+  hs-source-dirs:   test
+  other-modules:    Data.StateCodesSpec
+
+  build-depends:    base                   >= 4.7   && < 5.0
+                  , aeson
+                  , hspec
+                  , QuickCheck
+                  , state-codes
+                  , text
+
+  if flag(dev)
+    ghc-options:       -Wall -Werror
+  else
+    ghc-options:       -O2 -Wall
+  default-language: Haskell2010
diff --git a/test/Data/StateCodesSpec.hs b/test/Data/StateCodesSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/Data/StateCodesSpec.hs
@@ -0,0 +1,27 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# OPTIONS -fno-warn-orphans  #-}
+
+module Data.StateCodesSpec where
+
+import           Data.Aeson
+import qualified Data.Aeson            as A
+import           Test.Hspec
+import           Test.Hspec.QuickCheck
+import           Test.QuickCheck
+
+import           Data.StateCodes
+
+instance Arbitrary StateCode where
+  arbitrary = elements [minBound ..]
+
+
+spec :: Spec
+spec = do
+  prop "fromName . toName" $ forAll arbitrary $ \code ->
+    (fromName . toName) code == code
+
+  prop "fromText . toText" $ forAll arbitrary $ \code ->
+    (fromText . toText) code == code
+
+  prop "fromJSON . toJSON" $ forAll (arbitrary :: Gen StateCode)$ \code ->
+    (fromJSON . toJSON) code == A.Success code
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec.hs
@@ -0,0 +1,1 @@
+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
