diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,12 +1,15 @@
 # emojis
 
-## 0.1
+# 0.1.4
 
-  * Initial release
+  * Update emoji data.
+  * Export new function `replaceEmojis`, allowing replacement of
+    emojis in a Text with alternate text.
+  * Drop support for ghc < 8.8.
 
-# 0.1.1
+# 0.1.3
 
-  * Update emoji data.
+  * Update emoji data to Unicode Emoji 15.0 and aliases from gemoji.
 
 # 0.1.2
 
@@ -16,6 +19,10 @@
     complete list of emojis, including emojis for which gemoji
     provides no alias (Stephen Morgan).
 
-# 0.1.3
+# 0.1.1
 
-  * Update emoji data to Unicode Emoji 15.0 and aliases from gemoji.
+  * Update emoji data.
+
+## 0.1
+
+  * Initial release
diff --git a/emojis.cabal b/emojis.cabal
--- a/emojis.cabal
+++ b/emojis.cabal
@@ -1,5 +1,5 @@
 name:                emojis
-version:             0.1.3
+version:             0.1.4
 synopsis:            Conversion between emoji characters and their names.
 description:         This package provides functions for converting
                      emoji names to emoji characters and vice versa.
@@ -27,7 +27,8 @@
 library
   hs-source-dirs:      src
   exposed-modules:     Text.Emoji
-  build-depends:       base >= 4.9 && < 5,
+  other-modules:       Trie
+  build-depends:       base >= 4.13 && < 5,
                        text,
                        containers
   default-language:    Haskell2010
diff --git a/src/Text/Emoji.hs b/src/Text/Emoji.hs
--- a/src/Text/Emoji.hs
+++ b/src/Text/Emoji.hs
@@ -5,13 +5,18 @@
 ( emojis
 , emojiFromAlias
 , aliasesFromEmoji
+, replaceEmojis
 , baseEmojis
 , zwjEmojis
 ) where
 
 import Prelude
+import Data.Char (chr, ord)
 import qualified Data.Map as M
 import Data.Text (Text)
+import qualified Data.Text as T
+import Data.Bifunctor (first)
+import Trie as Trie
 
 emojiMap :: M.Map Text Text
 emojiMap = M.fromList emojis
@@ -30,6 +35,32 @@
 -- | Lookup the aliases of an emoji.
 aliasesFromEmoji :: Text -> Maybe [Text]
 aliasesFromEmoji s = M.lookup s emojiAliasMap
+
+-- | Replace emojis in a text with alternative text.
+-- The replacement function maps an emoji and a list of emoji aliases
+-- to a replacement text.
+replaceEmojis :: (Text -> [Text] -> Text) -> Text -> Text
+replaceEmojis getReplacement = fromCodePoints . go . toCodePoints
+ where
+   go [] = []
+   go (c:cs) =
+       case Trie.matchLongestPrefix emojiTrie (c:cs) of
+         Just (aliases, numcps, _subtrie) ->
+           let (consumed, remaining) = splitAt numcps (c:cs)
+            in toCodePoints (getReplacement (fromCodePoints consumed) aliases)
+                 <> go remaining
+         Nothing -> -- go forward one UTF8 code point
+           c : go cs
+
+toCodePoints :: Text -> [Int]
+toCodePoints = map ord . T.unpack
+
+fromCodePoints :: [Int] -> Text
+fromCodePoints = T.pack . map chr
+
+emojiTrie :: Trie.Trie [Text]
+emojiTrie =
+  Trie.fromList . map (first toCodePoints) . M.toList $ emojiAliasMap
 
 -- | Association list of (alias, emoji) pairs.  Note that the
 -- same emoji may have multiple aliases.
diff --git a/src/Text/emojis.inc b/src/Text/emojis.inc
--- a/src/Text/emojis.inc
+++ b/src/Text/emojis.inc
@@ -4506,6 +4506,10 @@
   , "\128105\127999\8205\129309\8205\128105\127997"
   , "\128105\127999\8205\129309\8205\128105\127998"
   , "\129489\8205\129309\8205\129489"
