diff --git a/.travis.yml b/.travis.yml
new file mode 100644
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,112 @@
+# This Travis job script has been generated by a script via
+#
+#   runghc make_travis_yml_2.hs 'loglevel.cabal'
+#
+# For more information, see https://github.com/haskell-CI/haskell-ci
+#
+language: c
+sudo: false
+
+git:
+  submodules: false  # whether to recursively clone submodules
+
+cache:
+  directories:
+    - $HOME/.cabal/packages
+    - $HOME/.cabal/store
+
+before_cache:
+  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/build-reports.log
+  # remove files that are regenerated by 'cabal update'
+  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/00-index.*
+  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/*.json
+  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/01-index.cache
+  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/01-index.tar
+  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/01-index.tar.idx
+
+  - rm -rfv $HOME/.cabal/packages/head.hackage
+
+matrix:
+  include:
+    - compiler: "ghc-8.4.3"
+    # env: TEST=--disable-tests BENCH=--disable-benchmarks
+      addons: {apt: {packages: [ghc-ppa-tools,cabal-install-2.2,ghc-8.4.3], sources: [hvr-ghc]}}
+    - compiler: "ghc-8.2.2"
+    # env: TEST=--disable-tests BENCH=--disable-benchmarks
+      addons: {apt: {packages: [ghc-ppa-tools,cabal-install-2.2,ghc-8.2.2], sources: [hvr-ghc]}}
+    - compiler: "ghc-8.0.2"
+    # env: TEST=--disable-tests BENCH=--disable-benchmarks
+      addons: {apt: {packages: [ghc-ppa-tools,cabal-install-2.2,ghc-8.0.2], sources: [hvr-ghc]}}
+    - compiler: "ghc-7.10.3"
+    # env: TEST=--disable-tests BENCH=--disable-benchmarks
+      addons: {apt: {packages: [ghc-ppa-tools,cabal-install-2.2,ghc-7.10.3], sources: [hvr-ghc]}}
+
+before_install:
+  - HC=${CC}
+  - HCPKG=${HC/ghc/ghc-pkg}
+  - unset CC
+  - ROOTDIR=$(pwd)
+  - mkdir -p $HOME/.local/bin
+  - "PATH=/opt/ghc/bin:/opt/ghc-ppa-tools/bin:$HOME/local/bin:$PATH"
+  - HCNUMVER=$(( $(${HC} --numeric-version|sed -E 's/([0-9]+)\.([0-9]+)\.([0-9]+).*/\1 * 10000 + \2 * 100 + \3/') ))
+  - echo $HCNUMVER
+
+install:
+  - cabal --version
+  - echo "$(${HC} --version) [$(${HC} --print-project-git-commit-id 2> /dev/null || echo '?')]"
+  - BENCH=${BENCH---enable-benchmarks}
+  - TEST=${TEST---enable-tests}
+  - HADDOCK=${HADDOCK-true}
+  - UNCONSTRAINED=${UNCONSTRAINED-true}
+  - NOINSTALLEDCONSTRAINTS=${NOINSTALLEDCONSTRAINTS-false}
+  - GHCHEAD=${GHCHEAD-false}
+  - travis_retry cabal update -v
+  - "sed -i.bak 's/^jobs:/-- jobs:/' ${HOME}/.cabal/config"
+  - rm -fv cabal.project cabal.project.local
+  - grep -Ev -- '^\s*--' ${HOME}/.cabal/config | grep -Ev '^\s*$'
+  - "printf 'packages: \".\"\\n' > cabal.project"
+  - touch cabal.project.local
+  - "if ! $NOINSTALLEDCONSTRAINTS; then for pkg in $($HCPKG list --simple-output); do echo $pkg  | grep -vw -- loglevel | sed 's/^/constraints: /' | sed 's/-[^-]*$/ installed/' >> cabal.project.local; done; fi"
+  - cat cabal.project || true
+  - cat cabal.project.local || true
+  - if [ -f "./configure.ac" ]; then
+      (cd "." && autoreconf -i);
+    fi
+  - rm -f cabal.project.freeze
+  - cabal new-build -w ${HC} ${TEST} ${BENCH} --project-file="cabal.project" --dep -j2 all
+  - cabal new-build -w ${HC} --disable-tests --disable-benchmarks --project-file="cabal.project" --dep -j2 all
+  - rm -rf .ghc.environment.* "."/dist
+  - DISTDIR=$(mktemp -d /tmp/dist-test.XXXX)
+
+# Here starts the actual work to be performed for the package under test;
+# any command which exits with a non-zero exit code causes the build to fail.
+script:
+  # test that source-distributions can be generated
+  - (cd "." && cabal sdist)
+  - mv "."/dist/loglevel-*.tar.gz ${DISTDIR}/
+  - cd ${DISTDIR} || false
+  - find . -maxdepth 1 -name '*.tar.gz' -exec tar -xvf '{}' \;
+  - "printf 'packages: loglevel-*/*.cabal\\n' > cabal.project"
+  - touch cabal.project.local
+  - "if ! $NOINSTALLEDCONSTRAINTS; then for pkg in $($HCPKG list --simple-output); do echo $pkg  | grep -vw -- loglevel | sed 's/^/constraints: /' | sed 's/-[^-]*$/ installed/' >> cabal.project.local; done; fi"
+  - cat cabal.project || true
+  - cat cabal.project.local || true
+  # this builds all libraries and executables (without tests/benchmarks)
+  - cabal new-build -w ${HC} --disable-tests --disable-benchmarks all
+
+  # build & run tests, build benchmarks
+  - cabal new-build -w ${HC} ${TEST} ${BENCH} all
+  - cabal new-test -w ${HC} all
+
+  # cabal check
+  - (cd loglevel-* && cabal check)
+
+  # haddock
+  - rm -rf ./dist-newstyle
+  - if $HADDOCK; then cabal new-haddock -w ${HC} ${TEST} ${BENCH} all; else echo "Skipping haddock generation";fi
+
+  # Build without installed constraints for packages in global-db
+  - if $UNCONSTRAINED; then rm -f cabal.project.local; echo cabal new-build -w ${HC} --disable-tests --disable-benchmarks all; else echo "Not building without installed constraints"; fi
+
+# REGENDATA ["loglevel.cabal"]
+# EOF
diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,5 @@
+# Revision history for loglevel
+
+## 0.1.0.0 -- 2018-08-29
+
+* First version.
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2018 Lars Kuhtz
+
+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,42 @@
+[![Build Status](https://travis-ci.org/larskuhtz/loglevel.svg?branch=master)](https://travis-ci.org/larskuhtz/loglevel)
+
+# Log Level Datatype
+
+This package provides a Haskell log-level datatype. It allows to specify APIs
+with logging-callbacks without depending on a particular logging framework.
+
+There is a large number of different Haskell logging frameworks that support
+different use cases and backends. As a consequence these framework make
+different trade-offs with respect to their architecture and implementation.
+Often they have complex internals and many external dependencies.
+
+While logging frameworks differ a lot in their internals and backends, they tend
+to have similar frontends. In particular, many software components depend for
+logging only on a callback function that typically has a type similar to
+
+```haskell
+loggingCallback ∷ LogLevel → Text → IO ()
+```
+
+The only framework-specific dependency is the `LogLevel` type. This type is in
+most cases similar, often isomorphic, and sometimes even identical across
+different frameworks.
+
+It is unfortunate that a software component has to depend on a particular
+logging framework (and all of the frameworks dependencies) just for using the
+`LogLevel` type that is almost identical throughout most logging frameworks.
+
+This package allows software components to include logging callbacks in their
+APIs without depending on a particular logging framework.
+
+---
+
+Even more complex logging callbacks often have a type along the lines of
+
+```haskell
+genericLoggingCallback ∷ c a ⇒ LogLevel → a → IO ()
+```
+
+where `c` is a constraint made up from common type classes like `ToJSON`,
+`Serializable`, `NFData`, or `Generic`.
+
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/loglevel.cabal b/loglevel.cabal
new file mode 100644
--- /dev/null
+++ b/loglevel.cabal
@@ -0,0 +1,53 @@
+name: loglevel
+version: 0.1.0.0
+synopsis: Log Level Datatype
+description:
+    The package provides a LogLevel type for defining logging callbacks without
+    depending on a particular logging framework.
+homepage: https://github.com/larskuhtz/loglevel
+bug-reports: https://github.com/larskuhtz/loglevel/issues
+license: MIT
+license-file: LICENSE
+author: Lars Kuhtz
+maintainer: lakuhtz@gmail.com
+copyright: Copyright (C) 2018 Lars Kuhtz <lakuhtz@gmail.com>
+category: System
+build-type: Simple
+extra-source-files: ChangeLog.md
+cabal-version: >=1.10
+tested-with:
+      GHC == 8.4.3
+    , GHC == 8.2.2
+    , GHC == 8.0.2
+    , GHC == 7.10.3
+
+extra-source-files:
+    ChangeLog.md
+    README.md
+    .travis.yml
+
+source-repository head
+    type: git
+    location: https://github.com/larskuhtz/loglevel
+
+library
+    default-language: Haskell2010
+    hs-source-dirs: src
+    ghc-options: -Wall
+    exposed-modules: System.LogLevel
+    build-depends:
+          base >=4.7 && <5.0
+        , text >= 1.0
+        , deepseq >= 1.4
+
+test-suite tests
+    type: exitcode-stdio-1.0
+    default-language: Haskell2010
+    hs-source-dirs: test
+    ghc-options: -Wall
+    main-is: Tests.hs
+    build-depends:
+          loglevel
+        , base >=4.7 && <5.0
+        , text >= 1.0
+
diff --git a/src/System/LogLevel.hs b/src/System/LogLevel.hs
new file mode 100644
--- /dev/null
+++ b/src/System/LogLevel.hs
@@ -0,0 +1,54 @@
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE UnicodeSyntax #-}
+
+-- |
+-- Module: System.LogLevel
+-- Copyright: Copyright © 2018 Lars Kuhtz <lakuhtz@gmail.com>
+-- License: MIT
+-- Maintainer: Lars Kuhtz <lakuhtz@gmail.com>
+-- Stability: experimental
+--
+-- Log Level Datatype
+--
+module System.LogLevel
+( LogLevel(..)
+, logLevelToText
+, logLevelFromText
+) where
+
+import Control.DeepSeq
+
+import Data.Char
+import Data.String
+import qualified Data.Text as T
+
+import GHC.Generics
+
+data LogLevel
+    = Quiet
+    | Error
+    | Warn
+    | Info
+    | Debug
+    | Other T.Text
+    deriving (Show, Read, Eq, Ord, Generic)
+
+instance NFData LogLevel
+
+instance IsString LogLevel where
+    fromString s = case toLower <$> s of
+        "quiet" → Quiet
+        "error" → Error
+        "warn" → Warn
+        "info" → Info
+        "debug" → Debug
+        _ → Other (T.pack s)
+
+logLevelToText ∷ IsString a ⇒ LogLevel → a
+logLevelToText (Other t) = fromString $ T.unpack t
+logLevelToText l = fromString $ toLower <$> show l
+
+logLevelFromText ∷ T.Text → LogLevel
+logLevelFromText = fromString . T.unpack
+
diff --git a/test/Tests.hs b/test/Tests.hs
new file mode 100644
--- /dev/null
+++ b/test/Tests.hs
@@ -0,0 +1,61 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE UnicodeSyntax #-}
+
+-- |
+-- Module: Main
+-- Copyright: Copyright © 2018 Lars Kuhtz <lakuhtz@gmail>
+-- License: MIT
+-- Maintainer: Lars Kuhtz <lakuhtz@gmail>
+-- Stability: experimental
+--
+module Main
+( main
+) where
+
+import Data.Bifunctor
+import Data.Char
+import Data.String
+import qualified Data.Text as T
+
+import System.LogLevel
+
+main ∷ IO Int
+main = sum <$> sequence
+    [ test "logLevelToText" test_logLevelToText
+    , test "logLevelFromText1" test_logLevelFromText1
+    , test "logLevelFromText2" test_logLevelFromText2
+    ]
+
+test ∷ String → Bool → IO Int
+test t True = 0 <$ putStrLn (t ++ " passed")
+test t False = 1 <$ putStrLn (t ++ " failed")
+
+logLevelText ∷ IsString a ⇒ [(LogLevel, a)]
+logLevelText =
+    [ (Error, "error")
+    , (Quiet, "quiet")
+    , (Warn, "warn")
+    , (Info, "info")
+    , (Debug, "debug")
+    , (Other "", "")
+    , (Other "Abc Xyz", "Abc Xyz")
+    ]
+
+test_logLevelToText ∷ Bool
+test_logLevelToText = all check logLevelText
+  where
+    check ∷ (LogLevel, T.Text) → Bool
+    check = uncurry (==) . first logLevelToText
+
+test_logLevelFromText1 ∷ Bool
+test_logLevelFromText1 = all check logLevelText
+  where
+    check = uncurry (==) . second logLevelFromText
+
+test_logLevelFromText2 ∷ Bool
+test_logLevelFromText2 = all check (init logLevelText)
+    && not (check $ last logLevelText)
+  where
+    check = uncurry (==)
+        . second (logLevelFromText . T.pack . fmap toUpper)
+
