diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+Copyright 2017 Lyndon Maydwell
+
+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,37 @@
+## Servant-Options
+
+This library provides a middleware that returns `HTTP OPTIONS` responses for
+valid application routes defined by your (Proxy :: Proxy api).
+It is especially useful when trying to write an API that can be used
+in a cross-origin capacity, as browsers will send "pre-flight" checks
+by requesting OPTIONS for routes that are about to be called.
+
+Before:
+
+![](https://github.com/sordina/servant-options/blob/master/images/before.png?raw=true)
+
+After:
+
+![](https://github.com/sordina/servant-options/blob/master/images/after.png?raw=true)
+
+Usage:
+
+    module MyApp where
+
+    import App
+    import Servant
+    import Network.Wai.Middleware.Cors
+    import Network.Wai.Middleware.Servant.Options
+
+    app :: Application
+    app = logStdoutDev
+        $ cors (const $ Just policy)
+        $ provideOptions apiProxy
+        $ serve apiProxy apiServer
+      where
+      policy = simpleCorsResourcePolicy
+               { corsRequestHeaders = [ "content-type" ] }
+
+## See Also
+
+* <https://github.com/haskell-servant/servant/issues/278>
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/servant-options.cabal b/servant-options.cabal
new file mode 100644
--- /dev/null
+++ b/servant-options.cabal
@@ -0,0 +1,35 @@
+-- This file has been generated from package.yaml by hpack version 0.15.0.
+--
+-- see: https://github.com/sol/hpack
+
+name:           servant-options
+version:        0.1.0.0
+synopsis:       Provide responses to OPTIONS requests for Servant applications.
+description:    Provide responses to OPTIONS requests for Servant applications.
+category:       Web
+homepage:       https://github.com/sordina/servant-options
+author:         Lyndon Maydwell
+maintainer:     maydwell@gmail.com
+copyright:      2017 Lyndon Maydwell
+license:        MIT
+license-file:   LICENSE
+build-type:     Simple
+cabal-version:  >= 1.10
+
+extra-source-files:
+    README.md
+
+library
+  hs-source-dirs:
+      src
+  build-depends:
+      base >= 4.7 && < 5
+    , servant-server
+    , servant-foreign
+    , wai
+    , bytestring
+    , text
+    , http-types
+  exposed-modules:
+      Network.Wai.Middleware.Servant.Options
+  default-language: Haskell2010
diff --git a/src/Network/Wai/Middleware/Servant/Options.hs b/src/Network/Wai/Middleware/Servant/Options.hs
new file mode 100644
--- /dev/null
+++ b/src/Network/Wai/Middleware/Servant/Options.hs
@@ -0,0 +1,57 @@
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+-- |
+-- A middleware to respond to Options requests for a servant app
+-- very helpful when trying to deal with pre-flight CORS requests.
+--
+module Network.Wai.Middleware.Servant.Options (provideOptions) where
+
+import Servant
+import Servant.Foreign
+import Network.Wai
+import Data.Text hiding (null, zipWith, length)
+import Network.HTTP.Types.Method
+import Data.Maybe
+import Data.List (nub)
+import Network.HTTP.Types
+import qualified Data.ByteString as B
+
+provideOptions :: (GenerateList NoContent (Foreign NoContent api), HasForeign NoTypes NoContent api)
+               => Proxy api -> Middleware
+provideOptions apiproxy app req cb
+  | rmeth == "OPTIONS" = optional cb prior pinfo mlist
+  | otherwise          = prior
+  where
+  rmeth = requestMethod req :: Method
+  pinfo = pathInfo      req :: [ Text ]
+  mlist = listFromAPI (Proxy :: Proxy NoTypes) (Proxy :: Proxy NoContent) apiproxy
+  prior = app req cb
+
+optional :: (Response -> r) -> r -> [Text] -> [Req NoContent] -> r
+optional cb prior ts rs
+  | null methods = prior
+  | otherwise    = cb (buildResponse methods)
+  where
+  methods = mapMaybe (getMethod ts) rs
+
+getMethod :: [Text] -> Req NoContent -> Maybe Method
+getMethod rs ps
+  | sameLength && matchingSegments = Just (_reqMethod ps)
+  | otherwise                      = Nothing
+  where
+  pattern          = _path $ _reqUrl ps
+  sameLength       = length rs == length pattern
+  matchingSegments = and $ zipWith matchSegment rs pattern
+
+matchSegment :: Text -> Segment NoContent -> Bool
+matchSegment a (Segment (Static (PathSegment b)) ) | a /= b = False
+matchSegment _ _                                            = True
+
+buildResponse :: [Method] -> Response
+buildResponse ms = responseBuilder s h mempty
+  where
+  s = Status 200 "OK"
+  m = B.intercalate ", " ("OPTIONS" : nub ms)
+  h = [ ("Allow", m) ]
+
