diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Matthew Parsons (c) 2016
+
+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 Matthew Parsons 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/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/reflex-dom-helpers.cabal b/reflex-dom-helpers.cabal
new file mode 100644
--- /dev/null
+++ b/reflex-dom-helpers.cabal
@@ -0,0 +1,47 @@
+name:                reflex-dom-helpers
+version:             0.1.0.0
+synopsis:            Element tag helpers for working with reflex-dom
+description:         Please see README.md
+homepage:            https://github.com/layer-3-communications/reflex-dom-helpers
+license:             BSD3
+license-file:        LICENSE
+author:              Matthew Parsons
+maintainer:          parsonsmatt@gmail.com
+copyright:           2016 Matthew Parsons
+category:            Web
+build-type:          Simple
+cabal-version:       >=1.10
+
+library
+  hs-source-dirs:      src
+  exposed-modules:
+      Reflex.Tags
+    , Reflex.Tags.Simple
+    , Reflex.Tags.SimplePrime
+    , Reflex.Tags.Attr
+    , Reflex.Tags.AttrPrime
+    , Reflex.Tags.DynAttr
+    , Reflex.Tags.DynAttrPrime
+    , Reflex.Tags.TH
+  build-depends:
+      base >= 4.7 && < 5
+    , reflex
+    , reflex-dom
+    , template-haskell
+  default-language:    Haskell2010
+  default-extensions:
+      TemplateHaskell
+      NoMonomorphismRestriction
+
+test-suite reflex-dom-helpers-test
+  type:                exitcode-stdio-1.0
+  hs-source-dirs:      test
+  main-is:             Spec.hs
+  build-depends:       base
+                     , reflex-dom-helpers
+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
+  default-language:    Haskell2010
+
+source-repository head
+  type:     git
+  location: https://github.com/layer-3-communications/reflex-dom-helpers
diff --git a/src/Reflex/Tags.hs b/src/Reflex/Tags.hs
new file mode 100644
--- /dev/null
+++ b/src/Reflex/Tags.hs
@@ -0,0 +1,31 @@
+{-|
+Module      : Reflex.Tags
+Description : reflex-dom tags with function suffixes
+Copyright   : (c) Layer 3 Communications, 2016
+                  Matthew Parsons, 2016
+License     : BSD3
+Maintainer  : parsonsmatt@gmail.com
+Stability   : experimental
+Portability : POSIX
+
+This module exports all of the HTML tags in the various permutations generally
+used by reflex-dom with a suffix. The suffix prevents name collisions with
+Prelude functions. Following the example of "Lucid", ordinary elements have an
+underscore character appended to them. The other elements use the suffix that
+you'd normally add to 'el' to make.
+
+Here are a list of equivalences:
+
+* @'el' "p"@ to 'p_'
+* @'el'' "p"@ to 'p''
+* @'elAttr' "p"@ to 'pAttr'
+* @'elAttr'' "p"@ to 'pAttr''
+* @'elDynAttr'@ "p"@ to 'pDynAttr'
+* @'elDynAttr@' "p"' to 'pDynAttr''
+-}
+
+module Reflex.Tags where
+
+import Reflex.Tags.TH
+
+genTags
diff --git a/src/Reflex/Tags/Attr.hs b/src/Reflex/Tags/Attr.hs
new file mode 100644
--- /dev/null
+++ b/src/Reflex/Tags/Attr.hs
@@ -0,0 +1,21 @@
+{-|
+Module      : Reflex.Tags.Attr
+Description : reflex-dom attribute tags
+Copyright   : (c) Layer 3 Communications, 2016
+                  Matthew Parsons, 2016
+License     : BSD3
+Maintainer  : parsonsmatt@gmail.com
+Stability   : experimental
+Portability : POSIX
+
+This module is intended to be imported qualified.
+
+This module exports all of the HTML tags for the 'elAttr' function.
+-}
+module Reflex.Tags.Attr where
+
+import Prelude()
+import Reflex.Tags.TH
+import Reflex.Dom.Widget
+
+$(gen 'elAttr "")
diff --git a/src/Reflex/Tags/AttrPrime.hs b/src/Reflex/Tags/AttrPrime.hs
new file mode 100644
--- /dev/null
+++ b/src/Reflex/Tags/AttrPrime.hs
@@ -0,0 +1,22 @@
+{-|
+Module      : Reflex.Tags.AttrPrime
+Description : reflex-dom attribute tags
+Copyright   : (c) Layer 3 Communications, 2016
+                  Matthew Parsons, 2016
+License     : BSD3
+Maintainer  : parsonsmatt@gmail.com
+Stability   : experimental
+Portability : POSIX
+
+This module is intended to be imported qualified.
+
+This module exports all of the HTML tags for the 'elAttr\'' function.
+-}
+
+module Reflex.Tags.AttrPrime where
+
+import Prelude()
+import Reflex.Tags.TH
+import Reflex.Dom.Widget
+
+$(gen 'elAttr' "")
diff --git a/src/Reflex/Tags/DynAttr.hs b/src/Reflex/Tags/DynAttr.hs
new file mode 100644
--- /dev/null
+++ b/src/Reflex/Tags/DynAttr.hs
@@ -0,0 +1,21 @@
+{-|
+Module      : Reflex.Tags.DynAttr
+Description : reflex-dom attribute tags
+Copyright   : (c) Layer 3 Communications, 2016
+                  Matthew Parsons, 2016
+License     : BSD3
+Maintainer  : parsonsmatt@gmail.com
+Stability   : experimental
+Portability : POSIX
+
+This module is intended to be imported qualified.
+
+This module exports all of the HTML tags for the 'elDynAttr' function.
+-}
+module Reflex.Tags.DynAttr where
+
+import Prelude()
+import Reflex.Tags.TH
+import Reflex.Dom.Widget
+
+$(gen 'elDynAttr "")
diff --git a/src/Reflex/Tags/DynAttrPrime.hs b/src/Reflex/Tags/DynAttrPrime.hs
new file mode 100644
--- /dev/null
+++ b/src/Reflex/Tags/DynAttrPrime.hs
@@ -0,0 +1,21 @@
+{-|
+Module      : Reflex.Tags.DynAttrPrime
+Description : reflex-dom attribute tags
+Copyright   : (c) Layer 3 Communications, 2016
+                  Matthew Parsons, 2016
+License     : BSD3
+Maintainer  : parsonsmatt@gmail.com
+Stability   : experimental
+Portability : POSIX
+
+This module is intended to be imported qualified.
+
+This module exports all of the HTML tags for the 'elDynAttr\'' function.
+-}
+module Reflex.Tags.DynAttrPrime where
+
+import Prelude()
+import Reflex.Tags.TH
+import Reflex.Dom.Widget
+
+$(gen 'elDynAttr' "")
diff --git a/src/Reflex/Tags/Simple.hs b/src/Reflex/Tags/Simple.hs
new file mode 100644
--- /dev/null
+++ b/src/Reflex/Tags/Simple.hs
@@ -0,0 +1,23 @@
+{-|
+Module      : Reflex.Tags.Simple
+Description : reflex-dom simple tags
+Copyright   : (c) Layer 3 Communications, 2016
+                  Matthew Parsons, 2016
+License     : BSD3
+Maintainer  : parsonsmatt@gmail.com
+Stability   : experimental
+Portability : POSIX
+
+This module is intended to be imported qualified.
+
+This module exports all of the HTML tags for the 'el' function.
+-}
+
+module Reflex.Tags.Simple where
+
+import qualified Prelude as P
+
+import Reflex.Dom.Widget (el)
+import Reflex.Tags.TH
+
+gen 'el ""
diff --git a/src/Reflex/Tags/SimplePrime.hs b/src/Reflex/Tags/SimplePrime.hs
new file mode 100644
--- /dev/null
+++ b/src/Reflex/Tags/SimplePrime.hs
@@ -0,0 +1,22 @@
+{-|
+Module      : Reflex.Tags.SimplePrime
+Description : reflex-dom simple tags
+Copyright   : (c) Layer 3 Communications, 2016
+                  Matthew Parsons, 2016
+License     : BSD3
+Maintainer  : parsonsmatt@gmail.com
+Stability   : experimental
+Portability : POSIX
+
+This module is intended to be imported qualified.
+
+This module exports all of the HTML tags for the 'el\'' function.
+-}
+module Reflex.Tags.SimplePrime where
+
+import qualified Prelude as P
+
+import Reflex.Dom.Widget (el')
+import Reflex.Tags.TH
+
+gen 'el' ""
diff --git a/src/Reflex/Tags/TH.hs b/src/Reflex/Tags/TH.hs
new file mode 100644
--- /dev/null
+++ b/src/Reflex/Tags/TH.hs
@@ -0,0 +1,193 @@
+{-|
+Module      : Reflex.Tags.TH
+Description : Template Haskell utilities
+Copyright   : (c) Layer 3 Communications, 2016
+                  Matthew Parsons, 2016
+License     : BSD3
+Maintainer  : parsonsmatt@gmail.com
+Stability   : experimental
+Portability : POSIX
+
+This module provide utilities for generating convenience functions for HTML
+elements.
+-}
+
+module Reflex.Tags.TH where
+
+import Reflex.Dom.Widget
+import Control.Monad
+
+import Language.Haskell.TH
+
+-- | A list of all HTML elements.
+elements :: [String]
+elements =
+  [ "a"
+  , "abbr"
+  , "acronym"
+  , "address"
+  , "applet"
+  , "area"
+  , "article"
+  , "aside"
+  , "audio"
+  , "b"
+  , "base"
+  , "basefont"
+  , "bdi"
+  , "bdo"
+  , "big"
+  , "blockquote"
+  , "body"
+  , "br"
+  , "button"
+  , "canvas"
+  , "caption"
+  , "center"
+  , "cite"
+  , "code"
+  , "col"
+  , "colgroup"
+  , "datalist"
+  , "dd"
+  , "del"
+  , "details"
+  , "dfn"
+  , "dialog"
+  , "dir"
+  , "div"
+  , "dl"
+  , "dt"
+  , "em"
+  , "embed"
+  , "fieldset"
+  , "figcaption"
+  , "figure"
+  , "font"
+  , "footer"
+  , "form"
+  , "frame"
+  , "frameset"
+  , "h1"
+  , "h2"
+  , "h3"
+  , "h4"
+  , "h5"
+  , "h6"
+  , "head"
+  , "header"
+  , "hr"
+  , "html"
+  , "i"
+  , "iframe"
+  , "img"
+  , "input"
+  , "ins"
+  , "kbd"
+  , "keygen"
+  , "label"
+  , "legend"
+  , "li"
+  , "link"
+  , "main"
+  , "map"
+  , "mark"
+  , "menu"
+  , "menuitem"
+  , "meta"
+  , "meter"
+  , "nav"
+  , "noframes"
+  , "noscript"
+  , "object"
+  , "ol"
+  , "optgroup"
+  , "option"
+  , "output"
+  , "p"
+  , "param"
+  , "pre"
+  , "progress"
+  , "q"
+  , "rp"
+  , "rt"
+  , "ruby"
+  , "s"
+  , "samp"
+  , "script"
+  , "section"
+  , "select"
+  , "small"
+  , "source"
+  , "span"
+  , "strike"
+  , "strong"
+  , "style"
+  , "sub"
+  , "summary"
+  , "sup"
+  , "table"
+  , "tbody"
+  , "td"
+  , "textarea"
+  , "tfoot"
+  , "th"
+  , "thead"
+  , "time"
+  , "title"
+  , "tr"
+  , "track"
+  , "tt"
+  , "u"
+  , "ul"
+  , "var"
+  , "video"
+  , "wbr"
+  ]
+
+-- | Given a name for a function and a suffix, this function will generate
+-- a list of declarations. Each declaration will consist of the function applied
+-- to each of the HTML elements with the given suffix.
+gen :: Name -> String -> DecsQ
+gen sym suffix =
+    forM elements $ \element -> do
+        let name = mkName (element ++ suffix)
+        funD name [clause [] (normalB (appE (varE sym) (stringE element))) []]
+
+-- | Generate 'el' functions for all of the elements with an @_@ suffix.
+gen_ :: DecsQ
+gen_ = gen 'el "_"
+
+-- | Generate 'el'' functions for all of the elements with an @'@ suffix.
+gen' :: DecsQ
+gen' = gen 'el' "'"
+
+-- | Generate 'elAttr' functions for all of the elements with an @Attr@ suffix.
+genAttr :: DecsQ
+genAttr = gen 'elAttr "Attr"
+
+-- | Generate 'elAttr'' functions for all of the elements with an @Attr'@
+-- suffix.
+genAttr' :: DecsQ
+genAttr' = gen 'elAttr' "Attr'"
+
+-- | Generate 'elDynAttr' functions for all of the elements with a @DynAttr@
+-- suffix.
+genDynAttr :: DecsQ
+genDynAttr = gen 'elDynAttr "DynAttr"
+
+-- | Generate 'elDynAttr'' functions for all of the elements with a @DynAttr'@
+-- suffix.
+genDynAttr' :: DecsQ
+genDynAttr' = gen 'elDynAttr' "DynAttr'"
+
+-- | Generate all of the tags with all of the suffixes.
+genTags :: DecsQ
+genTags = do
+    a <- gen_
+    b <- gen'
+    c <- genAttr
+    d <- genAttr'
+    e <- genDynAttr
+    f <- genDynAttr'
+    return (mconcat [a, b, c, d, e, f])
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec.hs
@@ -0,0 +1,2 @@
+main :: IO ()
+main = putStrLn "Test suite not yet implemented"
