diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,5 @@
+# CHANGELOG
+
+## v0.1.0.0
+
+* Initial release
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Pavan Rikhi (c) 2020
+
+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 Pavan Rikhi 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,83 @@
+# wai-middleware-clacks
+
+[![wai-middleware-clacks Build Status](https://travis-ci.org/prikhi/wai-middleware-clacks.svg?branch=master)](https://travis-ci.org/prikhi/wai-middleware-clacks)
+
+*"You know they'll never really die while the Trunk is alive."*
+
+`wai-middleware-clacks` is a middleware that inserts an arbitrary
+`X-Clacks-Overhead` header into every Wai response. From
+[GNU Terry Pratchett](http://gnuterrypratchett.com):
+
+> In Terry Pratchett's Discworld series, the clacks are a series of semaphore
+> towers loosely based on the concept of the telegraph. Invented by an
+> artificer named Robert Dearheart, the towers could send messages "at the
+> speed of light" using standardized codes. Three of these codes are of
+> particular import:
+>
+> * G: send the message on
+> * N: do not log the message
+> * U: turn the message around at the end of the line and send it back again
+>
+> When Dearheart's son John died due to an accident while working on a clacks
+> tower, Dearheart inserted John's name into the overhead of the clacks with a
+> "GNU" in front of it as a way to memorialize his son forever (or for at least
+> as long as the clacks are standing.)
+>
+> Keeping the legacy of Sir Terry Pratchett alive forever. For as long as his
+> name is still passed along the Clacks, Death can't have him.
+
+
+## Usage
+
+To use this package to keep the legacy of Terry Pratchett alive, simply pass
+your wai application to @clacks gnuTerryPratchett@ before passing it to the
+@run@ function:
+
+```haskell
+import Network.Wai.Handler.Warp (run)
+import Network.Wai.Middleware.Clacks (clacks, gnuTerryPratchett)
+
+import MyLib.App (myApp)
+
+main :: IO ()
+main = run 8080 $ clacks gnuTerryPratchett myApp
+```
+
+You can use the `Clacks` type to build a custom configuration for the `clacks`
+function, allowing you to pass anything into the header:
+
+```haskell
+import Data.List.NonEmpty (NonEmpty(..))
+import Network.Wai (Middleware)
+import Network.Wai.Middleware.Clacks (Clacks(..), clacks)
+
+myClacks :: Middleware
+myClacks = clacks $ Clacks $ "GNU Ada Lovelace" :| ["GNU Hoban Washburne", "GNU Shephard Book"]
+```
+
+
+## Build
+
+You can build the project with stack:
+
+```
+stack build
+```
+
+For development, you can enable fast builds with file-watching,
+documentation-building, & test-running:
+
+```
+stack test --haddock --fast --file-watch --pedantic
+```
+
+To build & open the documentation, run
+
+```
+stack haddock --open wai-middleware-clacks
+```
+
+
+## LICENSE
+
+BSD-3
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/Network/Wai/Middleware/Clacks.hs b/src/Network/Wai/Middleware/Clacks.hs
new file mode 100644
--- /dev/null
+++ b/src/Network/Wai/Middleware/Clacks.hs
@@ -0,0 +1,92 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-|
+The @Clacks@ middleware adds a @X-Clacks-Overhead@ header to every response
+served by a Wai server.
+
+To use this package to keep the legacy of Terry Pratchett alive, simply
+pass your wai application to @clacks gnuTerryPratchett@ before passing it
+to the @run@ function:
+
+> import Network.Wai.Handler.Warp (run)
+> import Network.Wai.Middleware.Clacks (clacks, gnuTerryPratchett)
+>
+> import MyLib.App (myApp)
+>
+> main :: IO ()
+> main = run 8080 $ clacks gnuTerryPratchett myApp
+
+You can use the 'Clacks' type to build a custom configuration for the
+'clacks' function, allowing you to pass anything into the header:
+
+> import Data.List.NonEmpty (NonEmpty(..))
+> import Network.Wai (Middleware)
+> import Network.Wai.Middleware.Clacks (Clacks(..), clacks)
+>
+> myClacks :: Middleware
+> myClacks = clacks $ Clacks $ "GNU Ada Lovelace" :| ["GNU Hoban Washburne", "GNU Shephard Book"]
+
+For more information about the Clacks or the @X-Clacks-Overhead@ header,
+check out the <http://www.gnuterrypratchett.com GNU Terry Pratchett website>.
+
+-}
+module Network.Wai.Middleware.Clacks
+    ( clacks
+    , Clacks(..)
+    , gnuTerryPratchett
+    , clacksHeaderName
+    )
+where
+
+import           Prelude.Compat
+
+import           Data.List.NonEmpty.Compat      ( NonEmpty(..)
+                                                , toList
+                                                )
+import           Data.Text.Encoding             ( encodeUtf8 )
+import           Network.HTTP.Types.Header      ( ResponseHeaders
+                                                , HeaderName
+                                                )
+import           Network.Wai                    ( Middleware
+                                                , modifyResponse
+                                                , mapResponseHeaders
+                                                )
+
+import qualified Data.ByteString               as BS
+import qualified Data.CaseInsensitive          as CI
+import qualified Data.List                     as L
+import qualified Data.Text                     as T
+
+
+-- | A "Network.Wai" 'Middleware' that adds a @X-Clacks-Overhead@ header
+-- containing the messages in the 'Clacks' configuration.
+clacks :: Clacks -> Middleware
+clacks settings = modifyResponse $ mapResponseHeaders addHeader
+  where
+    headerContents :: BS.ByteString
+    headerContents =
+        encodeUtf8 . T.intercalate "," . toList $ clacksMessages settings
+    addHeader :: ResponseHeaders -> ResponseHeaders
+    addHeader hs = case L.find ((== clacksHeaderName) . fst) hs of
+        Nothing      -> (clacksHeaderName, headerContents) : hs
+        Just (_, "") -> (clacksHeaderName, headerContents) : hs
+        Just (name, contents) ->
+            (name, contents <> "," <> headerContents)
+                : filter ((/= clacksHeaderName) . fst) hs
+
+-- | Configuration for the Clacks WAI Middleware.
+newtype Clacks =
+    Clacks
+        { clacksMessages :: NonEmpty T.Text
+        -- ^ The Clacks Messages to Include in the Header.
+        } deriving (Show, Read, Eq)
+
+
+-- | Sends a Clacks message of @GNU Terry Pratchett@.
+gnuTerryPratchett :: Clacks
+gnuTerryPratchett = Clacks $ "GNU Terry Pratchett" :| []
+
+
+-- | The name of the Clacks header.
+clacksHeaderName :: HeaderName
+clacksHeaderName = CI.mk "X-Clacks-Overhead"
diff --git a/tests/Spec.hs b/tests/Spec.hs
new file mode 100644
--- /dev/null
+++ b/tests/Spec.hs
@@ -0,0 +1,46 @@
+{-# LANGUAGE OverloadedStrings #-}
+import           Data.List.NonEmpty.Compat      ( NonEmpty(..) )
+import           Test.Tasty
+import           Test.Tasty.Wai
+import           Network.HTTP.Types             ( status200 )
+import           Network.Wai                    ( Application
+                                                , responseLBS
+                                                )
+
+import           Network.Wai.Middleware.Clacks
+
+main :: IO ()
+main = defaultMain tests
+
+
+tests :: TestTree
+tests = testGroup "Wai Tests" [testSingle, testMultiple, testExisting]
+  where
+    testSingle :: TestTree
+    testSingle = testWai (simpleApp gnuTerryPratchett) "Single Message" $ do
+        get "42" >>= assertHeader clacksHeaderName "GNU Terry Pratchett"
+    testMultiple :: TestTree
+    testMultiple =
+        let settings = Clacks $ "GNU Terry Pratchett" :| ["GNU Ada Lovelace"]
+        in  testWai (simpleApp settings) "Multiple Messages"
+                $   get "9001"
+                >>= assertHeader clacksHeaderName
+                                 "GNU Terry Pratchett,GNU Ada Lovelace"
+    testExisting :: TestTree
+    testExisting =
+        testWai (existingHeaderApp gnuTerryPratchett) "Existing Clacks Header"
+            $ do
+                  get "neko" >>= assertHeader
+                      clacksHeaderName
+                      "GNU Ada Lovelace,GNU Terry Pratchett"
+
+
+simpleApp :: Clacks -> Application
+simpleApp settings =
+    clacks settings $ \_ cb -> cb $ responseLBS status200 [] "Hello World"
+
+existingHeaderApp :: Clacks -> Application
+existingHeaderApp settings = clacks settings $ \_ cb -> cb $ responseLBS
+    status200
+    [(clacksHeaderName, "GNU Ada Lovelace")]
+    "Hello World"
diff --git a/wai-middleware-clacks.cabal b/wai-middleware-clacks.cabal
new file mode 100644
--- /dev/null
+++ b/wai-middleware-clacks.cabal
@@ -0,0 +1,101 @@
+cabal-version: 1.12
+
+-- This file has been generated from package.yaml by hpack version 0.33.0.
+--
+-- see: https://github.com/sol/hpack
+--
+-- hash: 895632c4795b860ff962c56d9e843f228030b41aadc1d8f3806e7fefbccc5229
+
+name:           wai-middleware-clacks
+version:        0.1.0.0
+synopsis:       GNU Terry Pratchett - Add the X-Clacks-Overhead Header to Wai Responses.
+description:    /"You know they'll never really die while the Trunk is alive."/
+                .
+                @wai-middleware-clacks@ is a middleware that inserts an arbitrary
+                @X-Clacks-Overhead@ header into every Wai response. From
+                <http://gnuterrypratchett.com GNU Terry Pratchett>:
+                .
+                > In Terry Pratchett's Discworld series, the clacks are a series of
+                > semaphore towers loosely based on the concept of the telegraph. Invented
+                > by an artificer named Robert Dearheart, the towers could send messages
+                > "at the speed of light" using standardized codes. Three of these codes
+                > are of particular import:
+                >
+                > G: send the message on
+                > N: do not log the message
+                > U: turn the message around at the end of the line and send it back again
+                >
+                > When Dearheart's son John died due to an accident while working on a
+                > clacks tower, Dearheart inserted John's name into the overhead of the
+                > clacks with a "GNU" in front of it as a way to memorialize his son forever
+                > (or for at least as long as the clacks are standing.)
+                >
+                >
+                > Keeping the legacy of Sir Terry Pratchett alive forever. For as long as
+                > his name is still passed along the Clacks, Death can't have him.
+                .
+                Please see the
+                <https://github.com/prikhi/wai-middleware-clacks/blob/master/README.md README>
+                or
+                <https://hackage.haskell.org/package/wai-middleware-clacks/docs/Network-Wai-Middleware-Clacks.html module documentation>
+                for usage instructions.
+category:       Web, Wai
+homepage:       https://github.com/prikhi/wai-middleware-clacks#readme
+bug-reports:    https://github.com/prikhi/wai-middleware-clacks/issues
+author:         Pavan Rikhi
+maintainer:     pavan.rikhi@gmail.com
+copyright:      2020 Pavan Rikhi
+license:        BSD3
+license-file:   LICENSE
+build-type:     Simple
+extra-source-files:
+    README.md
+    CHANGELOG.md
+
+source-repository head
+  type: git
+  location: https://github.com/prikhi/wai-middleware-clacks
+
+library
+  exposed-modules:
+      Network.Wai.Middleware.Clacks
+  other-modules:
+      Paths_wai_middleware_clacks
+  hs-source-dirs:
+      src
+  ghc-options: -Wall
+  build-depends:
+      base >=4.3 && <5
+    , base-compat-batteries
+    , bytestring
+    , case-insensitive
+    , http-types
+    , text
+    , wai
+  if impl(ghc >= 8.0)
+    ghc-options: -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints
+  else
+    ghc-options: -fwarn-incomplete-record-updates -fwarn-incomplete-uni-patterns
+  default-language: Haskell2010
+
+test-suite wai-middleware-clacks-test
+  type: exitcode-stdio-1.0
+  main-is: Spec.hs
+  other-modules:
+      Paths_wai_middleware_clacks
+  hs-source-dirs:
+      tests
+  ghc-options: -Wall -threaded -rtsopts -with-rtsopts "-N -T"
+  build-depends:
+      base >=4.3 && <5
+    , base-compat-batteries
+    , http-types
+    , tasty
+    , tasty-wai
+    , wai
+    , wai-middleware-clacks
+  if impl(ghc >= 8.0)
+    ghc-options: -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints
+  else
+    ghc-options: -fwarn-incomplete-record-updates -fwarn-incomplete-uni-patterns
+  default-language: Haskell2010
