diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,8 @@
+# Changelog for skylighting-lucid
+
+## 1.0.0 (2020-03-07)
+
+#### Added
+
+- Versions of `formatHtmlInline` and `formatHtmlBlock` that produce `lucid`
+  types instead of `blaze.`
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Colin Woodbury (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 Author name here 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,7 @@
+# skylighting-lucid
+
+This library extends the HTML capabilities of
+[skylighting](http://hackage.haskell.org/package/skylighting) to produce types
+from the [lucid](http://hackage.haskell.org/package/lucid) library.
+
+This can be used for server-side syntax highlighting of code samples.
diff --git a/lib/Skylighting/Format/HTML/Lucid.hs b/lib/Skylighting/Format/HTML/Lucid.hs
new file mode 100644
--- /dev/null
+++ b/lib/Skylighting/Format/HTML/Lucid.hs
@@ -0,0 +1,145 @@
+{-# LANGUAGE CPP               #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+module Skylighting.Format.HTML.Lucid
+  ( formatHtmlInline
+  , formatHtmlBlock
+  ) where
+
+import           Data.Foldable (traverse_)
+import qualified Data.List as L
+import qualified Data.Text as T
+import           Lucid
+import           Skylighting.Types
+
+#if !MIN_VERSION_base(4,11,0)
+import           Data.Semigroup
+#endif
+
+-- | Format tokens using HTML spans inside @code@ tags. For example,
+-- A @KeywordTok@ is rendered as a span with class @kw@.
+-- Short class names correspond to 'TokenType's as follows:
+-- 'KeywordTok'        = @kw@,
+-- 'DataTypeTok'       = @dt@,
+-- 'DecValTok'         = @dv@,
+-- 'BaseNTok'          = @bn@,
+-- 'FloatTok'          = @fl@,
+-- 'CharTok'           = @ch@,
+-- 'StringTok'         = @st@,
+-- 'CommentTok'        = @co@,
+-- 'OtherTok'          = @ot@,
+-- 'AlertTok'          = @al@,
+-- 'FunctionTok'       = @fu@,
+-- 'RegionMarkerTok'   = @re@,
+-- 'ErrorTok'          = @er@,
+-- 'ConstantTok'       = @cn@,
+-- 'SpecialCharTok'    = @sc@,
+-- 'VerbatimStringTok' = @vs@,
+-- 'SpecialStringTok'  = @ss@,
+-- 'ImportTok'         = @im@,
+-- 'DocumentationTok'  = @do@,
+-- 'AnnotationTok'     = @an@,
+-- 'CommentVarTok'     = @cv@,
+-- 'VariableTok'       = @va@,
+-- 'ControlFlowTok'    = @cf@,
+-- 'OperatorTok'       = @op@,
+-- 'BuiltInTok'        = @bu@,
+-- 'ExtensionTok'      = @ex@,
+-- 'PreprocessorTok'   = @pp@,
+-- 'AttributeTok'      = @at@,
+-- 'InformationTok'    = @in@,
+-- 'WarningTok'        = @wa@.
+-- A 'NormalTok' is not marked up at all.
+formatHtmlInline :: FormatOptions -> [SourceLine] -> Html ()
+formatHtmlInline opts =
+  -- wrapCode opts . mconcat . L.intersperse (toHtml "\n") . map (traverse_ (tokenToHtml opts))
+  wrapCode opts . mconcat . map (traverse_ (tokenToHtml opts))
+
+-- | Format tokens as an HTML @pre@ block. Each line is wrapped in an a element
+-- with the class ‘source-line’. If line numbering is selected, the surrounding
+-- pre is given the class ‘numberSource’, and the resulting html will display
+-- line numbers thanks to the included CSS. See the documentation for
+-- 'formatHtmlInline' for information about how tokens are encoded.
+formatHtmlBlock :: FormatOptions -> [SourceLine] -> Html ()
+formatHtmlBlock opts ls =
+  div_ [class_ "sourceCode"]
+  $ pre_ [classes_ classes]
+    $ wrapCode opts
+    $ mconcat
+    $ L.intersperse "\n"
+    $ zipWith (sourceLineToHtml opts) [startNum..] ls
+  where
+    classes :: [T.Text]
+    classes = "sourceCode"
+      :  ["numberSource" | numberLines opts]
+      ++ [x | x <- containerClasses opts, x /= "sourceCode"]
+
+    startNum :: LineNo
+    startNum = LineNo $ startNumber opts
+
+wrapCode :: FormatOptions -> Html () -> Html ()
+wrapCode opts h =
+  code_ [classes_ $ "sourceCode" : codeClasses opts] h
+                         -- !? (startZero /= 0, A.style (toValue counterOverride))
+                         -- $ h
+  -- where
+  --   counterOverride :: String
+  --   counterOverride = "counter-reset: source-line " <> show startZero <> ";"
+
+  --   startZero :: Int
+    -- startZero = startNumber opts - 1
+
+-- | Each line of source is wrapped in an (inline-block) anchor that makes
+-- subsequent per-line processing (e.g. adding line numnbers) possible.
+sourceLineToHtml :: FormatOptions -> LineNo -> SourceLine -> Html ()
+sourceLineToHtml opts lno cont = span_ [id_ prefixedLineNo] $ do
+  a_ [href_ lineRef] ""
+  traverse_ (tokenToHtml opts) cont
+  where
+    lineRef :: T.Text
+    lineRef = T.cons '#' prefixedLineNo
+
+    prefixedLineNo :: T.Text
+    prefixedLineNo = lineIdPrefix opts <> T.pack (show $ lineNo lno)
+
+tokenToHtml :: FormatOptions -> Token -> Html ()
+tokenToHtml _ (NormalTok, txt) = toHtml txt
+tokenToHtml opts (toktype, txt)
+  | titleAttributes opts = sp -- ! A.title (toValue $ show toktype)
+  | otherwise = sp
+  where
+    sp :: Html ()
+    sp = span_ [class_ $ short toktype] $ toHtml txt
+
+short :: TokenType -> T.Text
+short KeywordTok        = "kw"
+short DataTypeTok       = "dt"
+short DecValTok         = "dv"
+short BaseNTok          = "bn"
+short FloatTok          = "fl"
+short CharTok           = "ch"
+short StringTok         = "st"
+short CommentTok        = "co"
+short OtherTok          = "ot"
+short AlertTok          = "al"
+short FunctionTok       = "fu"
+short RegionMarkerTok   = "re"
+short ErrorTok          = "er"
+short ConstantTok       = "cn"
+short SpecialCharTok    = "sc"
+short VerbatimStringTok = "vs"
+short SpecialStringTok  = "ss"
+short ImportTok         = "im"
+short DocumentationTok  = "do"
+short AnnotationTok     = "an"
+short CommentVarTok     = "cv"
+short VariableTok       = "va"
+short ControlFlowTok    = "cf"
+short OperatorTok       = "op"
+short BuiltInTok        = "bu"
+short ExtensionTok      = "ex"
+short PreprocessorTok   = "pp"
+short AttributeTok      = "at"
+short InformationTok    = "in"
+short WarningTok        = "wa"
+short NormalTok         = ""
diff --git a/skylighting-lucid.cabal b/skylighting-lucid.cabal
new file mode 100644
--- /dev/null
+++ b/skylighting-lucid.cabal
@@ -0,0 +1,32 @@
+cabal-version:      2.0
+name:               skylighting-lucid
+version:            1.0.0
+synopsis:           Lucid support for Skylighting
+description:        Lucid support for Skylighting
+category:           Web
+homepage:           https://github.com/fosskers/skylighting-lucid
+author:             Colin Woodbury
+maintainer:         colin@fosskers.ca
+copyright:          2020 Colin Woodbury
+license:            BSD3
+license-file:       LICENSE
+build-type:         Simple
+extra-source-files:
+  README.md
+  ChangeLog.md
+
+library
+  default-language: Haskell2010
+  hs-source-dirs:   lib
+  ghc-options:
+    -Wall -Wpartial-fields -Wincomplete-record-updates
+    -Wincomplete-uni-patterns -Widentities
+
+  build-depends:
+      base              >=4.7 && <5
+    , containers
+    , lucid             ^>=2.9
+    , skylighting-core  ^>=0.8
+    , text
+
+  exposed-modules:  Skylighting.Format.HTML.Lucid
