diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Daniel YU (c) 2019
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Daniel YU nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,1 @@
+# salak-yaml
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/salak-toml.cabal b/salak-toml.cabal
new file mode 100644
--- /dev/null
+++ b/salak-toml.cabal
@@ -0,0 +1,50 @@
+cabal-version: 1.12
+name: salak-toml
+version: 0.2.7
+license: BSD3
+license-file: LICENSE
+copyright: (c) 2018 Daniel YU
+maintainer: Daniel YU <leptonyu@gmail.com>
+author: Daniel YU
+homepage: https://github.com/leptonyu/salak#readme
+synopsis: Configuration Loader for toml
+category: Library, Configuration
+build-type: Simple
+extra-source-files:
+    README.md
+    test/salak.toml
+
+library
+    exposed-modules:
+        Salak.Load.Toml
+    hs-source-dirs: src
+    other-modules:
+        Paths_salak_toml
+    default-language: Haskell2010
+    build-depends:
+        base >=4.10 && <5,
+        mtl >=2.2.2 && <2.3,
+        salak ==0.2.7,
+        text >=1.2.3.1 && <1.3,
+        time >=1.8.0.2 && <1.9,
+        tomland ==1.0.*,
+        unordered-containers >=0.2.9.0 && <0.3
+
+test-suite spec
+    type: exitcode-stdio-1.0
+    main-is: Spec.hs
+    hs-source-dirs: test src
+    other-modules:
+        Salak.Load.Toml
+        Paths_salak_toml
+    default-language: Haskell2010
+    build-depends:
+        QuickCheck >=2.12.6.1 && <2.14,
+        base >=4.10 && <5,
+        hspec ==2.*,
+        mtl >=2.2.2 && <2.3,
+        salak ==0.2.7,
+        text >=1.2.3.1 && <1.3,
+        time >=1.8.0.2 && <1.9,
+        tomland ==1.0.*,
+        unordered-containers >=0.2.9.0 && <0.3
diff --git a/src/Salak/Load/Toml.hs b/src/Salak/Load/Toml.hs
new file mode 100644
--- /dev/null
+++ b/src/Salak/Load/Toml.hs
@@ -0,0 +1,61 @@
+{-# LANGUAGE GADTs           #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE TupleSections   #-}
+module Salak.Load.Toml where
+
+import           Control.Monad          (foldM, (>=>))
+import           Control.Monad.IO.Class (MonadIO, liftIO)
+import           Control.Monad.State
+import qualified Data.HashMap.Strict    as HM
+import qualified Data.List.NonEmpty     as N
+import qualified Data.Text.IO           as IO
+import           Data.Time
+import           Salak
+import           Salak.Load
+import           Toml                   hiding (TOML)
+import qualified Toml                   as T
+
+data TOML = TOML
+
+instance HasLoad TOML where
+  loaders _ = (, loadToml) <$> ["toml", "tml"]
+
+toSs :: Key -> [Selector]
+toSs (Key ps) = toS <$> N.toList ps
+
+toS :: Piece -> Selector
+toS = SStr . unPiece
+
+loadTOML :: Reload -> T.TOML -> SourcePack -> SourcePack
+loadTOML name v sp = loadFile name sp $ go v
+  where
+    go T.TOML{..} i s = HM.foldlWithKey' (g1 i) (return s) tomlPairs
+                  >>= h2 i tomlTables
+    g1 i ms k v' = ms >>= updateSources (toSs k) (f1 i v')
+    g2 i ms _ v' = ms >>= f2 i v'
+    f1 :: Monad m => Priority -> AnyValue -> Source -> m Source
+    f1 i (AnyValue (Array   b)) = \s -> foldM (\s' (ix,x) -> updateSource (SNum ix) (f1 i $ AnyValue x) s') s $ zip [0..] b
+    f1 i (AnyValue (Bool    b)) = return . insertSource (VBool  i b)
+    f1 i (AnyValue (Integer b)) = return . insertSource (VNum   i $ fromIntegral b)
+    f1 i (AnyValue (Double  b)) = return . insertSource (VNum   i $ realToFrac b)
+    f1 i (AnyValue (Text    b)) = return . insertSource (VStr   i b)
+    f1 i (AnyValue (Local   b)) = return . insertSource (VLTime i b)
+    f1 i (AnyValue (Day     b)) = return . insertSource (VDay   i b)
+    f1 i (AnyValue (Hours   b)) = return . insertSource (VHour  i b)
+    f1 i (AnyValue (Zoned (ZonedTime a b))) = return . insertSource (VZTime i b a)
+    -- f1 i _ = return
+    f2 :: Monad m => Priority -> PrefixTree T.TOML -> Source -> m Source
+    f2 i (Leaf   k     toml) = updateSources (toSs k) (go toml i)
+    f2 i (Branch k v' tomap) = updateSources (toSs k) (h1 i v' >=> h2 i tomap)
+    h1 :: Monad m => Priority -> Maybe T.TOML -> Source -> m Source
+    h1 i (Just t) = go t i
+    h1 _ _        = return
+    h2 :: Monad m => Priority -> PrefixMap T.TOML -> Source -> m Source
+    h2 i m s = HM.foldlWithKey' (g2 i) (return s) m
+
+loadToml :: MonadIO m => FilePath -> SourcePackT m ()
+loadToml file = do
+    re <- liftIO $ parse <$> IO.readFile file
+    modify $ \sp ->case re of
+        Left  e -> addErr' (show e) sp
+        Right a -> loadTOML (defReload file $ loadToml file) a sp
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec.hs
@@ -0,0 +1,69 @@
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE DeriveGeneric       #-}
+{-# LANGUAGE FlexibleContexts    #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+module Main where
+
+import           Control.Monad.Reader
+import           Control.Monad.Writer
+import           Data.Either
+import           Data.List            (intercalate)
+import           Data.Text            (Text, pack, unpack)
+import           GHC.Generics
+import           Salak
+import           Salak.Load.Toml
+import           Test.Hspec
+import           Test.QuickCheck
+
+main = hspec spec
+
+spec :: Spec
+spec = do
+  describe "Salak.Load.Toml"  tomlProperty
+
+newtype SKey = SKey { unKey :: Text } deriving Show
+
+instance Arbitrary SKey where
+  arbitrary = do
+    key <- choose (1,20)
+    vs  <- vectorOf key $ do
+      k <- choose (1,20)
+      v <- vectorOf k $ choose ('a','z')
+      b <- choose (0,10) :: Gen Int
+      if b > 0 then return v else do
+        x <- choose (0,10) :: Gen Int
+        return (v ++ "[" ++ show x ++ "]")
+    return (SKey $ pack $ intercalate "." vs)
+
+data Conf = Conf
+  { name :: String
+  , age  :: Int
+  , male :: Bool
+  , det  :: SubConf
+  } deriving (Eq, Show, Generic)
+
+data SubConf = SubConf
+  { hello :: String } deriving (Eq, Show, Generic)
+
+instance FromProp SubConf where
+  fromProp = SubConf <$> "hello" .?= "yyy"
+
+instance FromProp Conf
+
+tomlProperty = do
+  context "load toml" $ do
+    it "salak.toml" $ do
+      loadAndRunSalak (loadToml "test/salak.toml") $ do
+        cf <- require "me.icymint.conf"
+        lift $ do
+          name cf `shouldBe` "shelly"
+          age  cf `shouldBe` 16
+          male cf `shouldBe` False
+          det  cf `shouldBe` SubConf "def"
+
+
+
+
+
diff --git a/test/salak.toml b/test/salak.toml
new file mode 100644
--- /dev/null
+++ b/test/salak.toml
@@ -0,0 +1,261 @@
+server.port        = 8080
+server.codes       = [ 5, 10, 42 ]
+server.description = """
+This is production server.
+Don't touch it!
+"""
+
+[mail]
+    host = "smtp.gmail.com"
+    send-if-inactive = false
+
+[me.icymint.conf]
+name="shelly"
+age=16
+male="no"
+det.hello="def"
+
+################################################################################
+## Comment
+
+# Speak your mind with the hash symbol. They go from the symbol to the end of
+# the line.
+
+
+################################################################################
+## Table
+
+# Tables (also known as hash tables or dictionaries) are collections of
+# key/value pairs. They appear in square brackets on a line by themselves.
+
+[table]
+
+key = "value" # Yeah, you can do this.
+
+# Nested tables are denoted by table names with dots in them. Name your tables
+# whatever crap you please, just don't use #, ., [ or ].
+
+[table.subtable]
+
+key = "another value"
+
+# You don't need to specify all the super-tables if you don't want to. TOML
+# knows how to do it for you.
+
+# [x] you
+# [x.y] don't
+# [x.y.z] need these
+[x.y.z.w] # for this to work
+
+
+################################################################################
+## Inline Table
+
+# Inline tables provide a more compact syntax for expressing tables. They are
+# especially useful for grouped data that can otherwise quickly become verbose.
+# Inline tables are enclosed in curly braces `{` and `}`. No newlines are
+# allowed between the curly braces unless they are valid within a value.
+
+[table.inline]
+
+name = { first = "Tom", last = "Preston-Werner" }
+point = { x = 1, y = 2 }
+
+
+################################################################################
+## String
+
+# There are four ways to express strings: basic, multi-line basic, literal, and
+# multi-line literal. All strings must contain only valid UTF-8 characters.
+
+[string.basic]
+
+basic = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."
+
+[string.multiline]
+
+# The following strings are byte-for-byte equivalent:
+key1 = "One\nTwo"
+key2 = """One\nTwo"""
+key3 = """
+One
+Two"""
+
+[string.multiline.continued]
+
+# The following strings are byte-for-byte equivalent:
+key1 = "The quick brown fox jumps over the lazy dog."
+
+key2 = """
+The quick brown \
+
+
+  fox jumps over \
+    the lazy dog."""
+
+key3 = """\
+       The quick brown \
+       fox jumps over \
+       the lazy dog.\
+       """
+
+[string.literal]
+
+# What you see is what you get.
+winpath  = 'C:\Users\nodejs\templates'
+winpath2 = '\\ServerX\admin$\system32\'
+quoted   = 'Tom "Dubs" Preston-Werner'
+regex    = '<\i\c*\s*>'
+
+
+[string.literal.multiline]
+
+regex2 = '''I [dw]on't need \d{2} apples'''
+lines  = '''
+The first newline is
+trimmed in raw strings.
+   All other whitespace
+   is preserved.
+'''
+
+
+################################################################################
+## Integer
+
+# Integers are whole numbers. Positive numbers may be prefixed with a plus sign.
+# Negative numbers are prefixed with a minus sign.
+
+[integer]
+
+key1 = +99
+key2 = 42
+key3 = 0
+key4 = -17
+
+[integer.underscores]
+
+# For large numbers, you may use underscores to enhance readability. Each
+# underscore must be surrounded by at least one digit.
+key1 = 1_000
+key2 = 5_349_221
+key3 = 1_2_3_4_5     # valid but inadvisable
+
+
+################################################################################
+## Float
+
+# A float consists of an integer part (which may be prefixed with a plus or
+# minus sign) followed by a fractional part and/or an exponent part.
+
+[float.fractional]
+
+key1 = +1.0
+key2 = 3.1415
+key3 = -0.01
+
+[float.exponent]
+
+key1 = 5e+22
+key2 = 1e6
+key3 = -2E-2
+
+[float.both]
+
+key = 6.626e-34
+
+[float.underscores]
+
+key1 = 9_224_617.445_991_228_313
+key2 = 1e1_000
+
+
+################################################################################
+## Boolean
+
+# Booleans are just the tokens you're used to. Always lowercase.
+
+[boolean]
+
+True = true
+False = false
+
+
+################################################################################
+## Datetime
+
+# Datetimes are RFC 3339 dates.
+
+[datetime]
+
+key1 = 1979-05-27T07:32:00Z
+key2 = 1979-05-27T00:32:00-07:00
+key3 = 1979-05-27T00:32:00.999999-07:00
+
+
+################################################################################
+## Array
+
+# Arrays are square brackets with other primitives inside. Whitespace is
+# ignored. Elements are separated by commas. Data types may not be mixed.
+
+[array]
+
+key1 = [ 1, 2, 3 ]
+key2 = [ "red", "yellow", "green" ]
+key3 = [ [ 1, 2 ], [3, 4, 5] ]
+key4 = [ [ 1, 2 ], ["a", "b", "c"] ] # this is ok
+
+# Arrays can also be multiline. So in addition to ignoring whitespace, arrays
+# also ignore newlines between the brackets.  Terminating commas are ok before
+# the closing bracket.
+
+key5 = [
+  1, 2, 3
+]
+key6 = [
+  1,
+  2, # this is ok
+]
+
+
+################################################################################
+## Array of Tables
+
+# These can be expressed by using a table name in double brackets. Each table
+# with the same double bracketed name will be an element in the array. The
+# tables are inserted in the order encountered.
+
+[[products]]
+
+name = "Hammer"
+sku = 738594937
+
+[[products]]
+
+[[products]]
+
+name = "Nail"
+sku = 284758393
+color = "gray"
+
+
+# You can create nested arrays of tables as well.
+
+[[fruit]]
+  name = "apple"
+
+  [fruit.physical]
+    color = "red"
+    shape = "round"
+
+  [[fruit.variety]]
+    name = "red delicious"
+
+  [[fruit.variety]]
+    name = "granny smith"
+
+[[fruit]]
+  name = "banana"
+
+  [[fruit.variety]]
+    name = "plantain"
