257 lines
34 KiB
Plaintext
257 lines
34 KiB
Plaintext
[38;5;12m [39m[38;2;255;187;0m[1m[4mAwesome Tiny JS [0m[38;5;14m[1m[4m![0m[38;2;255;187;0m[1m[4mAwesome[0m[38;5;14m[1m[4m (https://awesome.re/badge-flat.svg)[0m[38;2;255;187;0m[1m[4m (https://awesome.re)[0m
|
||
|
||
|
||
[38;5;12m [39m
|
||
[48;5;235m[38;5;249m[49m[39m
|
||
[38;5;12m [39m
|
||
|
||
|
||
[38;5;12mTiny front-end libraries to put your bundle on a diet. Rules:[39m
|
||
|
||
[38;5;12m- Size is under 2 kB-ish, min + gzip, with all dependencies, except where noted.[39m
|
||
[38;5;12m- For multi-purpose libraries, the size of a useful subset must be under 2 kB-ish.[39m
|
||
[38;5;12m- Useful client-side. I haven't figured out participation rules for node-only libraries, and I'm not too worried about them.[39m
|
||
[38;5;12m- Second-level libraries only allowed for React, Vue, Angular, svelte. [39m
|
||
[38;5;12m- 100+ GitHub stars _or_ 500+ weekly npm installs to focus on tools with some community review.[39m
|
||
[38;5;12m- No zero-JS (CSS- or type-only) libraries. It's not awesome-css or something.[39m
|
||
|
||
[38;2;255;187;0m[4mContents[0m
|
||
|
||
[38;5;12m- [39m[38;5;14m[1mUI Frameworks[0m[38;5;12m (#ui-frameworks)[39m
|
||
[38;5;12m- [39m[38;5;14m[1mEvent Emitters[0m[38;5;12m (#event-emitters)[39m
|
||
[38;5;12m- [39m[38;5;14m[1mState Managers[0m[38;5;12m (#state-managers)[39m
|
||
[38;5;12m - [39m[38;5;14m[1mSignals[0m[38;5;12m (#signals)[39m
|
||
[38;5;12m - [39m[38;5;14m[1mReactive Programming[0m[38;5;12m (#reactive-programming)[39m
|
||
[38;5;12m- [39m[38;5;14m[1mRouters and URL Utils[0m[38;5;12m (#routers-and-url-utils)[39m
|
||
[38;5;12m- [39m[38;5;14m[1mAPI Layer[0m[38;5;12m (#api-layer)[39m
|
||
[38;5;12m- [39m[38;5;14m[1mI18N[0m[38;5;12m (#i18n)[39m
|
||
[38;5;12m- [39m[38;5;14m[1mDates and Time[0m[38;5;12m (#dates-and-time)[39m
|
||
[38;5;12m- [39m[38;5;14m[1mGeneric Utilities[0m[38;5;12m (#generic-utilities)[39m
|
||
[38;5;12m- [39m[38;5;14m[1mValidation[0m[38;5;12m (#validation)[39m
|
||
[38;5;12m- [39m[38;5;14m[1mUnique ID Generation[0m[38;5;12m (#unique-id-generation)[39m
|
||
[38;5;12m- [39m[38;5;14m[1mColors[0m[38;5;12m (#colors)[39m
|
||
[38;5;12m- [39m[38;5;14m[1mTouch Gestures[0m[38;5;12m (#touch-gestures)[39m
|
||
[38;5;12m- [39m[38;5;14m[1mText Search[0m[38;5;12m (#text-search)[39m
|
||
|
||
[38;2;255;187;0m[4mUI Frameworks[0m
|
||
|
||
[38;5;12mUI[39m[38;5;12m [39m[38;5;12mframeworks[39m[38;5;12m [39m[38;5;12m(libraries?)[39m[38;5;12m [39m[38;5;12mprovide[39m[38;5;12m [39m[38;5;12mdeclarative[39m[38;5;12m [39m[38;5;12mtemplates,[39m[38;5;12m [39m[38;5;12mevent[39m[38;5;12m [39m[38;5;12mbindings,[39m[38;5;12m [39m[38;5;12mand[39m[38;5;12m [39m[38;5;12mobservable[39m[38;5;12m [39m[38;5;12mstate[39m[38;5;12m [39m[38;5;12mto[39m[38;5;12m [39m[38;5;12mupdate[39m[38;5;12m [39m[38;5;12mthe[39m[38;5;12m [39m[38;5;12mview.[39m[38;5;12m [39m[38;5;12mI've[39m[38;5;12m [39m[38;5;12mbeen[39m[38;5;12m [39m[38;5;12mgenerous[39m[38;5;12m [39m[38;5;12mand[39m[38;5;12m [39m[38;5;12mexpanded[39m[38;5;12m [39m[38;5;12mthe[39m[38;5;12m [39m[38;5;12msize[39m[38;5;12m [39m[38;5;12mlimit[39m[38;5;12m [39m[38;5;12mfor[39m[38;5;12m [39m[38;5;12mthis[39m[38;5;12m [39m[38;5;12mcategory[39m[38;5;12m [39m[38;5;12mto[39m[38;5;12m [39m[38;5;12m4.5[39m[38;5;12m [39m[38;5;12mkB[39m[38;5;12m [39m[38;5;12m(if[39m[38;5;12m [39m[38;5;12myou're[39m[38;5;12m [39m[38;5;12mboring,[39m[38;5;12m [39m[38;5;12mcount[39m[38;5;12m [39m[38;5;12mthem[39m[38;5;12m [39m[38;5;12mas[39m[38;5;12m [39m[38;5;12m2[39m[38;5;12m [39m[38;5;12mlibraries),[39m[38;5;12m [39m[38;5;12mbut[39m[38;5;12m [39m[38;5;12malso[39m[38;5;12m [39m
|
||
[38;5;12mincreased[39m[38;5;12m [39m[38;5;12mthe[39m[38;5;12m [39m[38;5;12mstar[39m[38;5;12m [39m[38;5;12mlimit[39m[38;5;12m [39m[38;5;12mto[39m[38;5;12m [39m[38;5;12m2K.[39m[38;5;12m [39m
|
||
|
||
[38;5;12m- [39m[38;5;14m[1mpreact[0m[38;5;12m (https://github.com/preactjs/preact) - React-like API (pre-hooks). Cool ecosystem of similarly tiny tools and components. Highly recommended. [39m
|
||
|
||
[38;5;12mThe following libraries are small and cool, but note they're about [39m[38;5;14m[1m500x less popular than preact.[0m[38;5;12m (https://npmtrends.com/preact-vs-hyperapp-vs-redom) Kudos for deconstrucing the very essence of a "framework":[39m
|
||
|
||
[38;5;12m- [39m[38;5;14m[1mhyperapp[0m[38;5;12m (https://github.com/jorgebucaran/hyperapp) - vDOM framework with pure JS syntax and immutable state, [39m
|
||
[38;5;12m- [39m[38;5;14m[1mredom[0m[38;5;12m (https://github.com/redom/redom) - Hyperapp-style templates with _imperative_ event listeners and updates, [39m
|
||
|
||
[38;5;12mNow, for the [39m[38;5;14m[1mopenly experimental[0m[38;5;12m (https://npmtrends.com/@arrow-js/core-vs-fre-vs-hyperapp-vs-redom-vs-superfine-vs-vanjs-core) UI libraries:[39m
|
||
|
||
[38;5;12m- [39m[38;5;14m[1mfre[0m[38;5;12m (https://github.com/frejs/fre) - React-like library with hooks and concurrency, [39m
|
||
[38;5;12m- [39m[38;5;14m[1mvan[0m[38;5;12m (https://github.com/vanjs-org/van) - vDOM-based framework optimized for no-build setups, [39m
|
||
[38;5;12m- [39m[38;5;14m[1msuperfine[0m[38;5;12m (https://github.com/jorgebucaran/superfine) - Hyperapp with state & effect hooks removed, [39m
|
||
[38;5;12m- [39m[38;5;14m[1marrowjs[0m[38;5;12m (https://github.com/justin-schroeder/arrow-js) - Tagged templates + reactive data, [39m
|
||
|
||
[38;5;12mAnd if being declarative is not your thing:[39m
|
||
|
||
[38;5;12m- [39m[38;5;14m[1mumbrella[0m[38;5;12m (https://github.com/franciscop/umbrella) - jQuery-style DOM manipulation library, [39m
|
||
|
||
[38;2;255;187;0m[4mEvent Emitters[0m
|
||
|
||
[38;5;12mEvent 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.[39m
|
||
|
||
[38;5;12m- [39m[38;5;14m[1mmitt[0m[38;5;12m (https://github.com/developit/mitt) - Plain event emitter that I use on most projects, [39m
|
||
[38;5;12m- [39m[38;5;14m[1mnanoevents[0m[38;5;12m (https://github.com/ai/nanoevents) - Nicer unsubscribe API, but no [39m[48;5;235m[38;5;249m*[49m[39m[38;5;12m event, [39m
|
||
[38;5;12m- [39m[38;5;14m[1monfire.js[0m[38;5;12m (https://github.com/hustcc/onfire.js) - Also has [39m[48;5;235m[38;5;249m.once[49m[39m[38;5;12m method, [39m
|
||
|
||
[38;2;255;187;0m[4mState Managers[0m
|
||
|
||
[38;5;12mState managers combine observable state with actions and framework bindings, intended for app-wide state.[39m
|
||
|
||
[38;5;12m- [39m[38;5;14m[1mzustand[0m[38;5;12m (https://github.com/pmndrs/zustand) - Simple stores with pleasant actions and selectors. Vanilla [39m
|
||
[38;5;12m- [39m[38;5;14m[1mnanostores[0m[38;5;12m (https://github.com/nanostores/nanostores) - Modular store with good tree-shaking support, extra. Supports all the top frameworks.[39m
|
||
[38;5;12m- [39m[38;5;14m[1mexome[0m[38;5;12m (https://github.com/marcisbee/exome) - Atomic stores with lots of framework connectors, extra. Supports all the top frameworks.[39m
|
||
[38;5;12m- [39m[38;5;14m[1mstoreon[0m[38;5;12m (https://github.com/storeon/storeon) - Minimal redux-styled store with lots of framework connectors, + Vue, Svelte, Angular.[39m
|
||
[38;5;12m- [39m[38;5;14m[1munistore[0m[38;5;12m (https://github.com/developit/unistore) - Centralized store with actions, [39m
|
||
[38;5;12m- [39m[38;5;14m[1mteaful[0m[38;5;12m (https://github.com/teafuljs/teaful) - Store with useState-like API, , including React / preact connector.[39m
|
||
|
||
[38;2;255;187;0m[4mSignals[0m
|
||
|
||
[38;5;12mA signal-styled state manager provides observable values (aka _signals_), derived values and effects.[39m
|
||
|
||
[38;5;12m- [39m[38;5;14m[1m@preact/signals[0m[38;5;12m (https://github.com/preactjs/signals) - The OG signals from preact with react integration.[39m
|
||
[38;5;12m- [39m[38;5;14m[1musignal[0m[38;5;12m (https://github.com/WebReflection/usignal) - A smaller signal implementation, [39m
|
||
[38;5;12m- [39m[38;5;14m[1mhyperactiv[0m[38;5;12m (https://github.com/elbywan/hyperactiv) - 4 functions to make objects observable and listen to changes, [39m
|
||
[38;5;12m- [39m[38;5;14m[1mflimsy[0m[38;5;12m (https://github.com/fabiospampinato/flimsy) - Signals from Solid (it _almost_ fit into UI frameworks category itself). Author warning: _it's probably buggy._ [39m
|
||
|
||
[38;5;12mHonorable mention: [39m[38;5;14m[1moby[0m[38;5;12m (https://github.com/vobyjs/oby) _could_ make it _if_ it had tree-shaking, but otherwise is around 7 kB.[39m
|
||
|
||
[38;2;255;187;0m[4mReactive Programming[0m
|
||
|
||
[38;5;12mAnother 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:[39m
|
||
|
||
[38;5;12m- [39m[38;5;14m[1mflyd[0m[38;5;12m (https://github.com/paldepind/flyd) - Rx-styled event streams, [39m
|
||
[38;5;12m- [39m[38;5;14m[1mcallbag-basics[0m[38;5;12m (https://github.com/staltz/callbag-basics) - Rx-style event streams, [39m
|
||
|
||
[38;2;255;187;0m[4mRouters and URL Utils[0m
|
||
|
||
[38;5;12mDo stuff on URL / history changes, with path matching and parsing:[39m
|
||
|
||
[38;5;12m- [39m[38;5;14m[1mwouter[0m[38;5;12m (https://github.com/molefrog/wouter) - Declarative router for React / preact, [39m
|
||
[38;5;12m- [39m[38;5;14m[1m@nanostores/router[0m[38;5;12m (https://github.com/nanostores/router) - Routes as a nanostores store (framework-agnostic), [39m
|
||
[38;5;12m- [39m[38;5;14m[1mnavaid[0m[38;5;12m (https://github.com/lukeed/navaid) - History-based observable router, [39m
|
||
|
||
[38;5;12mJust want to parse or match URL paths without observing them? Here you go:[39m
|
||
|
||
[38;5;12m- [39m[38;5;14m[1mmatchit[0m[38;5;12m (https://github.com/lukeed/matchit) - Route parser and matcher in [39m
|
||
[38;5;12m- [39m[38;5;14m[1mregexparam[0m[38;5;12m (https://github.com/lukeed/regexparam) - Convert path to regexp in [39m
|
||
[38;5;12m- [39m[38;5;14m[1mqss[0m[38;5;12m (https://github.com/lukeed/qss) - Parse querystrings in . Not sure you need it, [39m[38;5;14m[1mURL API[0m[38;5;12m (https://developer.mozilla.org/en-US/docs/Web/API/URL) support is good. [39m
|
||
|
||
[38;2;255;187;0m[4mAPI Layer[0m
|
||
|
||
[48;5;235m[38;5;249mfetch[49m[39m[38;5;12m API has some boilerplate associated with it: serialize & parse data, reject on non-200 response, etc. These tiny packages handle it for you:[39m
|
||
|
||
[38;5;12m- [39m[38;5;14m[1mredaxios[0m[38;5;12m (https://github.com/developit/redaxios) - Drop-in axios replacement for modern browsers, [39m
|
||
[38;5;12m- [39m[38;5;14m[1mwretch[0m[38;5;12m (https://github.com/elbywan/wretch) - Chainable API with error processing and lots of extra plugins, [39m
|
||
[38;5;12m- [39m[38;5;14m[1mgretchen[0m[38;5;12m (https://github.com/truework/gretchen) - Chainable API with type-safe errors, [39m
|
||
|
||
[38;5;12mIf for some reason you still need a fetch polyfill, try this one:[39m
|
||
|
||
[38;5;12m- [39m[38;5;14m[1munfetch[0m[38;5;12m (https://github.com/developit/unfetch) - Loose fetch polyfill, [39m
|
||
|
||
[38;2;255;187;0m[4mI18N[0m
|
||
|
||
[38;5;12mA map of strings might seem enough to translate an app, but these tools also handle interpolation and some extra goodies:[39m
|
||
|
||
[38;5;12m- [39m[38;5;14m[1m@nanostores/i18n[0m[38;5;12m (https://github.com/nanostores/i18n) - Detect locale, load dictionaries, format dates / numbers, including nanostores.[39m
|
||
[38;5;12m- [39m[38;5;14m[1meo-locale[0m[38;5;12m (https://github.com/ibitcy/eo-locale) - Interpolation and dates / numbers, with react bindings.[39m
|
||
[38;5;12m- [39m[38;5;14m[1mrosetta[0m[38;5;12m (https://github.com/lukeed/rosetta) - Bare-bones template strings ([39m[48;5;235m[38;5;249m{{hello}}, {{username}}[49m[39m[38;5;12m) and custom functions for everyting else, [39m
|
||
[38;5;12m- [39m[38;5;14m[1mlingui[0m[38;5;12m (https://github.com/lingui/js-lingui) - Small core with template strings, [39m
|
||
|
||
[38;2;255;187;0m[4mDates and Time[0m
|
||
|
||
[38;5;12mDate and time manipulation in pure JS is verbose. Luckily, two of the top date libraries have sensible size:[39m
|
||
|
||
[38;5;12m- [39m[38;5;14m[1mdate-fns[0m[38;5;12m (https://github.com/date-fns/date-fns/) - Not tiny as a whole, but [39m[38;5;14m[1mmost functions[0m[38;5;12m (https://bundlephobia.com/package/date-fns) are under 1 kB each (format and parse are quite heavy).[39m
|
||
[38;5;12m- [39m[38;5;14m[1mdayjs[0m[38;5;12m (https://github.com/iamkun/dayjs) - _Almost_ moment.js-compatible API, covers most use cases, [39m
|
||
|
||
[38;5;12mAnd some more packages that only do formatting:[39m
|
||
|
||
[38;5;12m- [39m[38;5;14m[1mtinytime[0m[38;5;12m (https://github.com/aweary/tinytime) - Simple date / time formatter: [39m[48;5;235m[38;5;249m{h}:{mm} -> 9:33[49m[39m[38;5;12m, [39m
|
||
[38;5;12m- [39m[38;5;14m[1mtinydate[0m[38;5;12m (https://github.com/lukeed/tinydate) - Date / time formatter, only supports padded numeric output ([39m[48;5;235m[38;5;249mSeptember -> 09[49m[39m[38;5;12m), [39m
|
||
[38;5;12m- [39m[38;5;14m[1mtime-stamp[0m[38;5;12m (https://github.com/jonschlinkert/time-stamp) - More of the same, [39m
|
||
[38;5;12m- [39m[38;5;14m[1mms[0m[38;5;12m (https://github.com/vercel/ms) - Parse & format ms durations, e.g. [39m[48;5;235m[38;5;249m"1m" [49m[39m
|
||
[38;5;12m- [39m[38;5;14m[1mtimeago.js[0m[38;5;12m (https://github.com/hustcc/timeago.js) - Format dates into stuff like _X minutes ago_ or _in X hours,_ [39m
|
||
[38;5;12m- [39m[38;5;14m[1mfromnow[0m[38;5;12m (https://github.com/lukeed/fromnow) - More of the same, [39m
|
||
|
||
[38;5;12mNote that the built-in [39m[48;5;235m[38;5;249m[1mIntl.DateTimeFormat[0m[38;5;12m (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat) has decent support.[39m
|
||
|
||
[38;2;255;187;0m[4mGeneric Utilities[0m
|
||
|
||
[38;5;12mSomething 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.[39m
|
||
|
||
[38;5;12m- [39m[38;5;14m[1mremeda[0m[38;5;12m (https://github.com/remeda/remeda) - 90 tree-shakable helpers [39m[38;5;14m[1m(list).[0m[38;5;12m (https://bundlephobia.com/package/remeda)[39m
|
||
[38;5;12m- [39m[38;5;14m[1mrambda[0m[38;5;12m (https://github.com/selfrefactor/rambda) - 187 tree-shakable helpers [39m[38;5;14m[1m(list).[0m[38;5;12m (https://bundlephobia.com/package/rambda)[39m
|
||
[38;5;12m- [39m[38;5;14m[1mjust[0m[38;5;12m (https://github.com/angus-c/just) - 82 helpers in separate packages [39m[38;5;14m[1m(list).[0m[38;5;12m (https://anguscroll.com/just/)[39m
|
||
[38;5;12m- [39m[38;5;14m[1m@fxts/core[0m[38;5;12m (https://github.com/marpple/FxTS) - 96 tree-shakable helpers. Lazy evaluation support.[39m
|
||
|
||
[38;5;12mHonorable mention: [39m[38;5;14m[1munderscore,[0m[38;5;12m (https://github.com/jashkenas/underscore) contains many sub-1 kB helpers. It does not tree-shake as well as the libraries above due to codebase structure.[39m
|
||
|
||
[38;5;12mNote: lodash itself is not tree-shakable, but has made many attempts at modulaity with [39m[48;5;235m[38;5;249mlodash.method[49m[39m[38;5;12m packages, imports from [39m[48;5;235m[38;5;249mlodash/method[49m[39m[38;5;12m, and [39m[48;5;235m[38;5;249mlodash-es[49m[39m[38;5;12m, none of which work well in practice.[39m
|
||
|
||
[38;5;12mAlso note that much of the original lodash functionality comes built-in with modern ES. Prefer native versions over libraries as your browser target allows.[39m
|
||
|
||
[38;2;255;187;0m[4mValidation[0m
|
||
|
||
[38;5;12mTo[39m[38;5;12m [39m[38;5;12mcheck[39m[38;5;12m [39m[38;5;12mif[39m[38;5;12m [39m[38;5;12man[39m[38;5;12m [39m[38;5;12mobject[39m[38;5;12m [39m[38;5;12mmatches[39m[38;5;12m [39m[38;5;12man[39m[38;5;12m [39m[38;5;12mexpected[39m[38;5;12m [39m[38;5;12mschema,[39m[38;5;12m [39m[38;5;12myou'd[39m[38;5;12m [39m[38;5;12moften[39m[38;5;12m [39m[38;5;12muse[39m[38;5;12m [39m[38;5;12mzod,[39m[38;5;12m [39m[38;5;12myup,[39m[38;5;12m [39m[38;5;12mjoi[39m[38;5;12m [39m[38;5;12mor[39m[38;5;12m [39m[38;5;12majv.[39m[38;5;12m [39m[38;5;12mBut[39m[38;5;12m [39m[38;5;12m90%[39m[38;5;12m [39m[38;5;12mof[39m[38;5;12m [39m[38;5;12mthe[39m[38;5;12m [39m[38;5;12mtime[39m[38;5;12m [39m[38;5;12myou[39m[38;5;12m [39m[38;5;12mcan[39m[38;5;12m [39m[38;5;12mget[39m[38;5;12m [39m[38;5;12mwhat[39m[38;5;12m [39m[38;5;12myou[39m[38;5;12m [39m[38;5;12mneed[39m[38;5;12m [39m[38;5;12min[39m[38;5;12m [39m[38;5;12munder[39m[38;5;12m [39m[38;5;12m2[39m[38;5;12m [39m[38;5;12mkB.[39m[38;5;12m [39m[38;5;12m_Note:_[39m[38;5;12m [39m[38;5;12mI[39m[38;5;12m [39m[38;5;12mcompare[39m[38;5;12m [39m[38;5;12ma[39m[38;5;12m [39m[38;5;12mbase[39m[38;5;12m [39m[38;5;12mvalidation[39m[38;5;12m [39m[38;5;12msubset[39m[38;5;12m [39m[38;5;12m(core[39m[38;5;12m [39m[38;5;12m+[39m[38;5;12m [39m[38;5;12mobject[39m[38;5;12m [39m[38;5;12m/[39m[38;5;12m [39m[38;5;12marray[39m[38;5;12m [39m[38;5;12m+[39m[38;5;12m [39m[38;5;12mstring[39m[38;5;12m [39m[38;5;12m/[39m[38;5;12m [39m[38;5;12mnumber[39m[38;5;12m [39m[38;5;12m/[39m[38;5;12m [39m[38;5;12mboolean)[39m[38;5;12m [39m
|
||
[38;5;12munder[39m[38;5;12m [39m[38;5;12mtree-shaking[39m[38;5;12m [39m[38;5;12mto[39m[38;5;12m [39m[38;5;12mavoid[39m[38;5;12m [39m[38;5;12mpunishing[39m[38;5;12m [39m[38;5;12mlibs[39m[38;5;12m [39m[38;5;12mthat[39m[38;5;12m [39m[38;5;12mhave[39m[38;5;12m [39m[38;5;12mmore[39m[38;5;12m [39m[38;5;12mfeatures.[39m
|
||
|
||
[38;5;12m- [39m[38;5;14m[1mv8n[0m[38;5;12m (https://github.com/imbrn/v8n) - zod-style API with fine-grained checks: [39m[48;5;235m[38;5;249mv8n().string().minLength(5).first("H").last("o")[49m[39m[38;5;12m. No tree shaking, [39m
|
||
[38;5;12m- [39m[38;5;14m[1mbanditypes[0m[38;5;12m (https://github.com/thoughtspile/banditypes) - The smallest validation library: [39m
|
||
[38;5;12m- [39m[38;5;14m[1msuperstruct[0m[38;5;12m (https://github.com/ianstormtaylor/superstruct) - The most popular modular validation library with good tree-shaking, [39m
|
||
[38;5;12m- [39m[38;5;14m[1mvalibot[0m[38;5;12m (https://github.com/fabian-hiller/valibot) - Another modular validation library, [39m
|
||
[38;5;12m- [39m[38;5;14m[1mdeep-waters[0m[38;5;12m (https://github.com/antonioru/deep-waters) - Composable functional validators, .[39m
|
||
|
||
[38;2;255;187;0m[4mUnique ID Generation[0m
|
||
|
||
[38;5;12mUnique[39m[38;5;12m [39m[38;5;12mID[39m[38;5;12m [39m[38;5;12mgeneration[39m[38;5;12m [39m[38;5;12mdoes[39m[38;5;12m [39m[38;5;12mnot[39m[38;5;12m [39m[38;5;12mtake[39m[38;5;12m [39m[38;5;12ma[39m[38;5;12m [39m[38;5;12mlot[39m[38;5;12m [39m[38;5;12mof[39m[38;5;12m [39m[38;5;12mcode,[39m[38;5;12m [39m[38;5;12mbut[39m[38;5;12m [39m[38;5;12mit's[39m[38;5;12m [39m[38;5;12mnot[39m[38;5;12m [39m[38;5;12msometing[39m[38;5;12m [39m[38;5;12mI'd[39m[38;5;12m [39m[38;5;12mwant[39m[38;5;12m [39m[38;5;12mto[39m[38;5;12m [39m[38;5;12mwrite[39m[38;5;12m [39m[38;5;12mmyself.[39m[38;5;12m [39m[38;5;12mLimit[39m[38;5;12m [39m[38;5;12mis[39m[38;5;12m [39m[38;5;12m500[39m[38;5;12m [39m[38;5;12mbytes.[39m[38;5;12m [39m[38;5;12mAlso[39m[38;5;12m [39m[38;5;12mnote[39m[38;5;12m [39m[38;5;12mthat[39m[38;5;12m [39m[38;5;12mthe[39m[38;5;12m [39m[38;5;14m[1mnative[0m[38;5;14m[1m [0m[48;5;235m[38;5;249m[1mcrypto.randomUUID[0m[38;5;12m [39m[38;5;12m(https://developer.mozilla.org/en-US/docs/Web/API/Crypto/randomUUID)[39m[38;5;12m [39m[38;5;12mhas[39m[38;5;12m [39m[38;5;14m[1mOK[0m[38;5;14m[1m [0m[38;5;14m[1msupport.[0m
|
||
[38;5;12m(https://caniuse.com/mdn-api_crypto_randomuuid)[39m
|
||
|
||
[38;5;12m- [39m[38;5;14m[1m@lukeed/uuid[0m[38;5;12m (https://github.com/lukeed/uuid) - Real UUIDs, [39m
|
||
[38;5;12m- [39m[38;5;14m[1mnanoid[0m[38;5;12m (https://github.com/ai/nanoid) - Random IDs with larger alphabet, [39m
|
||
[38;5;12m- [39m[38;5;14m[1muid[0m[38;5;12m (https://github.com/lukeed/uid) - More of the same, [39m
|
||
[38;5;12m- [39m[38;5;14m[1mhexoid[0m[38;5;12m (https://github.com/lukeed/hexoid) - Hexadecimal IDs, [39m
|
||
|
||
[38;2;255;187;0m[4mColors[0m
|
||
|
||
[38;5;12mColor manipulation is rare in pure UI development, but very helpful for data visualization, and uses [39m[38;5;14m[1mfreaky math.[0m[38;5;12m (https://en.wikipedia.org/wiki/HSL_and_HSV#Color_conversion_formulae) Don't fry your brain, take these:[39m
|
||
|
||
[38;5;12m- [39m[38;5;14m[1mcolord[0m[38;5;12m (https://github.com/omgovich/colord) - Manipulate colors and convert between spaces, . Extra features come as plugins, 150b to 1.5 kB each.[39m
|
||
[38;5;12m- [39m[38;5;14m[1mcolr[0m[38;5;12m (https://github.com/stayradiated/colr) - More of the same, [39m
|
||
[38;5;12m- [39m[38;5;14m[1mpolychrome[0m[38;5;12m (https://github.com/cdonohue/polychrome) - More of the same, [39m
|
||
[38;5;12m- [39m[38;5;14m[1mrandomcolor[0m[38;5;12m (https://github.com/davidmerfield/randomColor) - Attractive random colors with configuration. [39m
|
||
|
||
[38;2;255;187;0m[4mTouch Gestures[0m
|
||
|
||
[38;5;12mTouch 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:[39m
|
||
|
||
[38;5;12m- [39m[38;5;14m[1malloyfinger[0m[38;5;12m (https://github.com/AlloyTeam/AlloyFinger) - Pan, swipe, tap, doubletap, longpress, _and_ pinch / rotate. My personal favorite. .[39m
|
||
[38;5;12m- [39m[38;5;14m[1mtinygesture[0m[38;5;12m (https://github.com/sciactive/tinygesture) - Configurable pan, swipe, tap, doubletap, longpress. .[39m
|
||
|
||
[38;5;12mEven 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:[39m
|
||
|
||
[38;5;12m- [39m[38;5;14m[1mpointer-tracker[0m[38;5;12m (https://github.com/GoogleChromeLabs/pointer-tracker) - Unified interface for mouse, touch and pointer events, [39m
|
||
[38;5;12m- [39m[38;5;14m[1mdetect-it[0m[38;5;12m (https://github.com/rafgraph/detect-it) - Detect present and primary input method (touch / mouse) and supported events, [39m
|
||
|
||
[38;5;12mHonorable[39m[38;5;12m [39m[38;5;12mmentions:[39m[38;5;12m [39m[38;5;14m[1many-touch[0m[38;5;12m [39m[38;5;12m(https://github.com/any86/any-touch)[39m[38;5;12m [39m[38;5;12mattempts[39m[38;5;12m [39m[38;5;12ma[39m[38;5;12m [39m[38;5;12mmodular[39m[38;5;12m [39m[38;5;12mapproach[39m[38;5;12m [39m[38;5;12mto[39m[38;5;12m [39m[38;5;12mgesture[39m[38;5;12m [39m[38;5;12mdetection,[39m[38;5;12m [39m[38;5;12mbut[39m[38;5;12m [39m[38;5;12mthe[39m[38;5;12m [39m[38;5;12mcore[39m[38;5;12m [39m[38;5;12mis[39m[38;5;12m [39m[38;5;12maround[39m[38;5;12m [39m[38;5;12m2[39m[38;5;12m [39m[38;5;12mkB[39m[38;5;12m [39m[38;5;12mwithout[39m[38;5;12m [39m[38;5;12many[39m[38;5;12m [39m[38;5;12mgesture[39m[38;5;12m [39m[38;5;12mrecognizers.[39m[38;5;12m [39m[38;5;14m[1mrc-gesture,[0m[38;5;12m [39m[38;5;12m(https://github.com/react-component/gesture)[39m[38;5;12m [39m[38;5;12mused[39m[38;5;12m [39m[38;5;12min[39m[38;5;12m [39m[38;5;12mant[39m
|
||
[38;5;12mdesign[39m[38;5;12m [39m[38;5;12msystem,[39m[38;5;12m [39m[38;5;12mcould[39m[38;5;12m [39m[38;5;12mbe[39m[38;5;12m [39m[38;5;12mthe[39m[38;5;12m [39m[38;5;12monly[39m[38;5;12m [39m[38;5;12mreact[39m[38;5;12m [39m[38;5;12mcomponent[39m[38;5;12m [39m[38;5;12mon[39m[38;5;12m [39m[38;5;12mthe[39m[38;5;12m [39m[38;5;12mlist,[39m[38;5;12m [39m[38;5;12mbut[39m[38;5;12m [39m[38;5;12mbabel-runtime[39m[38;5;12m [39m[38;5;12m/[39m[38;5;12m [39m[38;5;12mcorejs[39m[38;5;12m [39m[38;5;12mpolyfills[39m[38;5;12m [39m[38;5;12mhard-wired[39m[38;5;12m [39m[38;5;12minto[39m[38;5;12m [39m[38;5;12mthe[39m[38;5;12m [39m[38;5;12mbuild[39m[38;5;12m [39m[38;5;12mpush[39m[38;5;12m [39m[38;5;12mthe[39m[38;5;12m [39m[38;5;12m~2.5[39m[38;5;12m [39m[38;5;12mkB[39m[38;5;12m [39m[38;5;12msize[39m[38;5;12m [39m[38;5;12mto[39m[38;5;12m [39m[38;5;12mover[39m[38;5;12m [39m[38;5;12m10[39m[38;5;12m [39m[38;5;12mkB.[39m
|
||
|
||
[38;2;255;187;0m[4mText Search[0m
|
||
|
||
[38;5;12mText[39m[38;5;12m [39m[38;5;12msearch[39m[38;5;12m [39m[38;5;12mis[39m[38;5;12m [39m[38;5;12mimportant[39m[38;5;12m [39m[38;5;12mfor[39m[38;5;12m [39m[38;5;12mclient-side[39m[38;5;12m [39m[38;5;12mfiltering[39m[38;5;12m [39m[38;5;12mand[39m[38;5;12m [39m[38;5;12mautosuggests.[39m[38;5;12m [39m[38;5;12mNaive[39m[38;5;12m [39m[48;5;235m[38;5;249moption.includes(search)[49m[39m[38;5;12m [39m[38;5;12mhas[39m[38;5;12m [39m[38;5;12mno[39m[38;5;12m [39m[38;5;12msensible[39m[38;5;12m [39m[38;5;12morder[39m[38;5;12m [39m[38;5;12mon[39m[38;5;12m [39m[38;5;12mthe[39m[38;5;12m [39m[38;5;12mresults,[39m[38;5;12m [39m[38;5;12mand[39m[38;5;12m [39m[38;5;12mignoring[39m[38;5;12m [39m[38;5;12mword[39m[38;5;12m [39m[38;5;12mboundaries[39m[38;5;12m [39m[38;5;12mgives[39m[38;5;12m [39m[38;5;12munexpected[39m[38;5;12m [39m[38;5;12mmatches[39m[38;5;12m [39m[38;5;12mlike[39m[38;5;12m [39m[38;5;12m_spa[39m[38;5;12m [39m[38;5;12m->[39m[38;5;12m [39m[38;5;12mnewSPAper._[39m[38;5;12m [39m[38;5;12mFirst,[39m[38;5;12m [39m[38;5;12mhere[39m[38;5;12m [39m[38;5;12mare[39m[38;5;12m [39m[38;5;12msome[39m[38;5;12m [39m[38;5;12mlibraries[39m
|
||
[38;5;12mthat[39m[38;5;12m [39m[38;5;12mprioritize[39m[38;5;12m [39m[38;5;12mword[39m[38;5;12m [39m[38;5;12mmatches:[39m
|
||
|
||
[38;5;12m- [39m[38;5;14m[1mjs-search[0m[38;5;12m (https://github.com/bvaughn/js-search) - Feature-rich and customizable: multi-field indices, stop words, custom stemmers and tokenizers. [39m
|
||
[38;5;12m-[39m[38;5;12m [39m[38;5;14m[1mndx[0m[38;5;12m [39m[38;5;12m(https://github.com/localvoid/ndx)[39m[38;5;12m [39m[38;5;12m-[39m[38;5;12m [39m[38;5;12mSimilar[39m[38;5;12m [39m[38;5;12mto[39m[38;5;12m [39m[38;5;12mjs-search,[39m[38;5;12m [39m[38;5;12mdiffers[39m[38;5;12m [39m[38;5;12min[39m[38;5;12m [39m[38;5;14m[1mranking[0m[38;5;12m [39m[38;5;12m(https://kmwllc.com/index.php/2020/03/20/understanding-tf-idf-and-bm-25/)[39m[38;5;12m [39m[38;5;12mand[39m[38;5;12m [39m[38;5;12mis[39m[38;5;12m [39m[38;5;12mless[39m[38;5;12m [39m[38;5;12mstrict[39m[38;5;12m [39m[38;5;12mfor[39m[38;5;12m [39m[38;5;12mmulti-word[39m[38;5;12m [39m[38;5;12mqueries[39m[38;5;12m [39m[38;5;14m[1m(compare)[0m[38;5;12m [39m
|
||
[38;5;12m(https://leeoniya.github.io/uFuzzy/demos/compare.html?libs=js-search,ndx,Wade&search=twilight%20sag).[39m[38;5;12m [39m[38;5;12mSupports[39m[38;5;12m [39m[38;5;12mfield[39m[38;5;12m [39m[38;5;12mweights.[39m[38;5;12m [39m
|
||
[38;5;12m- [39m[38;5;14m[1mwade[0m[38;5;12m (https://github.com/kbrsh/wade) - Also similar, [39m[38;5;14m[1m(compare)[0m[38;5;12m (https://leeoniya.github.io/uFuzzy/demos/compare.html?libs=js-search,Wade,ndx&search=twilight%20sag) [39m
|
||
[38;5;12m- [39m[38;5;14m[1mlibsearch[0m[38;5;12m (https://github.com/thesephist/libsearch) - Index-free search (slower, but easier to use) with sane ordering [39m
|
||
|
||
[38;5;12mOne[39m[38;5;12m [39m[38;5;12mway[39m[38;5;12m [39m[38;5;12mto[39m[38;5;12m [39m[38;5;12mfind[39m[38;5;12m [39m[38;5;12msensible[39m[38;5;12m [39m[38;5;12minexact[39m[38;5;12m [39m[38;5;12mmatches[39m[38;5;12m [39m[38;5;12mis[39m[38;5;12m [39m[38;5;12m_stemming_[39m[38;5;12m [39m[38;5;12m—[39m[38;5;12m [39m[38;5;12mconverting[39m[38;5;12m [39m[38;5;12mwords[39m[38;5;12m [39m[38;5;12mto[39m[38;5;12m [39m[38;5;12ma[39m[38;5;12m [39m[38;5;12mroot[39m[38;5;12m [39m[38;5;12mform.[39m[38;5;12m [39m[38;5;12m_Walked_[39m[38;5;12m [39m[38;5;12mwill[39m[38;5;12m [39m[38;5;12mmatch[39m[38;5;12m [39m[38;5;12m_walking,_[39m[38;5;12m [39m[38;5;12metc.[39m[38;5;12m [39m[38;5;12mHere[39m[38;5;12m [39m[38;5;12mare[39m[38;5;12m [39m[38;5;12ma[39m[38;5;12m [39m[38;5;12mfew[39m[38;5;12m [39m[38;5;14m[1mPorter[0m[38;5;14m[1m [0m[38;5;14m[1mstemmers[0m[38;5;12m [39m[38;5;12m(https://vijinimallawaarachchi.com/2017/05/09/porter-stemming-algorithm/)[39m[38;5;12m [39m[38;5;12mfor[39m[38;5;12m [39m[38;5;12mEnglish[39m[38;5;12m [39m
|
||
[38;5;12mlanguage:[39m
|
||
|
||
[38;5;12m- [39m[38;5;14m[1mstemmer[0m[38;5;12m (https://github.com/words/stemmer) - [39m
|
||
[38;5;12m- [39m[38;5;14m[1mporter-stemmer[0m[38;5;12m (https://github.com/jedp/porter-stemmer) - [39m
|
||
|
||
[38;5;12mFor[39m[38;5;12m [39m[38;5;12mnon-English[39m[38;5;12m [39m[38;5;12mwords,[39m[38;5;12m [39m[38;5;12mI[39m[38;5;12m [39m[38;5;12monly[39m[38;5;12m [39m[38;5;12mhave[39m[38;5;12m [39m[38;5;12mhonorable[39m[38;5;12m [39m[38;5;12mmentions:[39m[38;5;12m [39m[38;5;14m[1msnowball-js[0m[38;5;12m [39m[38;5;12m(https://github.com/fortnightlabs/snowball-js)[39m[38;5;12m [39m[38;5;12mis[39m[38;5;12m [39m[38;5;12m17[39m[38;5;12m [39m[38;5;12mkB[39m[38;5;12m [39m[38;5;12mwith[39m[38;5;12m [39m[38;5;12m15[39m[38;5;12m [39m[38;5;12mlanguages,[39m[38;5;12m [39m[38;5;14m[1mlunr-languages[0m[38;5;12m [39m[38;5;12m(https://github.com/MihaiValentin/lunr-languages)[39m[38;5;12m [39m[38;5;12msupports[39m[38;5;12m [39m[38;5;12m30[39m[38;5;12m [39m[38;5;12mlanguages[39m[38;5;12m [39m[38;5;12mbut[39m[38;5;12m [39m[38;5;12monly[39m[38;5;12m [39m[38;5;12mworks[39m[38;5;12m [39m
|
||
[38;5;12mwith[39m[38;5;12m [39m[38;5;14m[1mlunr,[0m[38;5;12m [39m[38;5;12m(https://github.com/olivernn/lunr.js)[39m[38;5;12m [39m[38;5;12mthe[39m[38;5;12m [39m[38;5;12mmost[39m[38;5;12m [39m[38;5;12mpromising[39m[38;5;12m [39m[38;5;12mone[39m[38;5;12m [39m[38;5;12mis[39m[38;5;12m [39m[38;5;14m[1mnatural[0m[38;5;12m [39m[38;5;12m(https://github.com/NaturalNode/natural/tree/master/lib/natural/stemmers)[39m[38;5;12m [39m[38;5;12mbut[39m[38;5;12m [39m[38;5;12mit[39m[38;5;12m [39m[38;5;12mdepends[39m[38;5;12m [39m[38;5;12mon[39m[38;5;12m [39m[38;5;12mNode.js.[39m
|
||
|
||
[38;2;255;187;0m[4mFuzzy search[0m
|
||
|
||
[38;5;12m__Fuzzy[39m[38;5;12m [39m[38;5;12msearch__[39m[38;5;12m [39m[38;5;12mis[39m[38;5;12m [39m[38;5;12manother[39m[38;5;12m [39m[38;5;12mtake[39m[38;5;12m [39m[38;5;12mon[39m[38;5;12m [39m[38;5;12minexact[39m[38;5;12m [39m[38;5;12mmatching[39m[38;5;12m [39m[38;5;12m—[39m[38;5;12m [39m[38;5;12mthe[39m[38;5;12m [39m[38;5;12mwords[39m[38;5;12m [39m[38;5;12mcan[39m[38;5;12m [39m[38;5;12mbe[39m[38;5;12m [39m[38;5;12mmodified.[39m[38;5;12m [39m[38;5;12mFirst,[39m[38;5;12m [39m[38;5;12mwe[39m[38;5;12m [39m[38;5;12mhave[39m[38;5;12m [39m[38;5;12mlibraries[39m[38;5;12m [39m[38;5;12mthat[39m[38;5;12m [39m[38;5;12monly[39m[38;5;12m [39m[38;5;12mallow[39m[38;5;12m [39m[38;5;12minsertion:[39m[38;5;12m [39m[38;5;12mspacecat[39m[38;5;12m [39m[38;5;12m->[39m[38;5;12m [39m[38;5;12mSPACECrAfT.[39m[38;5;12m [39m[38;5;12mNot[39m[38;5;12m [39m[38;5;12mperfect[39m[38;5;12m [39m[38;5;12mfor[39m[38;5;12m [39m[38;5;12mgeneral-purpose[39m[38;5;12m [39m[38;5;12mtext[39m[38;5;12m [39m[38;5;12msearch,[39m[38;5;12m [39m[38;5;12mbut[39m[38;5;12m [39m[38;5;12mgreat[39m[38;5;12m [39m[38;5;12mfor[39m[38;5;12m [39m[38;5;12mfilename,[39m[38;5;12m [39m[38;5;12mcommand,[39m[38;5;12m [39m[38;5;12mor[39m[38;5;12m [39m[38;5;12mURL[39m[38;5;12m [39m
|
||
[38;5;12mlookups.[39m
|
||
|
||
[38;5;12m- [39m[38;5;14m[1mfuzzy[0m[38;5;12m (https://github.com/mattyork/fuzzy) - Index-free, can highlight matches. [39m
|
||
[38;5;12m- [39m[38;5;14m[1mfuzzy-search[0m[38;5;12m (https://github.com/wouterrutgers/fuzzy-search) - With stateful index. [39m
|
||
[38;5;12m- [39m[38;5;14m[1mfzy.js[0m[38;5;12m (https://github.com/jhawthorn/fzy.js) - Matches one string at a time, tree-shakeable scores and match highlighting. total, or ~150 bytes for [39m[48;5;235m[38;5;249mhasMatch[49m[39m[38;5;12m only.[39m
|
||
[38;5;12m- [39m[38;5;14m[1mfuzzysearch[0m[38;5;12m (https://github.com/bevacqua/fuzzysearch) - One string at a time, does not compute score / rank. [39m
|
||
[38;5;12m- [39m[38;5;14m[1mliquidmetal[0m[38;5;12m (https://github.com/rmm5t/liquidmetal) - Quicksilver algorithm, prioritizes matches at start of word for command abbreviations (e.g. [39m[48;5;235m[38;5;249mgp[49m[39m[38;5;12m -> [39m[48;5;235m[38;5;249mgit push[49m[39m[38;5;12m). One string at a time. [39m
|
||
[38;5;12m- [39m[38;5;14m[1mquick-score[0m[38;5;12m (https://github.com/fwextensions/quick-score) - Another quicksilver-based lib, tweaked for long strings. Built-in list filtering and sorting, or 1.2 kB for single-string scoring.[39m
|
||
|
||
[38;5;12mFinally, one library is specifically built for spellchecking:[39m
|
||
|
||
[38;5;12m- [39m[38;5;14m[1mfuzzyset[0m[38;5;12m (https://github.com/Glench/fuzzyset.js) - Find misspellings, e.g. missipissi -> Missisipi, Commercial usage costs $42.[39m
|
||
|
||
|
||
[38;2;255;187;0m[4mContributing[0m
|
||
|
||
[38;5;12mSuggestions welcome! See [39m[38;5;14m[1mcontributing.md[0m[38;5;12m (contributing.md), or drop an [39m[38;5;14m[1missue[0m[38;5;12m (https://github.com/thoughtspile/awesome-tiny-js/issues).[39m
|
||
|
||
[38;2;255;187;0m[4mFootnotes[0m
|
||
|
||
[38;5;12mSee [39m[38;5;14m[1mWIP[0m[38;5;12m (wip.md) for possibly awesome libraries I have found, but not yet analyzed deeply, and [39m[38;5;14m[1mincubate[0m[38;5;12m (incubate.md) for awesome libraries that don't meet popularity criteria yet.[39m
|
||
|
||
[38;5;12mCollected and reviewed by [39m[38;5;14m[1mVladimir Klepov[0m[38;5;12m (https://blog.thoughtspile.tech) in 2023.[39m
|
||
|
||
[38;5;12mtinyjs Github: https://github.com/thoughtspile/awesome-tiny-js[39m
|