diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,10 @@
+## Dotenv 0.2.0.0
+
+* Changed public interfaces to use Data.Text.
+* Added function `parseFile` to read dotenv file without modifying the
+  environment. Thanks to Daisuke Fujimura (Github: fujimura) for making this
+  contribution.
+  
+## Dotenv 0.1.0.0
+
+* First public release.
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2015 Justin Leitgeb
+Copyright (c) 2016 Justin Leitgeb
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
diff --git a/dotenv.cabal b/dotenv.cabal
--- a/dotenv.cabal
+++ b/dotenv.cabal
@@ -1,5 +1,5 @@
 name:                dotenv
-version:             0.1.0.9
+version:             0.2.0.0
 synopsis:            Loads environment variables from dotenv files
 homepage:            https://github.com/stackbuilders/dotenv-hs
 description:
@@ -34,23 +34,26 @@
 license:             MIT
 license-file:        LICENSE
 author:              Justin Leitgeb
-maintainer:          justin@stackbuilders.com
-copyright:           2015 Stack Builders Inc.
+maintainer:          hackage@stackbuilders.com
+copyright:           2015-2016 Stack Builders Inc.
 category:            Configuration
 build-type:          Simple
-extra-source-files:  spec/fixtures/.dotenv
+extra-source-files:    spec/fixtures/.dotenv
+                     , CHANGELOG.md
 cabal-version:       >=1.10
 bug-reports:         https://github.com/stackbuilders/dotenv-hs/issues
 
 executable dotenv
   main-is:             Main.hs
-  -- other-modules:
+  other-modules:       Configuration.Dotenv
+                       Configuration.Dotenv.Parse
   -- other-extensions:
-  build-depends:         base >=4.5 && <4.9
+  build-depends:         base >=4.5 && <5.0
                        , base-compat >= 0.4
-                       , optparse-applicative >=0.12 && < 0.13
-                       , parsec >= 3.1.0 && <= 3.2
+                       , optparse-applicative >=0.11 && < 0.13
+                       , megaparsec >= 4.2.0 && < 4.5.0
                        , process
+                       , text
 
   hs-source-dirs:      src
   default-language:    Haskell2010
@@ -59,9 +62,10 @@
   exposed-modules:    Configuration.Dotenv.Parse
                     , Configuration.Dotenv
 
-  build-depends:         base >=4.5 && <4.9
+  build-depends:         base >=4.5 && <5.0
                        , base-compat >= 0.4
-                       , parsec >= 3.1.0 && <= 3.2
+                       , megaparsec >= 4.2.0 && < 4.5.0
+                       , text
 
   hs-source-dirs:      src
   default-language:    Haskell2010
@@ -74,12 +78,14 @@
   main-is: Spec.hs
   other-modules:         Configuration.DotenvSpec
                        , Configuration.Dotenv.ParseSpec
+                       , Configuration.Dotenv
+                       , Configuration.Dotenv.Parse
 
-  build-depends:       base >=4.5 && <4.9
-                       , base-compat >= 0.4
-                       , parsec >= 3.1.0 && <= 3.2
-                       , parseerror-eq
-                       , hspec
+  build-depends:       base >=4.5 && <5.0
+                     , base-compat >= 0.4
+                     , megaparsec >= 4.2.0 && < 4.5.0
+                     , text
+                     , hspec
 
   default-language:    Haskell2010
   ghc-options:         -Wall