+  , "\129489\8205\129489\8205\129490"
+  , "\129489\8205\129489\8205\129490\8205\129490"
+  , "\129489\8205\129490"
+  , "\129489\8205\129490\8205\129490"
   , "\129489\127995\8205\10084\65039\8205\128139\8205\129489\127996"
   , "\129489\127995\8205\10084\65039\8205\128139\8205\129489\127997"
   , "\129489\127995\8205\10084\65039\8205\128139\8205\129489\127998"
@@ -4514,7 +4518,6 @@
   , "\129489\127995\8205\10084\65039\8205\129489\127997"
   , "\129489\127995\8205\10084\65039\8205\129489\127998"
   , "\129489\127995\8205\10084\65039\8205\129489\127999"
-  , "\129489\127995\8205\127876"
   , "\129489\127995\8205\129309\8205\129489\127995"
   , "\129489\127995\8205\129309\8205\129489\127996"
   , "\129489\127995\8205\129309\8205\129489\127997"
@@ -4528,7 +4531,6 @@
   , "\129489\127996\8205\10084\65039\8205\129489\127997"
   , "\129489\127996\8205\10084\65039\8205\129489\127998"
   , "\129489\127996\8205\10084\65039\8205\129489\127999"
-  , "\129489\127996\8205\127876"
   , "\129489\127996\8205\129309\8205\129489\127995"
   , "\129489\127996\8205\129309\8205\129489\127996"
   , "\129489\127996\8205\129309\8205\129489\127997"
@@ -4542,7 +4544,6 @@
   , "\129489\127997\8205\10084\65039\8205\129489\127996"
   , "\129489\127997\8205\10084\65039\8205\129489\127998"
   , "\129489\127997\8205\10084\65039\8205\129489\127999"
-  , "\129489\127997\8205\127876"
   , "\129489\127997\8205\129309\8205\129489\127995"
   , "\129489\127997\8205\129309\8205\129489\127996"
   , "\129489\127997\8205\129309\8205\129489\127997"
@@ -4556,7 +4557,6 @@
   , "\129489\127998\8205\10084\65039\8205\129489\127996"
   , "\129489\127998\8205\10084\65039\8205\129489\127997"
   , "\129489\127998\8205\10084\65039\8205\129489\127999"
-  , "\129489\127998\8205\127876"
   , "\129489\127998\8205\129309\8205\129489\127995"
   , "\129489\127998\8205\129309\8205\129489\127996"
   , "\129489\127998\8205\129309\8205\129489\127997"
@@ -4570,7 +4570,6 @@
   , "\129489\127999\8205\10084\65039\8205\129489\127996"
   , "\129489\127999\8205\10084\65039\8205\129489\127997"
   , "\129489\127999\8205\10084\65039\8205\129489\127998"
-  , "\129489\127999\8205\127876"
   , "\129489\127999\8205\129309\8205\129489\127995"
   , "\129489\127999\8205\129309\8205\129489\127996"
   , "\129489\127999\8205\129309\8205\129489\127997"
@@ -4596,6 +4595,12 @@
   , "\129777\127999\8205\129778\127996"
   , "\129777\127999\8205\129778\127997"
   , "\129777\127999\8205\129778\127998"
+  , "\127939\8205\10145\65039"
+  , "\127939\127995\8205\10145\65039"
+  , "\127939\127996\8205\10145\65039"
+  , "\127939\127997\8205\10145\65039"
+  , "\127939\127998\8205\10145\65039"
+  , "\127939\127999\8205\10145\65039"
   , "\128104\8205\9877\65039"
   , "\128104\8205\9878\65039"
   , "\128104\8205\9992\65039"
@@ -4614,8 +4619,11 @@
   , "\128104\8205\128640"
   , "\128104\8205\128658"
   , "\128104\8205\129455"
+  , "\128104\8205\129455\8205\10145\65039"
   , "\128104\8205\129468"
+  , "\128104\8205\129468\8205\10145\65039"
   , "\128104\8205\129469"
