Have a lot of custom/personal emojis and want to keep track of them? lemmy-emojis just got support for that! (It’s exactly as janky as the rest of the extension.) Btw, if you only want to use the extention to keep track of your own emojis and don’t want to have emojis from some lemmy instance, clearing the domain setting (and turning off “update automatically,” since it is unnecessary) will let you do that
Don’t know what lemmy-emojis is? It’s for you, the non-hexbear that want’s to use hexbear’s emojis. Or if you want to use dbzer0’s, or some third instance. It let’s you do that.
ⓘ This user is suspected of being a cat. Please report any suspicious behavior.
Oh, that’s fun!
Good to see you found
in addition to
, I wasn’t sure if I had used that one enough.Honestly, I kinda forgot it exists. This is why I need a plugin for personal emoji management.

Some day I need to give making this (into a userscript that will) work on my phone a shot

The problem is figuring out how to display it. Fetching the list and changing it’s structure (which was necessary in my extension) is pretty easy. Storing stuff too. Personal emojis could potentially just be a list hard-coded into the script… But getting it displayed… that’s not quite as easy. If I knew how to do it I might take a shot.
Edit: that thing where you start out looking at the code for an AO3 y/n userscript and end up reading smut…
ⓘ This user is suspected of being a cat. Please report any suspicious behavior.
Proof of concept - I had some brief tests where it didn’t work which I think are related to whether it’s fast enough to modify the data, but usually it seemed to work. I doubt this approach would work with fetching another site’s emojis in real time for that reason, but if a URL can get plugged in somewhere and the result cached into local storage or Indexed DB it might be fast enough to read the data from one of them.
// ==UserScript== // @name Lemmoji // @namespace http://something.here/ // @version 2026-07-13 // @description add emojis to lemmy // @author Trying2KnowMyself, theoretically with some code stolen from Edie except that I've only made it to a proof of concept phase so far and didn't actually steal code yet // @match https://hexbear.net/* // @icon https://hexbear.net/pictrs/image/79f0e1d8-b425-47fe-a1ac-9ee1ab6c246d.png // @grant none // @run-at document-start // ==/UserScript== (function() { 'use strict'; // it might already be set let isoData = window.isoData; if (window.isoData) { console.log("isoData already defined, might not work?"); augmentCustomEmojis(isoData); } Object.defineProperty(window, 'isoData', { get () { console.log("getting isoData"); return isoData; }, set(value) { console.log("setting isoData"); augmentCustomEmojis(value); } }); function augmentCustomEmojis(value) { console.log("augmenting isoData"); const biggestId = value.site_res.custom_emojis.reduce((acc, curr) => Math.max(acc, curr.custom_emoji.id), 0); value.site_res.custom_emojis.push({ "custom_emoji": { "id": biggestId + 1, "local_site_id": 1, "shortcode": "catclops", "image_url": "https://lemmy.ml/pictrs/image/fbab8b2d-2189-4311-b26f-61ae7cfa632c.png", "alt_text": "catclops", "category": "Custom", "published": "2023-06-17T21:15:35.303290Z" }, "keywords": [{ "custom_emoji_id": biggestId + 1, "keyword": "catclops" }] }); isoData = value } })();It was interesting to see that
/api/v3/siteonly gets hit on login - I briefly locked myself out with a login rate limit. Even more interesting to see why:isoDatagets set via the HTML if you’re already logged in.Cool. Seems to work perfectly fine for me, so I can’t debug the problem you encountered. You can store stuff with https://violentmonkey.github.io/api/gm/#gm_setvalue
// ==UserScript== // @name Lemmoji // @namespace http://something.here/ // @version 2026-07-13 // @description add emojis to lemmy // @author Trying2KnowMyself, theoretically with some code stolen from Edie except that I've only made it to a proof of concept phase so far and didn't actually steal code yet // @match https://hexbear.net/* // @icon https://hexbear.net/pictrs/image/79f0e1d8-b425-47fe-a1ac-9ee1ab6c246d.png // @grant none // @run-at document-start // ==/UserScript== (function() { 'use strict'; let emojis = [ { shortcode: "catclops", image_url: "https://lemmy.ml/pictrs/image/fbab8b2d-2189-4311-b26f-61ae7cfa632c.png", alt_text: "catclops", keywords: [ "catclops" ] } ] // it might already be set let isoData = window.isoData; if (window.isoData) { console.log("isoData already defined, might not work?"); augmentCustomEmojis(isoData); } Object.defineProperty(window, 'isoData', { get () { console.log("getting isoData"); return isoData; }, set(value) { console.log("setting isoData"); augmentCustomEmojis(value); } }); function augmentCustomEmojis(value) { console.log("augmenting isoData"); //const biggestId = value.site_res.custom_emojis.reduce((acc, curr) => Math.max(acc, curr.custom_emoji.id), 0); for (let i in emojis) { let keywords = []; for (let keyword in emojis[i].keywords) { keywords.push({ //"custom_emoji_id": biggestId + 1 + Number(i), "keyword": emojis[i].keywords[keyword] }); } value.site_res.custom_emojis.push({ "custom_emoji": { //"id": biggestId + 1 + Number(i), //"local_site_id": 1, "shortcode": emojis[i].shortcode, "image_url": emojis[i].image_url, "alt_text": emojis[i].alt_text, "category": "Custom", //"published": "2023-06-17T21:15:35.303290Z" }, "keywords": keywords }); } isoData = value } })();
ⓘ This user is suspected of being a cat. Please report any suspicious behavior.
Nice! I didn’t even think to try skipping some of those fields. I’ll have to see if I can throw another tab on settings for emoji management next.
E: throwing the tab there worked fine, but you can’t switch back to whichever tab you were on last. Maybe I should just throw a section under settings instead of trying to be fancy.
Edie [it/it/its/its/itself, she/her/her/hers/herself]@lemmy.encryptionin.spaceOPEnglish
1·5 hours agoI happened to know from my extension that those fields weren’t used in the emoji-mart (the thingy that pops up), though I didn’t know if some lemmy specific thing would need it, seems like it doesn’t.
ⓘ This user is suspected of being a cat. Please report any suspicious behavior.
Some general thoughts after poking around at it a bit + prior userscripts experience:
- userscripts modify the page, so displaying it would mean inserting it somewhere on the site rather than having an extension button to show it - that leaves two possible routes: replace the emoji picker on input boxes, or throw it somewhere common like the site header
- if options are not hard coded, they would similarly need to be rendered somewhere to support config changes - hard coded would be an easier starting point to get the rest of it working
- throwing it somewhere common is probably easier, because the general approach I’ve seen/used previously is that you create a promise that loops trying to select a known element with a setTimeout some number of times, and appends/prepends the desired element to the container it finds
- getting it to replace the built in picker would probably require first using that approach to attach event listeners to reply buttons and then using the events to trigger the replacement behaviour when someone starts to comment + additional handling for the create post page
- best practice for userscripts is to restrict the URLs they run on - something that potentially runs on your bank website is much more concerning than something that only runs on one site, but it’d be difficult to limit it appropriately enough while still listing/supporting most instances
- some userscripts will also intercept network calls by overriding methods on XMLHttpRequest.prototype and attaching load event listeners when the path matches, though I’ve mostly seen/used this in the context of wanting to capture the results to do other things with them - if that or similar could instead be used to augment the emojis response, then that could allow additional data to be added to the existing picker without replacing it
I’ll probably take another look at things later, but figured I’d share my thoughts so far.


