diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,5 @@
+# Revision history for `parsley-garnish`
+
+## 0.1.0.0 -- 2021-06-10
+
+* First version. Released on an unsuspecting world.
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2021, Jamie Willis, Matthew Pickering
+
+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 Jamie Willis, Matthew Pickering, 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,51 @@
+# Parsley Garnish
+This repo houses the `parsley`-specific GHC plugins to help make writing 
+parsers with `parsley` take less boilerplate.
+
+Each plugin here will in some way interact to produce values of either 
+type `Parsley.WQ` or `Parsley.Defunctionalized.Defunc`. These datatypes 
+are how `parsley`'s API interacts with user-land functions.
+
+By default, the user can produce values of these types by using the 
+`makeQ` function:
+
+```hs
+makeQ :: Quapplicative q => a -> Code a -> q a
+```
+
+Where both `WQ` and `Defunc` are instances of `Quapplicative`. However, 
+this can be tedious to do by hand.
+
+## `OverloadedQuotes`
+The first plugin found in the garnish hijacks the regular Haskell syntax 
+for _Untyped_ Template Haskell (UTH). Since `parsley` uses _Typed_ 
+Template Haskell (TTH), it is unlikely that a user of the library will 
+need to be using UTH in the same file (with the possible exception of 
+top-level splices, or quotes other than the basic `[|x|]`). This plugin 
+will transform every UTH quote in a file so that it represents a value of 
+`Quapplicative q => q a`. This transformation is as follows:
+
+```hs
+qsucc :: Quapplicative q => q Int -> q Int
+qsucc qx = [|$(qx) + 1|]
+-- goes to:
+qsucc qx = makeQ (_val qx + 1) [||$$(_code qx) + 1||]
+```
+
+Values of `Defunc` can also be spliced in directly:
+
+```hs
+diffcons :: Defunc a -> Defunc ([a] -> [a]) -> Defunc ([a] -> [a])
+diffcons qx qdxs = [| $(COMPOSE) ($(CONS) $(qx)) $(qdxs) |]
+```
+
+And lambda abstraction works too (along with any other syntax):
+
+```hs
+diffcons' :: Defunc (a -> ([a] -> [a]) -> [a] -> [a])
+diffcons' = [|\x dxs -> $(diffcons [|x|] [|dxs|])|]
+```
+
+The disadvantage to this plugin _currently_ is that it does not make any 
+attempt to  leverage the specialised parts of `Defunc` to improve the code 
+generation and inspectibility. The user would be left to use this manually.
diff --git a/parsley-garnish.cabal b/parsley-garnish.cabal
new file mode 100644
--- /dev/null
+++ b/parsley-garnish.cabal
@@ -0,0 +1,51 @@
+name:               parsley-garnish
+version:            0.1.0.0
+synopsis:           A collection of GHC plugins to work with parsley
+description:        This package contains a collection (for now one) to help
+                    remove boilerplate when writing parsers using @parsley@.
+homepage:           https://github.com/j-mie6/parsley-garnish
+bug-reports:        https://github.com/j-mie6/parsley-garnish/issues             
+license:            BSD3
+license-file:       LICENSE
+author:             Jamie Willis, Garnish Contributors
+-- When the lift-plugin + overloaded-syntax is in this can change
+--, Matthew Pickering
+maintainer:         Jamie Willis <j.willis19@imperial.ac.uk>
+category:           Plugin
+build-type:         Simple
+extra-doc-files:    ChangeLog.md
+                    README.md
+cabal-version:      1.18
+
+library
+  exposed-modules:  
+--                    Parsley.Garnish,
+--                    Parsley.LiftPlugin
+--                    Parsley.OverloadedSyntaxPlugin
+                    Parsley.OverloadedQuotesPlugin
+  other-modules:    Parsley.PluginUtils
+--                    -- Lift Plugin
+--                    Parsley.LiftPlugin.Plugin
+--                    Parsley.LiftPlugin.Error
+--                    Parsley.LiftPlugin.Fake
+--                    Parsley.LiftPlugin.LiftReplace
+--                    Parsley.LiftPlugin.LiftFind
+                    -- Overloaded Syntax Plugin
+--                    Parsley.OverloadedSyntaxPlugin.Plugin
+                    -- Overloaded Quotes Plugin
+                    Parsley.OverloadedQuotesPlugin.Plugin
+
+  build-depends:    base                >= 4.10    && < 5,
+                    parsley             >= 0.1     && < 0.2,
+                    template-haskell    >= 2.14    && < 3,
+                    ghc-tcplugins-extra >= 0.3     && < 0.5,
+                    ghc                 >= 8.6     && < 9,
+                    syb                 >= 0.7     && < 0.8
+
+  hs-source-dirs:   src
+  ghc-options:      -Wall
+  default-language: Haskell2010
+
+source-repository head
+  type:                git
+  location:            https://github.com/j-mie6/parsley-garnish
diff --git a/src/Parsley/OverloadedQuotesPlugin.hs b/src/Parsley/OverloadedQuotesPlugin.hs
new file mode 100644
--- /dev/null
+++ b/src/Parsley/OverloadedQuotesPlugin.hs
@@ -0,0 +1,38 @@
+{-|
+Module      : Parsley.OverloadedQuotesPlugin
+Description : Plugin for replacing Untyped Template Haskell quotes with
+              @parsley@'s @Quapplicative@ values.
+License     : BSD-3-CLAUSE
+Maintainer  : Jamie Willis
+Stability   : stable
+
+This plugin hijacks the regular Haskell syntax 
+for /Untyped/ Template Haskell (UTH). Since @parsley@ uses /Typed/ 
+Template Haskell (TTH), it is unlikely that a user of the library will 
+need to be using UTH in the same file (with the possible exception of 
+top-level splices, or quotes other than the basic @[|x|]@). This plugin 
+will transform every UTH quote in a file so that it represents a value of 
+@Quapplicative q => q a@. This transformation is as follows:
+
+> qsucc :: Quapplicative q => q Int -> q Int
+> qsucc qx = [|$(qx) + 1|]
+> -- goes to:
+> qsucc qx = makeQ (_val qx + 1) [||$$(_code qx) + 1||]
+
+Values of @Parsley.Defunctionalized.Defunc@ can also be spliced in directly:
+
+> diffcons :: Defunc a -> Defunc ([a] -> [a]) -> Defunc ([a] -> [a])
+> diffcons qx qdxs = [| $(COMPOSE) ($(CONS) $(qx)) $(qdxs) |]
+
+And lambda abstraction works too (along with any other syntax):
+
+> diffcons' :: Defunc (a -> ([a] -> [a]) -> [a] -> [a])
+> diffcons' = [|\x dxs -> $(diffcons [|x|] [|dxs|])|]
+
+The disadvantage to this plugin /currently/ is that it does not make any 
+attempt to  leverage the specialised parts of @Defunc@ to improve the code 
+generation and inspectibility. The user would be left to use this manually.
+-}
+module Parsley.OverloadedQuotesPlugin (module Plugin) where
+
+import Parsley.OverloadedQuotesPlugin.Plugin as Plugin
diff --git a/src/Parsley/OverloadedQuotesPlugin/Plugin.hs b/src/Parsley/OverloadedQuotesPlugin/Plugin.hs
new file mode 100644
--- /dev/null
+++ b/src/Parsley/OverloadedQuotesPlugin/Plugin.hs
@@ -0,0 +1,123 @@
+{-# OPTIONS_GHC -Wno-missing-pattern-synonym-signatures #-}
+{-# LANGUAGE DeriveFunctor #-}
+{-# LANGUAGE DeriveFoldable #-}
+{-# LANGUAGE DeriveTraversable #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE RankNTypes #-}
+module Parsley.OverloadedQuotesPlugin.Plugin (plugin) where
+
+import Plugins       (Plugin (..), defaultPlugin, purePlugin)
+import TcRnTypes     (TcGblEnv, TcM)
+import Data.Generics (GenericT, GenericQ, mkT, mkQ, everywhere, gmapT)
+import GHC.Generics  (Generic)
+
+import qualified GHC               (HsGroup, GhcRn, Name, GenLocated(L), SrcSpan)
+import qualified GhcPlugins as GHC (CommandLineOption)
+import qualified TcRnMonad as GHC  (getTopEnv)
+
+#if __GLASGOW_HASKELL__ < 810
+import qualified HsExpr as Expr
+#else
+import qualified GHC.Hs.Expr as Expr
+#endif
+
+import Parsley.PluginUtils (lookupModuleInPackage, lookupName, lookupNames)
+
+#if __GLASGOW_HASKELL__ >= 810
+import GHC.Hs.Extension
+noExt :: NoExtField
+noExt = noExtField
+#else
+import GHC (noExt)
+#endif
+
+type Expr = Expr.LHsExpr GHC.GhcRn
+
+{-|
+This plugin repurposes /Untyped/ Template Haskell quotes (and splices within them)
+to be @Parsley.Quapplicative@ values.
+-}
+plugin :: Plugin
+plugin = defaultPlugin { renamedResultAction = overloadedQuotes, pluginRecompile = purePlugin }
+
+data QOps a = QOps {
+    _code :: a,
+    _val :: a,
+    makeQ :: a
+  } deriving (Functor, Foldable, Traversable, Generic)
+
+quapplicativeStrings :: QOps String
+quapplicativeStrings = QOps {
+    _code = "_code",
+    _val  = "_val",
+    makeQ = "makeQ"
+  }
+
+overloadedQuotes :: [GHC.CommandLineOption] -> TcGblEnv -> GHC.HsGroup GHC.GhcRn -> TcM (TcGblEnv, GHC.HsGroup GHC.GhcRn)
+overloadedQuotes _ gEnv rn = do
+  hscEnv <- GHC.getTopEnv
+  parsley <- lookupModuleInPackage hscEnv "parsley" "Parsley.Internal.Common.Utils"
+  qops <- lookupNames parsley quapplicativeStrings
+  prelude <- lookupModuleInPackage hscEnv "base" "GHC.Err"
+  undef <- lookupName prelude "undefined"
+  -- This is a little inefficient, since the top-down transformation means no quotes can be
+  -- found under a top-level one: we use a top-down version of everywhereBut to stop traversal
+  -- of this whenever it fires
+  return (gEnv, onlyTopmost (mkQ False isQuote) (mkT (transformUTHQuote qops undef)) rn)
+
+mkApp :: GHC.SrcSpan -> Expr -> Expr -> Expr
+mkApp s f = GHC.L s . Expr.HsApp noExt f . mkPar s
+
+mkVar :: GHC.SrcSpan -> GHC.Name -> Expr
+mkVar s = GHC.L s . Expr.HsVar noExt . GHC.L s
+
+mkPar :: GHC.SrcSpan -> Expr -> Expr
+mkPar s = GHC.L s . Expr.HsPar noExt
+
+pattern LUTHQuote s ex1 ex2 x <- GHC.L s (Expr.HsRnBracketOut ex1 (Expr.ExpBr ex2 x) _)
+pattern LUTHSplice s ex1 ex2 dec name x = GHC.L s (Expr.HsSpliceE ex1 (Expr.HsUntypedSplice ex2 dec name x))
+
+isQuote :: Expr -> Bool
+isQuote (LUTHQuote _ _ _ _) = True
+isQuote _                   = False
+
+-- The goal here is to find [|e|] and turn it into makeQ e [||e||]
+-- The catch is that for any $qe in the quote, it must be hoisted out, let bound and then re-incorporated
+-- such that `[|x .. $qe .. y|]` ~> `let qe' = qe in makeQ (x .. _val qe' .. y) [||x .. $$(_code qe') .. y||]`
+-- This means that the content of the splice _cannot_ use any of the free-variables defined within
+-- the original quote. Perhaps in that case we could just inline the definition into both holes...
+-- As `transform` works bottom up, we can always assume nested quotes are already handled: this might
+-- get tricky, however.
+transformUTHQuote :: QOps GHC.Name -> GHC.Name -> Expr -> Expr
+transformUTHQuote ops undef (LUTHQuote s ex ex' x) = --pprTouch "new quote" $
+  mkPar s (makeQS `mkAppS` everywhere (mkT (transformUTHQuoteVar (_val ops) makeVal)) x
+                  `mkAppS` mkQuote (everywhere (mkT (transformUTHQuoteCode (_code ops) makeCode)) x))
+  where
+    mkQuote y = GHC.L s (Expr.HsBracket ex (Expr.TExpBr ex' y))
+    mkAppS = mkApp s
+    makeQS = mkVar s (makeQ ops)
+    makeVal y = mkPar s (makeQS `mkAppS` y `mkAppS` mkVar s undef)
+    makeCode y = mkPar s (makeQS `mkAppS` mkVar s undef `mkAppS` y)
+transformUTHQuote _ _ x = x
+
+transformUTHQuoteVar :: GHC.Name -> (Expr -> Expr) -> Expr -> Expr
+transformUTHQuoteVar _    makeVal (LUTHQuote _ _ _ x)      = makeVal x
+transformUTHQuoteVar _val _       (LUTHSplice s _ _ _ _ x) = mkApp s (mkVar s _val) x
+transformUTHQuoteVar _    _       x                        = x
+
+transformUTHQuoteCode :: GHC.Name -> (Expr -> Expr) -> Expr -> Expr
+transformUTHQuoteCode _     makeCode (LUTHQuote s ex ex' x)         = makeCode (GHC.L s (Expr.HsBracket ex (Expr.TExpBr ex' x)))
+transformUTHQuoteCode _code _        (LUTHSplice s ex ex' d name x) = GHC.L s . Expr.HsSpliceE ex . Expr.HsTypedSplice ex' d name $
+  mkApp s (mkVar s _code) x
+transformUTHQuoteCode _     _        x                              = x
+
+onlyTopmost :: GenericQ Bool -> GenericT -> GenericT
+onlyTopmost q f = go
+  where
+    go :: GenericT
+    go x
+      | q x = f x
+      | otherwise = gmapT go x
diff --git a/src/Parsley/PluginUtils.hs b/src/Parsley/PluginUtils.hs
new file mode 100644
--- /dev/null
+++ b/src/Parsley/PluginUtils.hs
@@ -0,0 +1,54 @@
+{-# LANGUAGE TypeSynonymInstances, FlexibleInstances #-}
+module Parsley.PluginUtils where
+
+import qualified GHC.TcPluginM.Extra as TCPluginExtra (lookupName)
+
+-- GHC API
+import TcRnTypes (TcM, TcPluginM)
+import Outputable
+
+-- ghc
+import qualified GhcPlugins as GHC
+import qualified IfaceEnv as GHC (lookupOrig)
+import Finder (findImportedModule, FindResult(Found))
+import FastString (mkFastString)
+import Module (Module, mkModuleName)
+import Name (Name)
+import Control.Monad.IO.Class ( liftIO )
+
+class Monad m => Lookup m where
+  lookupOrig :: Module -> GHC.OccName -> m Name
+
+instance Lookup TcM where
+  lookupOrig = GHC.lookupOrig
+
+instance Lookup TcPluginM where
+  lookupOrig = TCPluginExtra.lookupName
+
+pprTouch :: Outputable a => String -> a -> a
+pprTouch name x = pprTrace name (ppr x) x
+
+lookupNames :: (Lookup m, Traversable t) => Module -> t String -> m (t Name)
+lookupNames = traverse . lookupName
+
+lookupName :: Lookup m => Module -> String -> m Name
+lookupName pm = lookupOrig pm . GHC.mkVarOcc
+
+lookupClass :: Lookup m => Module -> String -> m Name
+lookupClass pm = lookupOrig pm . GHC.mkTcOcc
+
+lookupIds :: Traversable t => Module -> t String -> TcM (t GHC.Id)
+lookupIds = traverse . lookupId
+
+lookupId :: Module -> String -> TcM GHC.Id
+lookupId pm name = lookupName pm name >>= GHC.lookupId
+
+lookupModule :: GHC.HscEnv -> String -> TcM Module
+lookupModule hscEnv modName = do
+  Found _ md <- liftIO (findImportedModule hscEnv (mkModuleName modName) Nothing)
+  return md
+
+lookupModuleInPackage :: GHC.HscEnv -> String -> String -> TcM Module
+lookupModuleInPackage hscEnv package modName = do
+  Found _ md <- liftIO (findImportedModule hscEnv (mkModuleName modName) (Just (mkFastString package)))
+  return md