+  , "\128104\8205\129469\8205\10145\65039"
   , "\128104\127995\8205\9877\65039"
   , "\128104\127995\8205\9878\65039"
   , "\128104\127995\8205\9992\65039"
@@ -4634,8 +4642,11 @@
   , "\128104\127995\8205\128640"
   , "\128104\127995\8205\128658"
   , "\128104\127995\8205\129455"
+  , "\128104\127995\8205\129455\8205\10145\65039"
   , "\128104\127995\8205\129468"
+  , "\128104\127995\8205\129468\8205\10145\65039"
   , "\128104\127995\8205\129469"
+  , "\128104\127995\8205\129469\8205\10145\65039"
   , "\128104\127996\8205\9877\65039"
   , "\128104\127996\8205\9878\65039"
   , "\128104\127996\8205\9992\65039"
@@ -4654,8 +4665,11 @@
   , "\128104\127996\8205\128640"
   , "\128104\127996\8205\128658"
   , "\128104\127996\8205\129455"
+  , "\128104\127996\8205\129455\8205\10145\65039"
   , "\128104\127996\8205\129468"
+  , "\128104\127996\8205\129468\8205\10145\65039"
   , "\128104\127996\8205\129469"
+  , "\128104\127996\8205\129469\8205\10145\65039"
   , "\128104\127997\8205\9877\65039"
   , "\128104\127997\8205\9878\65039"
   , "\128104\127997\8205\9992\65039"
@@ -4674,8 +4688,11 @@
   , "\128104\127997\8205\128640"
   , "\128104\127997\8205\128658"
   , "\128104\127997\8205\129455"
+  , "\128104\127997\8205\129455\8205\10145\65039"
   , "\128104\127997\8205\129468"
+  , "\128104\127997\8205\129468\8205\10145\65039"
   , "\128104\127997\8205\129469"
+  , "\128104\127997\8205\129469\8205\10145\65039"
   , "\128104\127998\8205\9877\65039"
   , "\128104\127998\8205\9878\65039"
   , "\128104\127998\8205\9992\65039"
@@ -4694,8 +4711,11 @@
   , "\128104\127998\8205\128640"
   , "\128104\127998\8205\128658"
   , "\128104\127998\8205\129455"
+  , "\128104\127998\8205\129455\8205\10145\65039"
   , "\128104\127998\8205\129468"
+  , "\128104\127998\8205\129468\8205\10145\65039"
   , "\128104\127998\8205\129469"
+  , "\128104\127998\8205\129469\8205\10145\65039"
   , "\128104\127999\8205\9877\65039"
   , "\128104\127999\8205\9878\65039"
   , "\128104\127999\8205\9992\65039"
@@ -4714,8 +4734,11 @@
   , "\128104\127999\8205\128640"
   , "\128104\127999\8205\128658"
   , "\128104\127999\8205\129455"
+  , "\128104\127999\8205\129455\8205\10145\65039"
   , "\128104\127999\8205\129468"
+  , "\128104\127999\8205\129468\8205\10145\65039"
   , "\128104\127999\8205\129469"
+  , "\128104\127999\8205\129469\8205\10145\65039"
   , "\128105\8205\9877\65039"
   , "\128105\8205\9878\65039"
   , "\128105\8205\9992\65039"
@@ -4734,8 +4757,11 @@
   , "\128105\8205\128640"
   , "\128105\8205\128658"
   , "\128105\8205\129455"
+  , "\128105\8205\129455\8205\10145\65039"
   , "\128105\8205\129468"
+  , "\128105\8205\129468\8205\10145\65039"
   , "\128105\8205\129469"
+  , "\128105\8205\129469\8205\10145\65039"
   , "\128105\127995\8205\9877\65039"
   , "\128105\127995\8205\9878\65039"
   , "\128105\127995\8205\9992\65039"
@@ -4754,8 +4780,11 @@
   , "\128105\127995\8205\128640"
   , "\128105\127995\8205\128658"
   , "\128105\127995\8205\129455"
