stickies: The DOM Utility That Refuses to Lose Its Target
Aiden Bai’s library treats anchors as identities it can re-find, not nodes it can trust forever.

Two years ago, I started ✦ Million.js as a small experiment to make the Virtual DOM faster.
- Stickies treats an anchor as recoverable identity, so the sticker can survive re-renders and node replacement.
- Its real trick is layered lookup, starting with selectors and ending with structural similarity when the exact node disappears.
- Observers and requestAnimationFrame keep the overlay responsive without turning every movement into constant polling.
- The polished part is visibility and attachment logic, which makes the library behave more like a small window manager than a floating div.
Most overlay tools assume a target node will stay put. In a real app, that is the first lie the DOM tells you.
Stickies is interesting because it does not just chase coordinates. It tries to keep a sticker attached to the same content even after re-renders, layout shifts, and node replacement.
Why this is harder than it looks
Pinned comments, tooltips, and annotations look simple until the page starts changing. A flex row reorders, React swaps a node, a resize shifts everything, and the old reference is suddenly stale.
Absolute positioning and CSS sticky both solve part of the problem, but neither one preserves the semantic relationship between an overlay and the thing it points to. They know where something was. They do not know how to find it again.
The anchor is not a node. It is an identity.
That is the trick stickies is really built around. The anchor is not treated like a fragile DOM pointer. It is treated like a bundle of clues that can be used to re-identify the target after the tree changes.
The repo research points to three clues working together: CSS selectors, React-aware lookup, and ancestor similarity. If the exact node disappears, stickies can search for the closest structural match instead of giving up.
const anchor = {
selector: "[data-note='42']",
reactSelector: 'CommentCard > Paragraph',
ancestors: ['article', 'section', 'p']
}
const resolved =
querySelector(anchor.selector) ??
queryReactTree(anchor.reactSelector) ??
bestAncestorMatch(anchor.ancestors)
That matters because modern UIs rarely move a node in place. They replace it. A library that only caches a reference is one rerender away from being wrong.
How the library keeps the illusion alive
The recovery logic would not matter if the sticker updated sluggishly. Stickies pairs it with observers and a frame-synced render loop so changes land when the browser is ready to paint.
- MutationObserver watches DOM churn and attribute changes.
- ResizeObserver catches geometry changes.
- IntersectionObserver helps track visibility.
- requestAnimationFrame batches reconciliation into the next paint.
The state is designed to serialize cleanly too, which matters if you want a refresh not to erase the user's attachment work. A UI note should survive more than one paint cycle.
That is the difference between a responsive overlay and a janky one. The library waits for signals, then does the minimum work needed to reconcile position, visibility, and attachments.
When should the sticker hide or flip?
Occlusion detection is the quiet tell. Stickies does not just ask whether the anchor exists, it asks whether it is actually visible and whether the attachment still fits in the viewport. When space runs out, the UI can hide or flip instead of hanging awkwardly off the edge.
What this beats, and what it does not
Stickies is not a replacement for layout primitives. It solves a narrower problem: keeping a floating relationship stable while the DOM stays in motion.
| Approach | What it handles well | What breaks | Why stickies differs |
|---|---|---|---|
| Absolute positioning | Simple overlays on static pages | Scroll, resize, mutation, and reflow change the math | Re-finds the anchor and reconciles against a live target |
| CSS sticky | Pinning inside normal flow | It cannot follow a semantic anchor through re-rendering | Keeps an explicit attachment to a chosen node |
| Manual scroll handlers | Full control over placement | Edge cases pile up fast | Uses observers and frame batching instead of constant polling |
| General overlay libs | Placement and collision handling | Anchor identity disappears after rerender | Adds structural re-acquisition and visibility logic |
That is why the library feels more like infrastructure than UI sugar. If your product only needs a badge to sit in one place, simple CSS wins. If your product lets users annotate content that React may replace under them, anchor persistence becomes the feature.
Why Aiden Bai keeps building tools like this
The maintainer through-line is not hard to see. Aiden Bai is known for Million.js, and the same taste for pushing on abstraction boundaries shows up here: take a familiar browser problem and solve it at the layer where it actually breaks.
That quote is about Million.js, not stickies, but it captures the same instinct. The interest is in system-level leverage, not cosmetic polish.
Bottom line
Stickies is a browser utility with a memory problem, and it solves it by treating anchors as identities that can be lost and recovered. That is a small idea with a big practical payoff: overlays that stay honest even when the DOM does not.