jQuery-style DOM manipulation library, <img align="top" height="24" src="./img/umbrellajs.svg">
UI frameworks (libraries?) provide declarative templates, event bindings, and observable state to update the view. I've been generous and expanded the size limit for this category to 4.5 kB (if you're boring, count them as 2 libraries), but also increased the star limit to 2K.
The following libraries are small and cool, but note they're about 500x less popular than preact. Kudos for deconstrucing the very essence of a "framework":
Also has `.once` method, <img align="top" height="24" src="./img/onfirejs.svg">
Event emitter pattern is fairly easy to implement yourself, but why bother when you have these cool tools? With an arms race to build the smallest one, the limit is 0.5 kB.
Modular store with good tree-shaking support, <img align="top" height="24" src="./img/nanostores.svg"> vanilla, + React <img align="top" height="24" src="./img/nanostoresreact.svg"> extra. Supports all the top frameworks.
Atomic stores with lots of framework connectors, <img align="top" height="24" src="./img/exome.svg"> + React <img align="top" height="24" src="./img/exomereact.svg"> extra. Supports all the top frameworks.
The OG signals from preact <img align="top" height="24" src="./img/preactsignals-core.svg"> core, <img align="top" height="24" src="./img/preactsignals-react.svg"> with react integration.
Another well-known state management approach is reactive programmning — operating on event streams, applying filters and transforms to end up with an observable value. Think RxJS, but tiny:
Declarative router for React / preact, <img align="top" height="24" src="./img/wouter.svg">, also available as a standalone hook: <img align="top" height="24" src="./img/wouteruse-browser-location.svg">
Parse querystrings in <img align="top" height="24" src="./img/qss.svg">. Not sure you need it, [URL API](https://developer.mozilla.org/en-US/docs/Web/API/URL) support is good.
Do stuff on URL / history changes, with path matching and parsing:
Just want to parse or match URL paths without observing them? Here you go:
Something you'd find in lodash or ramda, but smaller. Most are pretty similar and very small, with minor differences in package structure (single / package-per-helper) and tree shaking vs direct helper import.
Honorable mention: underscore, contains many sub-1 kB helpers. It does not tree-shake as well as the libraries above due to codebase structure.
Note: lodash itself is not tree-shakable, but has made many attempts at modulaity with lodash.method packages, imports from lodash/method, and lodash-es, none of which work well in practice.
Also note that much of the original lodash functionality comes built-in with modern ES. Prefer native versions over libraries as your browser target allows.
zod-style API with fine-grained checks: `v8n().string().minLength(5).first("H").last("o")`. No tree shaking, <img align="top" height="24" src="./img/vn.svg">
To check if an object matches an expected schema, you'd often use zod, yup, joi or ajv. But 90% of the time you can get what you need in under 2 kB. Note: I compare a base validation subset (core + object / array + string / number / boolean) under tree-shaking to avoid punishing libs that have more features.
Unique ID generation does not take a lot of code, but it's not someting I'd want to write myself. Limit is 500 bytes. Also note that the native crypto.randomUUID has OK support.
Manipulate colors and convert between spaces, <img align="top" height="24" src="./img/colord.svg">. Extra features come as plugins, 150b to 1.5 kB each.
Detect present and primary input method (touch / mouse) and supported events, <img align="top" height="24" src="./img/detect-it.svg">
Touch gestures like swipe, drag, pinch or doubletap are a staple of mobile UX, but recognizing a series of touchmove / pointer events as a gesture is tricky, and testing is painful. Here are two libraries that do the heavy lifting for you:
Even if you want to detect gestures yourself, juggling mouse, touch and pointer events is hard enough, and browser inconsistencies don't help. Here are two more libraries to assist with that:
Honorable mentions: any-touch attempts a modular approach to gesture detection, but the core is around 2 kB without any gesture recognizers. rc-gesture, used in ant design system, could be the only react component on the list, but babel-runtime / corejs polyfills hard-wired into the build push the ~2.5 kB size to over 10 kB.
Similar to js-search, differs in [ranking](https://kmwllc.com/index.php/2020/03/20/understanding-tf-idf-and-bm-25/) and is less strict for multi-word queries [(compare)](https://leeoniya.github.io/uFuzzy/demos/compare.html?libs=js-search,ndx,Wade&search=twilight%20sag). Supports field weights. <img align="top" height="24" src="./img/ndx-ndxquery.svg">
Text search is important for client-side filtering and autosuggests. Naive option.includes(search) has no sensible order on the results, and ignoring word boundaries gives unexpected matches like spa -> newSPAper. First, here are some libraries that prioritize word matches:
One way to find sensible inexact matches is stemming — converting words to a root form. Walked will match walking, etc. Here are a few Porter stemmers for English language:
For non-English words, I only have honorable mentions: snowball-js is 17 kB with 15 languages, lunr-languages supports 30 languages but only works with lunr, the most promising one is natural but it depends on Node.js.
Matches one string at a time, tree-shakeable scores and match highlighting. <img align="top" height="24" src="./img/fzyjs.svg"> total, or ~150 bytes for `hasMatch` only.
Quicksilver algorithm, prioritizes matches at start of word for command abbreviations (e.g. `gp` -> `git push`). One string at a time. <img align="top" height="24" src="./img/liquidmetal.svg">
Another quicksilver-based lib, tweaked for long strings. Built-in list filtering and sorting, <img align="top" height="24" src="./img/quick-score.svg"> or 1.2 kB for single-string scoring.
Fuzzy search is another take on inexact matching — the words can be modified. First, we have libraries that only allow insertion: spacecat -> SPACECrAfT. Not perfect for general-purpose text search, but great for filename, command, or URL lookups.
Finally, one library is specifically built for spellchecking:
Footnotes
See WIP for possibly awesome libraries I have found, but not yet analyzed deeply, and incubate for awesome libraries that don't meet popularity criteria yet.