+  , "\128105\127995\8205\129455\8205\10145\65039"
   , "\128105\127995\8205\129468"
+  , "\128105\127995\8205\129468\8205\10145\65039"
   , "\128105\127995\8205\129469"
+  , "\128105\127995\8205\129469\8205\10145\65039"
   , "\128105\127996\8205\9877\65039"
   , "\128105\127996\8205\9878\65039"
   , "\128105\127996\8205\9992\65039"
@@ -4774,8 +4803,11 @@
   , "\128105\127996\8205\128640"
   , "\128105\127996\8205\128658"
   , "\128105\127996\8205\129455"
+  , "\128105\127996\8205\129455\8205\10145\65039"
   , "\128105\127996\8205\129468"
+  , "\128105\127996\8205\129468\8205\10145\65039"
   , "\128105\127996\8205\129469"
+  , "\128105\127996\8205\129469\8205\10145\65039"
   , "\128105\127997\8205\9877\65039"
   , "\128105\127997\8205\9878\65039"
   , "\128105\127997\8205\9992\65039"
@@ -4794,8 +4826,11 @@
   , "\128105\127997\8205\128640"
   , "\128105\127997\8205\128658"
   , "\128105\127997\8205\129455"
+  , "\128105\127997\8205\129455\8205\10145\65039"
   , "\128105\127997\8205\129468"
+  , "\128105\127997\8205\129468\8205\10145\65039"
   , "\128105\127997\8205\129469"
+  , "\128105\127997\8205\129469\8205\10145\65039"
   , "\128105\127998\8205\9877\65039"
   , "\128105\127998\8205\9878\65039"
   , "\128105\127998\8205\9992\65039"
@@ -4814,8 +4849,11 @@
   , "\128105\127998\8205\128640"
   , "\128105\127998\8205\128658"
   , "\128105\127998\8205\129455"
+  , "\128105\127998\8205\129455\8205\10145\65039"
   , "\128105\127998\8205\129468"
+  , "\128105\127998\8205\129468\8205\10145\65039"
   , "\128105\127998\8205\129469"
+  , "\128105\127998\8205\129469\8205\10145\65039"
   , "\128105\127999\8205\9877\65039"
   , "\128105\127999\8205\9878\65039"
   , "\128105\127999\8205\9992\65039"
@@ -4834,14 +4872,30 @@
   , "\128105\127999\8205\128640"
   , "\128105\127999\8205\128658"
   , "\128105\127999\8205\129455"
+  , "\128105\127999\8205\129455\8205\10145\65039"
   , "\128105\127999\8205\129468"
+  , "\128105\127999\8205\129468\8205\10145\65039"
   , "\128105\127999\8205\129469"
+  , "\128105\127999\8205\129469\8205\10145\65039"
+  , "\128694\8205\10145\65039"
+  , "\128694\127995\8205\10145\65039"
+  , "\128694\127996\8205\10145\65039"
+  , "\128694\127997\8205\10145\65039"
+  , "\128694\127998\8205\10145\65039"
+  , "\128694\127999\8205\10145\65039"
+  , "\129486\8205\10145\65039"
+  , "\129486\127995\8205\10145\65039"
+  , "\129486\127996\8205\10145\65039"
+  , "\129486\127997\8205\10145\65039"
+  , "\129486\127998\8205\10145\65039"
+  , "\129486\127999\8205\10145\65039"
   , "\129489\8205\9877\65039"
   , "\129489\8205\9878\65039"
   , "\129489\8205\9992\65039"
   , "\129489\8205\127806"
   , "\129489\8205\127859"
   , "\129489\8205\127868"
+  , "\129489\8205\127876"
   , "\129489\8205\127891"
   , "\129489\8205\127908"
   , "\129489\8205\127912"
@@ -4854,14 +4908,18 @@
   , "\129489\8205\128640"
   , "\129489\8205\128658"
   , "\129489\8205\129455"
+  , "\129489\8205\129455\8205\10145\65039"
   , "\129489\8205\129468"
