diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,7 @@
+# Revision history for monad-logger-extras
+
+## 0.1.0.0
+
+* First version.
+  * Composable loggers (with implementations for stdout, stderr, syslog)
+  * Orphan instances for Alternative and MonadPlus
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2020, Obsidian Systems LLC
+
+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 Obsidian Systems LLC 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.lhs b/README.lhs
new file mode 100644
--- /dev/null
+++ b/README.lhs
@@ -0,0 +1,39 @@
+monad-logger-extras
+===================
+[![Haskell](https://img.shields.io/badge/language-Haskell-orange.svg)](https://haskell.org) [![Hackage](https://img.shields.io/hackage/v/monad-logger-extras.svg)](https://hackage.haskell.org/package/monad-logger-extras) [![Hackage CI](https://matrix.hackage.haskell.org/api/v2/packages/monad-logger-extras/badge)](https://matrix.hackage.haskell.org/#/package/monad-logger-extras) [![Github CI](https://github.com/obsidiansystems/monad-logger-extras/workflows/github-action/badge.svg)](https://github.com/obsidiansystems/monad-logger-extras/actions) [![BSD3 License](https://img.shields.io/badge/license-BSD3-blue.svg)](https://github.com/obsidiansystems/monad-logger-extras/blob/master/LICENSE)
+
+Composable logging, syslog integration, and more with [monad-logger](https://hackage.haskell.org/package/monad-logger).
+
+Description
+-----------
+
+This package provides a way to compose logging actions so that you can conveniently log to multiple destinations. It also includes implementations of a few common logging actions: logging to stdout, stderr, nowhere (similar to `NoLoggingT`), and to a posix syslog (using [hsyslog](https://hackage.haskell.org/package/hsyslog)).
+
+It also contains a couple of orphan instances for [`LoggingT`](https://hackage.haskell.org/package/monad-logger-0.3.36/docs/Control-Monad-Logger.html#t:LoggingT): `MonadPlus` and `Alternative`.
+
+Example usage
+-------------
+
+Watch for the system log message by running:
+
+```bash
+journalctl --user -t log-test -f
+```
+
+This example can be built and run using cabal (either `cabal repl example` or `cabal build example`).
+
+
+```haskell
+
+> {-# LANGUAGE OverloadedStrings #-}
+> 
+> import Control.Monad.Logger
+> import Control.Monad.Logger.Extras
+> 
+> main :: IO ()
+> main = do
+>   let logger = logToStdout <> logToStderr <> logToSyslog "log-test"
+>   flip runLoggerLoggingT logger $ do
+>     logInfoN "This is a test. You should see this on stdout, stderr, and in your system log."
+
+```
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,39 @@
+monad-logger-extras
+===================
+[![Haskell](https://img.shields.io/badge/language-Haskell-orange.svg)](https://haskell.org) [![Hackage](https://img.shields.io/hackage/v/monad-logger-extras.svg)](https://hackage.haskell.org/package/monad-logger-extras) [![Hackage CI](https://matrix.hackage.haskell.org/api/v2/packages/monad-logger-extras/badge)](https://matrix.hackage.haskell.org/#/package/monad-logger-extras) [![Github CI](https://github.com/obsidiansystems/monad-logger-extras/workflows/github-action/badge.svg)](https://github.com/obsidiansystems/monad-logger-extras/actions) [![BSD3 License](https://img.shields.io/badge/license-BSD3-blue.svg)](https://github.com/obsidiansystems/monad-logger-extras/blob/master/LICENSE)
+
+Composable logging, syslog integration, and more with [monad-logger](https://hackage.haskell.org/package/monad-logger).
+
+Description
+-----------
+
+This package provides a way to compose logging actions so that you can conveniently log to multiple destinations. It also includes implementations of a few common logging actions: logging to stdout, stderr, nowhere (similar to `NoLoggingT`), and to a posix syslog (using [hsyslog](https://hackage.haskell.org/package/hsyslog)).
+
+It also contains a couple of orphan instances for [`LoggingT`](https://hackage.haskell.org/package/monad-logger-0.3.36/docs/Control-Monad-Logger.html#t:LoggingT): `MonadPlus` and `Alternative`.
+
+Example usage
+-------------
+
+Watch for the system log message by running:
+
+```bash
+journalctl --user -t log-test -f
+```
+
+This example can be built and run using cabal (either `cabal repl example` or `cabal build example`).
+
+
+```haskell
+
+> {-# LANGUAGE OverloadedStrings #-}
+> 
+> import Control.Monad.Logger
+> import Control.Monad.Logger.Extras
+> 
+> main :: IO ()
+> main = do
+>   let logger = logToStdout <> logToStderr <> logToSyslog "log-test"
+>   flip runLoggerLoggingT logger $ do
+>     logInfoN "This is a test. You should see this on stdout, stderr, and in your system log."
+
+```
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/monad-logger-extras.cabal b/monad-logger-extras.cabal
new file mode 100644
--- /dev/null
+++ b/monad-logger-extras.cabal
@@ -0,0 +1,55 @@
+cabal-version:      >=1.10
+name:               monad-logger-extras
+version:            0.1.0.0
+synopsis:
+  Utilities for composing loggers, plus a few orphan instances.
+
+description:
+  Build composable logging backends for monad-logger. This package includes a few composable backends (including a posix syslog backend).
+
+homepage:           https://github.com/obsidiansystems/monad-logger-extras
+bug-reports:
+  https://github.com/obsidiansystems/monad-logger-extras/issues
+
+license:            BSD3
+license-file:       LICENSE
+author:             Obsidian Systems LLC
+maintainer:         maintainer@obsidian.systems
+copyright:          2020 Obsidian Systems LLC
+category:           System
+build-type:         Simple
+extra-source-files:
+  CHANGELOG.md
+  README.md
+
+tested-with:        GHC ==8.6.5 || ==8.8.4 || ==8.10.2
+
+library
+  exposed-modules:
+    Control.Monad.Logger.Extras
+    Control.Monad.Logger.Orphans
+
+  build-depends:
+      base          >=4.12   && <5
+    , bytestring    >=0.10   && <0.12
+    , hsyslog       >=5      && <5.1
+    , monad-logger  >=0.3.36 && <0.4
+    , mtl           >=2.2    && <2.3
+
+  hs-source-dirs:   src
+  default-language: Haskell2010
+  ghc-options:      -Wall
+
+executable readme
+  build-depends:
+      base
+    , monad-logger
+    , monad-logger-extras
+
+  default-language: Haskell2010
+  main-is:          README.lhs
+  ghc-options:      -Wall -optL -q
+
+source-repository head
+  type:     git
+  location: git://github.com/obsidiansystems/monad-logger-extras
diff --git a/src/Control/Monad/Logger/Extras.hs b/src/Control/Monad/Logger/Extras.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/Logger/Extras.hs
@@ -0,0 +1,52 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-|
+Description: Composable logging actions for monad-logger, with a few predefined loggers.
+|-}
+module Control.Monad.Logger.Extras where
+
+import Control.Monad.Logger
+
+import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
+import System.IO
+import qualified System.Posix.Syslog as Posix
+
+-- | Run a 'LoggingT' action using the provided 'Logger'
+runLoggerLoggingT :: LoggingT m a -> Logger -> m a
+runLoggerLoggingT f logger = f `runLoggingT` unLogger logger
+
+-- | Type synonym for a logging action. See 'defaultLogStr' for the default
+-- formatting of this data.
+type LogF = Loc -> LogSource -> LogLevel -> LogStr -> IO ()
+
+-- | A composable logging action.
+newtype Logger = Logger { unLogger :: LogF }
+  deriving (Semigroup, Monoid)
+
+-- | Composable stderr logging action.
+logToStderr :: Logger
+logToStderr = Logger $ defaultOutput stderr
+
+-- | Composable stdout logging action.
+logToStdout :: Logger
+logToStdout = Logger $ defaultOutput stdout
+
+-- | This logger doesn't perform any logging action.
+logToNowhere :: Logger
+logToNowhere = mempty
+
+-- | Log messages to a posix system log. The string argument is a tag that can
+-- be used to identify log messages produced by this logger.
+-- You can, for instance, run @journalctl --user -t mytag@ to see log messages
+-- tagged with @"mytag"@.
+logToSyslog :: String -> Logger
+logToSyslog tagstr = Logger $ \loc src lvl str -> do
+  let syslogPriority = case lvl of
+        LevelDebug -> Posix.Debug
+        LevelInfo -> Posix.Info
+        LevelWarn -> Posix.Warning
+        LevelError -> Posix.Error
+        LevelOther _ -> Posix.Info
+      out = defaultLogStr loc src lvl str
+  Posix.withSyslog tagstr [Posix.DelayedOpen] Posix.User $
+    unsafeUseAsCStringLen (fromLogStr out) $
+      Posix.syslog Nothing syslogPriority
diff --git a/src/Control/Monad/Logger/Orphans.hs b/src/Control/Monad/Logger/Orphans.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/Logger/Orphans.hs
@@ -0,0 +1,17 @@
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+{-|
+Description: Orphan instances for monad-logger's LoggingT
+|-}
+module Control.Monad.Logger.Orphans where
+
+import Control.Monad.Logger
+
+import Control.Applicative (Alternative(..))
+import Control.Monad (MonadPlus(..))
+import Control.Monad.Trans (lift)
+
+instance (Monad m, Alternative m) => Alternative (LoggingT m) where
+  empty = lift empty
+  a <|> b = LoggingT $ \r -> let LoggingT f' = a <|> b in f' r
+
+instance (Monad m, Alternative m) => MonadPlus (LoggingT m)