diff --git a/spec/Configuration/Dotenv/ParseSpec.hs b/spec/Configuration/Dotenv/ParseSpec.hs
--- a/spec/Configuration/Dotenv/ParseSpec.hs
+++ b/spec/Configuration/Dotenv/ParseSpec.hs
@@ -1,15 +1,19 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
+{-# LANGUAGE OverloadedStrings #-}
 
-module Configuration.Dotenv.ParseSpec (spec) where
+module Configuration.Dotenv.ParseSpec (main, spec) where
 
 import Configuration.Dotenv.Parse (configParser)
 
-import Test.Hspec (it, describe, shouldBe, Spec)
+import Test.Hspec (it, describe, shouldBe, Spec, hspec)
 
-import Text.Parsec (ParseError, parse)
+import Text.Megaparsec (ParseError, parse)
 
-import Text.ParseErrorEq ()
+import qualified Data.Text as T
 
+main :: IO ()
+main = hspec spec
+
 spec :: Spec
 spec = describe "parse" $ do
   it "parses unquoted values" $
@@ -44,7 +48,7 @@
   it "does not parse variables with hyphens in the name" $
     isLeft (parseConfig "FOO-BAR=foobar") `shouldBe` True
 
-  it "parses variables with '_' in the name" $
+  it "parses variables with \"_\" in the name" $
     parseConfig "FOO_BAR=foobar" `shouldBe` Right [("FOO_BAR", "foobar")]
 
   it "parses variables with digits after the first character" $
@@ -69,7 +73,7 @@
   it "ignores inline comments after quoted arguments" $
     parseConfig "FOO=\"bar\" # this is foo" `shouldBe` Right [("FOO", "bar")]
 
-  it "allows # in quoted values" $
+  it "allows \"#\" in quoted values" $
     parseConfig "foo=\"bar#baz\" # comment" `shouldBe`
     Right [("foo", "bar#baz")]
 
@@ -85,5 +89,5 @@
 isLeft ( Left _ ) = True
 isLeft _          = False
 
-parseConfig :: String -> Either ParseError [(String, String)]
+parseConfig :: T.Text -> Either ParseError [(T.Text, T.Text)]
 parseConfig = parse configParser "(unknown)"
diff --git a/spec/Configuration/DotenvSpec.hs b/spec/Configuration/DotenvSpec.hs
--- a/spec/Configuration/DotenvSpec.hs
+++ b/spec/Configuration/DotenvSpec.hs
@@ -1,13 +1,19 @@
-module Configuration.DotenvSpec (spec) where
+{-# LANGUAGE OverloadedStrings #-}
 
-import Configuration.Dotenv (load, loadFile)
+module Configuration.DotenvSpec (main, spec) where
 
+import Configuration.Dotenv (load, loadFile, parseFile)
+
 import Test.Hspec
 
 import System.Environment.Compat (lookupEnv, setEnv, unsetEnv)
+import Control.Monad (liftM)
 
-{-# ANN module "HLint: ignore Reduce duplication" #-}
+{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
 
+main :: IO ()
+main = hspec spec
+
 spec :: Spec
 spec = do
   describe "load" $ after_ (unsetEnv "foo") $ do
@@ -53,3 +59,16 @@
       loadFile True "spec/fixtures/.dotenv"
 
       lookupEnv "DOTENV" `shouldReturn` Just "true"
+
+  describe "parseFile" $ after_ (unsetEnv "DOTENV") $ do
+    it "returns variables from a file without changing the environment" $ do
+      lookupEnv "DOTENV" `shouldReturn` Nothing
+
+      liftM head (parseFile "spec/fixtures/.dotenv") `shouldReturn`
+        ("DOTENV", "true")
+
+      lookupEnv "DOTENV" `shouldReturn` Nothing
+
+    it "recognizes unicode characters" $
+      liftM (!! 1) (parseFile "spec/fixtures/.dotenv") `shouldReturn`
+        ("UNICODE_TEST", "Manabí")
diff --git a/spec/fixtures/.dotenv b/spec/fixtures/.dotenv
--- a/spec/fixtures/.dotenv
+++ b/spec/fixtures/.dotenv
@@ -1,1 +1,2 @@
 DOTENV=true
+UNICODE_TEST=Manabí
diff --git a/src/Configuration/Dotenv.hs b/src/Configuration/Dotenv.hs
--- a/src/Configuration/Dotenv.hs
+++ b/src/Configuration/Dotenv.hs
@@ -1,16 +1,29 @@
-module Configuration.Dotenv (load, loadFile) where
+-- |
+-- Module      :  Configuration.Dotenv
+-- Copyright   :  © 2015–2016 Stack Builders Inc.
+-- License     :  MIT
+--
+-- Maintainer  :  Stack Builders <hackage@stackbuilders.com>
+-- Stability   :  experimental
+-- Portability :  portable
+--
+-- This module contains common functions to load and read dotenv files.
 
+module Configuration.Dotenv (load, loadFile, parseFile) where
+
 import System.Environment.Compat (lookupEnv, setEnv)
 
 import Configuration.Dotenv.Parse (configParser)
 
-import Text.Parsec (parse)
+import Text.Megaparsec (parse)
 
+import qualified Data.Text as T
+
 -- | Loads the given list of options into the environment. Optionally
 -- override existing variables with values from Dotenv files.
 load ::
   Bool -- ^ Override existing settings?
-  -> [(String, String)] -- ^ List of values to be set in environment
+  -> [(T.Text, T.Text)] -- ^ List of values to be set in environment
   -> IO ()
 load override = mapM_ (applySetting override)
 
@@ -20,22 +33,31 @@
   Bool        -- ^ Override existing settings?
   -> FilePath -- ^ A file containing options to load into the environment
   -> IO ()
-loadFile override f = do
+loadFile override f = load override =<< parseFile f
+
+-- | Parses the given dotenv file and returns values /without/ adding them to
+-- the environment.
+parseFile ::
+  FilePath -- ^ A file containing options to read
+  -> IO [(T.Text, T.Text)] -- ^ Variables contained in the file
+parseFile f = do
   contents <- readFile f
 
-  case parse configParser f contents of
+  case parse configParser f (T.pack contents) of
     Left e        -> error $ "Failed to read file" ++ show e
-    Right options -> load override options
-
+    Right options -> return options
 
-applySetting :: Bool -> (String, String) -> IO ()
+applySetting :: Bool -> (T.Text, T.Text) -> IO ()
 applySetting override (key, value) =
   if override then
-    setEnv key value
+    setEnv key' value'
 
   else do
-    res <- lookupEnv key
+    res <- lookupEnv key'
 
     case res of
-      Nothing -> setEnv key value
+      Nothing -> setEnv key' value'
       Just _  -> return ()
+
+    where key'   = T.unpack key
+          value' = T.unpack value
diff --git a/src/Configuration/Dotenv/Parse.hs b/src/Configuration/Dotenv/Parse.hs
--- a/src/Configuration/Dotenv/Parse.hs
+++ b/src/Configuration/Dotenv/Parse.hs
@@ -1,67 +1,84 @@
+-- |
+-- Module      :  Configuration.Dotenv.Parse
+-- Copyright   :  © 2015–2016 Stack Builders Inc.
+-- License     :  MIT
+--
+-- Maintainer  :  Stack Builders <hackage@stackbuilders.com>
+-- Stability   :  experimental
+-- Portability :  portable
+--
+-- Parser for files in dotenv format. These files generally consist of lines
+-- with the form key=value. Comments and blank lines are also supported. More
+-- information on the dotenv format can be found in the project README and the
+-- test suite.
+
 module Configuration.Dotenv.Parse (configParser) where
 
-import Text.Parsec ((<|>), (<?>), anyChar, char, many, manyTill, try)
-import Text.Parsec.Combinator (eof)
-import Text.Parsec.String (Parser)
-import Text.ParserCombinators.Parsec.Char
-  (digit, letter, newline, noneOf, oneOf)
+import Text.Megaparsec ((<?>), anyChar, char, eof, manyTill, try)
+import Text.Megaparsec.Text (Parser)
+import Text.Megaparsec.Char
+  (digitChar, letterChar, newline, noneOf, oneOf)
 
-import Control.Applicative ((<*), (*>), (<$>))
+import Control.Applicative
+import Prelude
+
 import Data.Maybe (catMaybes)
-import Control.Monad (liftM2)
+import Control.Monad (liftM, liftM2)
 
+import qualified Data.Text as T
+
 -- | Returns a parser for a Dotenv configuration file.  Accepts key
 -- and value arguments separated by "=".  Comments are allowed on
 -- lines by themselves and on blank lines.
-configParser :: Parser [(String, String)]
+configParser :: Parser [(T.Text, T.Text)]
 configParser = catMaybes <$> many envLine <* eof
 
 
-envLine :: Parser (Maybe (String, String))
+envLine :: Parser (Maybe (T.Text, T.Text))
 envLine = (comment <|> blankLine) *> return Nothing <|> Just <$> optionLine
 
-blankLine :: Parser String
-blankLine = many verticalSpace <* newline <?> "blank line"
+blankLine :: Parser T.Text
+blankLine = liftM T.pack (many verticalSpace <* newline) <?> "blank line"
 
-optionLine :: Parser (String, String)
+optionLine :: Parser (T.Text, T.Text)
 optionLine = liftM2 (,)
   (many verticalSpace *> variableName <* variableValueSeparator)
   value
 
 -- | Variables must start with a letter or underscore, and may contain
 -- letters, digits or '_' character after the first character.
-variableName :: Parser String
-variableName = liftM2 (:) (letter <|> char '_')
-  (many (letter <|> char '_' <|> digit <?>
+variableName :: Parser T.Text
+variableName = liftM T.pack (liftM2 (:) (letterChar <|> char '_')
+  (many (letterChar <|> char '_' <|> digitChar <?>
          unwords [ "valid non-leading shell variable character (alphanumeric,"
-                 , "digit or underscore)" ]))
+                 , "digit or underscore)" ])))
 
   <?> unwords [ "shell variable name (letter or underscore followed"
               , "by alphanumeric characters or underscores)" ]
 
-value :: Parser String
+value :: Parser T.Text
 value = quotedValue <|> unquotedValue <?> "variable value"
 
-quotedValue :: Parser String
+quotedValue :: Parser T.Text
 quotedValue = (quotedWith '\'' <|> quotedWith '\"')
   <* (comment *> return () <|> many verticalSpace *> endOfLineOrInput)
   <?> "variable value surrounded with single or double quotes"
 
-unquotedValue :: Parser String
+unquotedValue :: Parser T.Text
 unquotedValue =
-  manyTill anyChar (comment <|> many verticalSpace <* endOfLineOrInput)
+  liftM T.pack (manyTill anyChar (liftM T.unpack comment <|> many verticalSpace <* endOfLineOrInput))
 
 -- | Based on a commented-string parser in:
 -- http://hub.darcs.net/navilan/XMonadTasks/raw/Data/Config/Lexer.hs
-quotedWith :: Char -> Parser String
-quotedWith c = char c *> many chr <* (char c <?> "closing quote character")
+quotedWith :: Char -> Parser T.Text
+quotedWith c = liftM T.pack (char c *> many chr <* (char c <?> "closing quote character"))
 
   where chr = esc <|> noneOf [c]
         esc = escape *> char c <?> "escape character"
 
-comment :: Parser String
-comment = try (many verticalSpace *> char '#')
-          *> manyTill anyChar endOfLineOrInput
+comment :: Parser T.Text
+comment = liftM T.pack (try (many verticalSpace *> char '#')
+          *> manyTill anyChar endOfLineOrInput)
           <?> "comment"
 
 endOfLineOrInput :: Parser ()