+  , "\129489\8205\129468\8205\10145\65039"
   , "\129489\8205\129469"
+  , "\129489\8205\129469\8205\10145\65039"
   , "\129489\127995\8205\9877\65039"
   , "\129489\127995\8205\9878\65039"
   , "\129489\127995\8205\9992\65039"
   , "\129489\127995\8205\127806"
   , "\129489\127995\8205\127859"
   , "\129489\127995\8205\127868"
+  , "\129489\127995\8205\127876"
   , "\129489\127995\8205\127891"
   , "\129489\127995\8205\127908"
   , "\129489\127995\8205\127912"
@@ -4874,14 +4932,18 @@
   , "\129489\127995\8205\128640"
   , "\129489\127995\8205\128658"
   , "\129489\127995\8205\129455"
+  , "\129489\127995\8205\129455\8205\10145\65039"
   , "\129489\127995\8205\129468"
+  , "\129489\127995\8205\129468\8205\10145\65039"
   , "\129489\127995\8205\129469"
+  , "\129489\127995\8205\129469\8205\10145\65039"
   , "\129489\127996\8205\9877\65039"
   , "\129489\127996\8205\9878\65039"
   , "\129489\127996\8205\9992\65039"
   , "\129489\127996\8205\127806"
   , "\129489\127996\8205\127859"
   , "\129489\127996\8205\127868"
+  , "\129489\127996\8205\127876"
   , "\129489\127996\8205\127891"
   , "\129489\127996\8205\127908"
   , "\129489\127996\8205\127912"
@@ -4894,14 +4956,18 @@
   , "\129489\127996\8205\128640"
   , "\129489\127996\8205\128658"
   , "\129489\127996\8205\129455"
+  , "\129489\127996\8205\129455\8205\10145\65039"
   , "\129489\127996\8205\129468"
+  , "\129489\127996\8205\129468\8205\10145\65039"
   , "\129489\127996\8205\129469"
+  , "\129489\127996\8205\129469\8205\10145\65039"
   , "\129489\127997\8205\9877\65039"
   , "\129489\127997\8205\9878\65039"
   , "\129489\127997\8205\9992\65039"
   , "\129489\127997\8205\127806"
   , "\129489\127997\8205\127859"
   , "\129489\127997\8205\127868"
+  , "\129489\127997\8205\127876"
   , "\129489\127997\8205\127891"
   , "\129489\127997\8205\127908"
   , "\129489\127997\8205\127912"
@@ -4914,14 +4980,18 @@
   , "\129489\127997\8205\128640"
   , "\129489\127997\8205\128658"
   , "\129489\127997\8205\129455"
+  , "\129489\127997\8205\129455\8205\10145\65039"
   , "\129489\127997\8205\129468"
+  , "\129489\127997\8205\129468\8205\10145\65039"
   , "\129489\127997\8205\129469"
+  , "\129489\127997\8205\129469\8205\10145\65039"
   , "\129489\127998\8205\9877\65039"
   , "\129489\127998\8205\9878\65039"
   , "\129489\127998\8205\9992\65039"
   , "\129489\127998\8205\127806"
   , "\129489\127998\8205\127859"
   , "\129489\127998\8205\127868"
+  , "\129489\127998\8205\127876"
   , "\129489\127998\8205\127891"
   , "\129489\127998\8205\127908"
   , "\129489\127998\8205\127912"
@@ -4934,14 +5004,18 @@
   , "\129489\127998\8205\128640"
   , "\129489\127998\8205\128658"
   , "\129489\127998\8205\129455"
+  , "\129489\127998\8205\129455\8205\10145\65039"
   , "\129489\127998\8205\129468"
+  , "\129489\127998\8205\129468\8205\10145\65039"
   , "\129489\127998\8205\129469"
+  , "\129489\127998\8205\129469\8205\10145\65039"
   , "\129489\127999\8205\9877\65039"
   , "\129489\127999\8205\9878\65039"
   , "\129489\127999\8205\9992\65039"
   , "\129489\127999\8205\127806"
   , "\129489\127999\8205\127859"
   , "\129489\127999\8205\127868"
