Have-I-Bookmarked-Their-Tweet (HIBTT) Journey



I love browser extensions! Not all software has to be big to be useful.
Two extensions that I use almost daily are my HUD (almost). They give me valuable metadata about what I'm seeing.
The first one is the TRAY readability tool Chrome webstore page. I was judging a text I was writing, seeing if it's easy to read enough. I copied and pasted it into hemingwayeditor to see the difficulty and number of words. I also used it to see the word count of a text I was reading, to estimate my reading time. Tray readability tool does that with 1 click. After selecting the text I just click the extension icon and see all that data and more!
The second one is tabcount Chrome webstore page. At time I open 100+ tabs, spread across more than 1 window. It's often 'things to sort out'. Tabcount provides me an easy way to see progress in that. For lost tabs though, the native Chrome picker works better, with a nicer UI.
Small pieces of software are more modular. There is next to no learning curve. So they are additions to your workflow, not an overhaul. That's also why most of these are free. This does not seem to be a lockable niche. One con is the vendor lock-in; I might explore porting this to other platforms later.
That's how it looks published:
Beyond just the use of the project when browsing twitter, I had 3 learning goals. What was the hardest in this miniproject wasn't the code itself!
3 project goals
Jotai
The first thing I wanted to get more familiar with was the Jotai state management library.
I observed it's not as popular as Redux, but it seemed quite straightforward to work with. Especially compared with Zustand
.
Something just didn't click when I was browsing their page.
vincalst on reddit contrasted the two as top-down Zustand and bottom up Jotai.
I like Jotai for that. That is a minimalistic approach. It is more agile, the big picture is an organic emergent structure grown from the small states. You don't need to plan everything out in advance.
I created some atoms, and derivation of state from it is very convenient
const DEFAULT_BOOKMARKS: chrome.bookmarks.BookmarkTreeNode[] = []; const bkmrksAtom = atom(DEFAULT_BOOKMARKS); const userFromUrl = atom((get) => getUserFromUrl(get(tabUrlAtom)));
One thing I found is that I am accustomed to useState
and it's my goto. I might follow the advice from redditors arguing to keep useState
for local state, and use Jotai Atoms for complex state and global state. So far I've been using React Context for global state, can't say I love it.
Chrome APIs: Tabs and Bookmarks
Besides Jotai, I specifically wanted to work on a project that is a Chrome extension. I use bookmarks extensively and adding tools to help me use them better, more efficiently is valuable to me. I do use Obsidian for knowledge mapping, but as the movement of data from Chrome to there is the bottleneck. Data is easy to manipulate in either of those locations, but the border between them is hard to bridge.
I have some projects on my backlog that are extensions too! Follow me on twitter to get updates.
Publishing process and art
The third goal was to get familiar with the publishing process. What use is making tools without publishing them!
I had to make a new gmail account for development purposes and sign up for chrome webstore publishing.
There was a bit more paperwork than I expected, but the most struggle I had was with images for the store.
see the generated image!
The end result was this pic, (remember I'm not an artist haha).
I let myself be inspired by AI - prompting for
pixel art bird
, and then representing it myself using pixelart tool.
Then I made it to the correct size using this Chrome extension generator.
I expected to wrap up the publishing process in 30 minutes, took me about 3 hours. Now I know the cover art and icon are important to do beforehand!
Edit: fixing images to this post
I spent considerable time fixing the issue of images not displaying here correctly.
That could have been because of my Hugo setup, or peculiarities of Github Pages.
A path that works now is with relative pathing from the static directory.
I followed the official docs on the config file.
config.toml
contains a field for staticDir
, which I didn't use before.
Relative pathing for Markdown - the one understood by VSCode has proven to be a false friend. When I click the link working right in deployment, VSCode does not respond here correctly. It does not find the file
Try it out
Here you can checkout the published version. 8 people already did, which is more than I expected through the first month!