+  , "\129489\127999\8205\127876"
   , "\129489\127999\8205\127891"
   , "\129489\127999\8205\127908"
   , "\129489\127999\8205\127912"
@@ -4954,8 +5028,11 @@
   , "\129489\127999\8205\128640"
   , "\129489\127999\8205\128658"
   , "\129489\127999\8205\129455"
+  , "\129489\127999\8205\129455\8205\10145\65039"
   , "\129489\127999\8205\129468"
+  , "\129489\127999\8205\129468\8205\10145\65039"
   , "\129489\127999\8205\129469"
+  , "\129489\127999\8205\129469\8205\10145\65039"
   , "\9977\127995\8205\9792\65039"
   , "\9977\127995\8205\9794\65039"
   , "\9977\127996\8205\9792\65039"
@@ -4969,17 +5046,29 @@
   , "\9977\65039\8205\9792\65039"
   , "\9977\65039\8205\9794\65039"
   , "\127939\8205\9792\65039"
+  , "\127939\8205\9792\65039\8205\10145\65039"
   , "\127939\8205\9794\65039"
+  , "\127939\8205\9794\65039\8205\10145\65039"
   , "\127939\127995\8205\9792\65039"
+  , "\127939\127995\8205\9792\65039\8205\10145\65039"
   , "\127939\127995\8205\9794\65039"
+  , "\127939\127995\8205\9794\65039\8205\10145\65039"
   , "\127939\127996\8205\9792\65039"
+  , "\127939\127996\8205\9792\65039\8205\10145\65039"
   , "\127939\127996\8205\9794\65039"
+  , "\127939\127996\8205\9794\65039\8205\10145\65039"
   , "\127939\127997\8205\9792\65039"
+  , "\127939\127997\8205\9792\65039\8205\10145\65039"
   , "\127939\127997\8205\9794\65039"
+  , "\127939\127997\8205\9794\65039\8205\10145\65039"
   , "\127939\127998\8205\9792\65039"
+  , "\127939\127998\8205\9792\65039\8205\10145\65039"
   , "\127939\127998\8205\9794\65039"
+  , "\127939\127998\8205\9794\65039\8205\10145\65039"
   , "\127939\127999\8205\9792\65039"
+  , "\127939\127999\8205\9792\65039\8205\10145\65039"
   , "\127939\127999\8205\9794\65039"
+  , "\127939\127999\8205\9794\65039\8205\10145\65039"
   , "\127940\8205\9792\65039"
   , "\127940\8205\9794\65039"
   , "\127940\127995\8205\9792\65039"
@@ -5259,17 +5348,29 @@
   , "\128693\127999\8205\9792\65039"
   , "\128693\127999\8205\9794\65039"
   , "\128694\8205\9792\65039"
+  , "\128694\8205\9792\65039\8205\10145\65039"
   , "\128694\8205\9794\65039"
+  , "\128694\8205\9794\65039\8205\10145\65039"
   , "\128694\127995\8205\9792\65039"
+  , "\128694\127995\8205\9792\65039\8205\10145\65039"
   , "\128694\127995\8205\9794\65039"
+  , "\128694\127995\8205\9794\65039\8205\10145\65039"
   , "\128694\127996\8205\9792\65039"
+  , "\128694\127996\8205\9792\65039\8205\10145\65039"
   , "\128694\127996\8205\9794\65039"
+  , "\128694\127996\8205\9794\65039\8205\10145\65039"
   , "\128694\127997\8205\9792\65039"
+  , "\128694\127997\8205\9792\65039\8205\10145\65039"
   , "\128694\127997\8205\9794\65039"
+  , "\128694\127997\8205\9794\65039\8205\10145\65039"
   , "\128694\127998\8205\9792\65039"
+  , "\128694\127998\8205\9792\65039\8205\10145\65039"
   , "\128694\127998\8205\9794\65039"
+  , "\128694\127998\8205\9794\65039\8205\10145\65039"
   , "\128694\127999\8205\9792\65039"
+  , "\128694\127999\8205\9792\65039\8205\10145\65039"
   , "\128694\127999\8205\9794\65039"
+  , "\128694\127999\8205\9794\65039\8205\10145\65039"
   , "\129318\8205\9792\65039"
   , "\129318\8205\9794\65039"
   , "\129318\127995\8205\9792\65039"
@@ -5393,17 +5494,29 @@
   , "\129485\127999\8205\9792\65039"
   , "\129485\127999\8205\9794\65039"
   , "\129486\8205\9792\65039"
+  , "\129486\8205\9792\65039\8205\10145\65039"
   , "\129486\8205\9794\65039"
+  , "\129486\8205\9794\65039\8205\10145\65039"
   , "\129486\127995\8205\9792\65039"
+  , "\129486\127995\8205\9792\65039\8205\10145\65039"
   , "\129486\127995\8205\9794\65039"
+  , "\129486\127995\8205\9794\65039\8205\10145\65039"
   , "\129486\127996\8205\9792\65039"
+  , "\129486\127996\8205\9792\65039\8205\10145\65039"
   , "\129486\127996\8205\9794\65039"
+  , "\129486\127996\8205\9794\65039\8205\10145\65039"
   , "\129486\127997\8205\9792\65039"
+  , "\129486\127997\8205\9792\65039\8205\10145\65039"
   , "\129486\127997\8205\9794\65039"
+  , "\129486\127997\8205\9794\65039\8205\10145\65039"
   , "\129486\127998\8205\9792\65039"
+  , "\129486\127998\8205\9792\65039\8205\10145\65039"
   , "\129486\127998\8205\9794\65039"
+  , "\129486\127998\8205\9794\65039\8205\10145\65039"
   , "\129486\127999\8205\9792\65039"
+  , "\129486\127999\8205\9792\65039\8205\10145\65039"
   , "\129486\127999\8205\9794\65039"
+  , "\129486\127999\8205\9794\65039\8205\10145\65039"
   , "\129487\8205\9792\65039"
   , "\129487\8205\9794\65039"
   , "\129487\127995\8205\9792\65039"
@@ -5600,18 +5713,23 @@
   , "\129489\127999\8205\129457"
   , "\129489\127999\8205\129458"
   , "\129489\127999\8205\129459"
+  , "\9939\65039\8205\128165"
   , "\10084\65039\8205\128293"
   , "\10084\65039\8205\129657"
+  , "\127812\8205\129003"
+  , "\127819\8205\129001"
   , "\127987\65039\8205\9895\65039"
   , "\127987\65039\8205\127752"
   , "\127988\8205\9760\65039"
   , "\128008\8205\11035"
   , "\128021\8205\129466"
   , "\128038\8205\11035"
+  , "\128038\8205\128293"
   , "\128059\8205\10052\65039"
   , "\128065\65039\8205\128488\65039"
   , "\128558\8205\128168"
   , "\128565\8205\128171"
   , "\128566\8205\127787\65039"
-  , "\129489\8205\127876"
+  , "\128578\8205\8596\65039"
+  , "\128578\8205\8597\65039"
   ]
diff --git a/src/Trie.hs b/src/Trie.hs
new file mode 100644
--- /dev/null
+++ b/src/Trie.hs
@@ -0,0 +1,83 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE StrictData #-}
+module Trie
+  ( Trie
+  , empty
+  , insert
+  , alter
+  , unfoldTrie
+  , fromList
+  , matchLongestPrefix
+  )
+  where
+
+import Control.Monad (foldM)
+import qualified Data.IntMap as M
+import Data.Bifunctor (first)
+import Data.Maybe (fromMaybe)
+
+data Trie a = Trie (Maybe a) (Maybe (M.IntMap (Trie a)))
+  deriving (Show, Eq, Ord)
+
+instance Semigroup (Trie a) where
+   trie1 <> trie2 = foldr (uncurry insert) trie1 (unfoldTrie trie2)
+
+instance Monoid (Trie a) where
+   mempty = Trie Nothing Nothing
+   mappend = (<>)
+
+empty :: Trie a
+empty = Trie Nothing Nothing
+
+unfoldTrie :: Trie a -> [([Int], a)]
+unfoldTrie  = map (first reverse) . go []
+ where
+  go xs (Trie (Just v) (Just m)) =
+    (xs, v) : concatMap (gopair xs) (M.toList m)
+  go xs (Trie (Just v) Nothing) = [(xs, v)]
+  go xs (Trie Nothing (Just m)) =
+    concatMap (gopair xs) (M.toList m)
+  go _ (Trie Nothing Nothing) = []
+  gopair xs (i, trie) = go (i:xs) trie
+
+insert :: [Int] -> a -> Trie a -> Trie a
+insert [] x (Trie _ mbm) = Trie (Just x) mbm
+insert (c:cs) x (Trie mbv (Just m)) =
+  case M.lookup c m of
+    Nothing   -> Trie mbv (Just (M.insert c (insert cs x empty) m))
+    Just trie -> Trie mbv (Just (M.insert c (insert cs x trie) m))
+insert (c:cs) x (Trie mbv Nothing) =
+  Trie mbv (Just (M.insert c (insert cs x empty) mempty))
+
+fromList :: [([Int], a)] -> Trie a
+fromList = foldr (uncurry insert) mempty
+
+alter :: (Maybe a -> Maybe a) -> [Int] -> Trie a -> Trie a
+alter f [] (Trie mbv mbm) = Trie (f mbv) mbm
+alter f (c:cs) (Trie mbv (Just m)) =
+  Trie mbv (Just (M.insert c (alter f cs $ fromMaybe empty $ M.lookup c m) m))
+alter f (c:cs) (Trie mbv Nothing) =
+  Trie mbv (Just (M.insert c (alter f cs empty) mempty))
+
+type MatchState a = (Maybe (a, Int, Trie a), Int, Trie a)
+  -- best match so far, number of code points consumed, current subtrie
+
+{-# SPECIALIZE matchLongestPrefix :: Trie a -> [Int] -> Maybe (a, Int, Trie a) #-}
+-- returns Nothing for no match, or:
+-- Just (value, number of code points consumed, subtrie)
+matchLongestPrefix :: Foldable t => Trie a -> t Int -> Maybe (a, Int, Trie a)
+matchLongestPrefix trie = either id getBest . foldM go (Nothing, 0, trie)
+ where
+   getBest (x,_,_) = x
+   -- Left means we've failed, Right means we're still pursuing a match
+   go :: MatchState a -> Int -> Either (Maybe (a, Int, Trie a)) (MatchState a)
+   go (best, consumed, Trie _ mbm) c =
+     case mbm >>= M.lookup c of
+       -- char not matched: stop processing, return best so far:
+       Nothing -> Left best
+       -- char matched, with value: replace best, keep going:
+       Just subtrie@(Trie (Just x) _)
+               -> Right (Just (x, consumed + 1, subtrie), consumed + 1, subtrie)
+       -- char matched, but not value: keep best, keep going:
+       Just subtrie@(Trie Nothing _)
+               -> Right (best, consumed + 1, subtrie)
diff --git a/test/test.hs b/test/test.hs
--- a/test/test.hs
+++ b/test/test.hs
@@ -14,4 +14,8 @@
   , assertEqual "emoji name from nonexistent" Nothing (emojiFromAlias "saotehusatnoeus")
   , assertEqual "aliases from nonexistent emoji" Nothing (aliasesFromEmoji "oo")
   , assertEqual "aliases from emoji" (Just ["rage", "pout"]) (aliasesFromEmoji "😡")
+  , assertEqual "replaced emojis" "myα→ rage(😡) is 100(💯)"
+    (replaceEmojis (\txt aliases -> case aliases of
+                                      [] -> txt
+                                      (a:_) -> a <> "(" <> txt <> ")") "myα→ 😡 is 💯")
   ]
