Production-ready React utilities for modern applications
Website • Ecosystem • Quick Start • Why usefy? • Packages
✅ Stable & production-ready. usefy follows semantic versioning — breaking changes only ever land in a new major version.
usefy is a monorepo of production-ready React packages published under @usefy/*. Each package under packages/ stands on its own — install exactly what you need. Some are umbrellas that bundle a whole family (@usefy/hooks); others are single-purpose packages (@usefy/memory-monitor). New packages — another umbrella, or a standalone UI package — simply drop in at the same level.
| Package | Description |
|---|---|
@usefy/hooks |
70+ lightweight React hooks (umbrella — each hook is also published on its own as @usefy/use-*) |
@usefy/memory-monitor |
Real-time browser memory monitoring component |
@usefy/virtual-keyboard |
On-screen virtual keyboard with a declarative layout engine and headless hook |
@usefy/network-indicator |
Drop-in online/offline status banner with an auto-dismissing "back online" confirmation |
@usefy/scroll-progress |
Drop-in reading-progress bar that fills as you scroll the page or any container |
@usefy/spotlight-tour |
Guided onboarding tours with an animated spotlight overlay, gates, persistence, and enterprise a11y |
@usefy/confetti |
Canvas confetti & celebration engine — pooled particle physics, presets, custom shapes, headless core |
@usefy/signature-pad |
Electronic signature input — hand-written ink engine with velocity-based stroke width, PNG/SVG/JSON exports, headless core |
@usefy/diff-viewer |
Text diff viewer — linear-space Myers engine, word-level highlighting, collapsible context, row virtualization, headless core |
@usefy/qr-code |
QR code generator — hand-written ISO/IEC 18004 encoder, SVG/canvas/PNG output, module & eye shapes, gradients, logo safety validation, RSC-safe headless core |
@usefy/qr-scanner |
QR code scanner — native BarcodeDetector with a hand-written ISO/IEC 18004 decoder fallback, camera and still image, Reed–Solomon error correction, optional Web Worker |
A collection of 70+ lightweight React hooks for common patterns like state management, timing, storage, events, and more.
pnpm add @usefy/hooksimport { useToggle, useDebounce, useLocalStorage } from "@usefy/hooks";
function App() {
const { value: isOpen, toggle } = useToggle(false);
const [query, setQuery] = useState("");
const debouncedQuery = useDebounce(query, 300);
const [theme, setTheme] = useLocalStorage("theme", "light");
// ...
}Highlights:
-
useToggle,useCounter,useObjectState— State management (boolean, counter, object patch/merge) -
useRafState—useStatethat batches updates torequestAnimationFrame(one commit per frame) -
useDebounce,useThrottle,useTimer,useTimeout,useInterval— Timing utilities -
useLocalStorage,useSessionStorage,useCookie— Persistent storage (localStorage, sessionStorage, cookies) -
useEventListener,useOnClickOutside,useHover,useLongPress,useScrollLock,useFocusTrap,useFocusWithin— DOM events, gestures & modal accessibility -
useInfiniteScroll— Sentinel-driven infinite loading built on IntersectionObserver -
usePagination— Headless pagination state (page count, slice-ready range, ellipsis-aware pager model) -
useKeyPress,useHotkeys— Keyboard shortcuts, combinations, and sequences -
useMap,useSet,useList,useQueue,useStack— Map / Set / array / FIFO queue / LIFO stack data structure state management -
useSelection— Multi/single selection state for lists and tables (Set-based, checkbox-ready) -
useHistoryState— Undo/redo state history with time-travel -
useStep— Multi-step navigation for wizards, forms, and carousels -
useIntersectionObserver,useResizeObserver,useMutationObserver,useMeasure,useScrollPosition,useGeolocation,useWindowSize,useNetworkState,usePageVisibility,useIdle,usePermission,useUserMedia,useScript— Browser APIs & element measurement -
useAsyncFn,useAsync,usePolling— Async lifecycle tracking (manual-trigger / auto-run / interval polling with backoff and AbortController cancellation) -
useSignal— Event-driven communication -
useMemoryMonitor— Memory monitoring hook -
useIsClient,useIsomorphicLayoutEffect,usePrevious,useLatest,useEventCallback,useUpdateEffect,useMount,useIsFirstRender— SSR & lifecycle utilities -
useMediaQuery,usePreferredColorScheme,useReducedMotion,useDarkMode,useDocumentTitle— Responsive, theme & accessibility -
useControllableState,useMergedRefs,useDisclosure— Component-library primitives (controllable state, ref merging, open/close state)
Real-time memory monitoring panel with leak detection, snapshots, and reports
(built on @usefy/use-memory-monitor).
pnpm add @usefy/memory-monitorimport { MemoryMonitor } from "@usefy/memory-monitor";
function App() {
return (
<div>
<h1>My Application</h1>
<MemoryMonitor
mode="development"
position="right"
onLeakDetected={(analysis) => console.warn("Leak:", analysis)}
/>
</div>
);
}On-screen (virtual) keyboard for kiosks, PIN pads, and D-pad UIs — a declarative
layout engine, a headless useVirtualKeyboard hook, and enterprise a11y.
pnpm add @usefy/virtual-keyboardimport { useRef } from "react";
import { VirtualKeyboard, qwertyLayout } from "@usefy/virtual-keyboard";
function Search() {
const inputRef = useRef<HTMLInputElement>(null);
return (
<>
<input ref={inputRef} placeholder="Search…" />
<VirtualKeyboard inputRef={inputRef} layouts={qwertyLayout} submitOnEnter />
</>
);
}Drop-in online/offline status banner — renders nothing while online, warns when
the connection drops, and flashes an auto-dismissing "Back online" confirmation
on reconnect (built on @usefy/use-network-state).
pnpm add @usefy/network-indicatorimport { NetworkIndicator } from "@usefy/network-indicator";
function App() {
return (
<>
<YourApp />
{/* Mount once at the root — zero-config, SSR-safe */}
<NetworkIndicator position="top" onlineDuration={3000} />
</>
);
}Drop-in reading-progress bar — a thin fixed bar pinned to the top (or bottom) of
the viewport that fills as you scroll the page or any scrollable container
(built on @usefy/use-scroll-position).
pnpm add @usefy/scroll-progressimport { ScrollProgress } from "@usefy/scroll-progress";
function App() {
return (
<>
{/* Mount once — zero-config, accessible, SSR-safe */}
<ScrollProgress color="#8b5cf6" height={4} />
<YourApp />
</>
);
}Guided onboarding tours — dims the page, cuts an animated spotlight hole around
each step's target, and shows a step tooltip beside it. Interaction gates,
missing-target policies, tourId persistence, a pulsing beacon, full keyboard +
screen-reader support, and the whole state machine also available headless.
pnpm add @usefy/spotlight-tourimport { SpotlightTour } from "@usefy/spotlight-tour";
function App() {
return (
<SpotlightTour
defaultOpen
tourId="app-onboarding"
steps={[
{ title: "Welcome! 👋", content: "Let's take a quick look around." },
{ target: "#search", title: "Search", content: "Find anything here." },
{ target: "#create", content: "Click to create your first project.",
advanceOn: { event: "click" } }, // gated step
]}
/>
);
}Canvas confetti & celebration effects — bursts, fireworks, cannons, snow —
driven by a hand-written, zero-dependency particle engine (gravity, drag, 3D
tumble, object pooling, provably-idle rAF loop). One-liner fireConfetti(),
a <Confetti /> overlay + useConfetti() hook, presets, emoji/image/Path2D
shapes, and the whole engine also available headless.
pnpm add @usefy/confettiimport { fireConfetti } from "@usefy/confetti";
function ShipItButton() {
return (
<button onClick={() => fireConfetti({ origin: { y: 0.8 }, spread: 70 })}>
🚀 Ship it
</button>
);
}Electronic signature input — draw with mouse, finger, or stylus and export a trimmed PNG, true-vector SVG, or replayable JSON. Hand-written ink engine: Bézier smoothing + velocity/pressure-based variable stroke width, stroke-level undo/redo, on-canvas "sign here" guideline (never exported), read-only restore, and the whole engine also available headless. Zero dependencies.
pnpm add @usefy/signature-padimport { SignaturePad } from "@usefy/signature-pad";
function ConsentForm() {
return (
<div style={{ height: 200 }}>
<SignaturePad guideline onChange={({ isEmpty }) => setSigned(!isEmpty)} />
</div>
);
}Text diff viewer — render the difference between two texts side-by-side or unified, with line numbers, word-level highlighting inside changed lines, and unchanged regions collapsed behind expandable context. Hand-written linear-space Myers engine (zero deps), row virtualization for 20k-line diffs, an explicit cost guard, a bring-your-own-highlighter seam, real table accessibility, and the whole engine also available headless.
pnpm add @usefy/diff-viewerimport { DiffViewer } from "@usefy/diff-viewer";
function Review({ before, after }) {
return <DiffViewer oldText={before} newText={after} view="split" />;
}QR code generator — a hand-written ISO/IEC 18004 encoder (Reed–Solomon over
GF(256), optimal mode segmentation, penalty-scored mask selection) feeding SVG,
canvas and PNG from one geometry pipeline. Module and finder-eye shapes,
gradients, and logo embedding with logoSafety() measuring occlusion against
what the error-correction level can actually recover. The headless entry ships
no "use client" and no React, so a server component renders a code with zero
client JavaScript. Zero dependencies.
pnpm add @usefy/qr-codeimport { QRCode } from "@usefy/qr-code";
function ShareLink() {
return <QRCode value="https://usefy.dev" size={200} level="Q" title="Open usefy.dev" />;
}QR code scanner — the platform's BarcodeDetector where it exists, and a
hand-written ISO/IEC 18004 decoder where it does not: adaptive binarization,
sub-pixel finder detection, four-point perspective correction, Reed–Solomon
error correction, ECI and Kanji. Camera and still image, so a desktop
without a webcam is a first-class case rather than an error state. Corners come
back in source pixels with a helper that maps them through object-fit, and an
optional ./worker entry moves decoding off the main thread. The counterpart to
@usefy/qr-code, sharing its ISO tables so the two cannot disagree.
pnpm add @usefy/qr-scannerimport { QRScanner } from "@usefy/qr-scanner";
function CheckIn() {
// A QR payload is untrusted input — validate before acting on it.
return <QRScanner onScan={(result) => console.log(result.text)} />;
}| Need | Install | Import |
|---|---|---|
| All hooks | pnpm add @usefy/hooks |
import { useToggle } from "@usefy/hooks" |
| Single hook | pnpm add @usefy/use-toggle |
import { useToggle } from "@usefy/use-toggle" |
| Memory monitor | pnpm add @usefy/memory-monitor |
import { MemoryMonitor } from "@usefy/memory-monitor" |
| Virtual keyboard | pnpm add @usefy/virtual-keyboard |
import { VirtualKeyboard } from "@usefy/virtual-keyboard" |
| Network status banner | pnpm add @usefy/network-indicator |
import { NetworkIndicator } from "@usefy/network-indicator" |
| Scroll progress bar | pnpm add @usefy/scroll-progress |
import { ScrollProgress } from "@usefy/scroll-progress" |
| Onboarding tour | pnpm add @usefy/spotlight-tour |
import { SpotlightTour } from "@usefy/spotlight-tour" |
| Confetti / celebrations | pnpm add @usefy/confetti |
import { fireConfetti } from "@usefy/confetti" |
| Signature input | pnpm add @usefy/signature-pad |
import { SignaturePad } from "@usefy/signature-pad" |
| Text diff viewer | pnpm add @usefy/diff-viewer |
import { DiffViewer } from "@usefy/diff-viewer" |
| QR codes | pnpm add @usefy/qr-code |
import { QRCode } from "@usefy/qr-code" |
| QR scanning | pnpm add @usefy/qr-scanner |
import { QRScanner } from "@usefy/qr-scanner" |
All packages require React 18 or 19:
{
"peerDependencies": {
"react": "^18.0.0 || ^19.0.0"
}
}Some packages may have additional peer dependencies (check individual package docs).
|
|
- TypeScript First — Complete type safety with full autocomplete support
- SSR Compatible — Works seamlessly with Next.js, Remix, and other SSR frameworks
- Tree Shakeable — Import only what you need to optimize bundle size
- Well Tested — High test coverage ensures reliability and stability
- Well Documented — Detailed documentation with practical examples
- Interactive Demos — Try everything in our Storybook playground
| Hook | Description |
|---|---|
useToggle |
Boolean state with toggle, setTrue, setFalse |
useCounter |
Counter with increment, decrement, reset |
useDebounce |
Value debouncing with leading/trailing edge |
useDebounceCallback |
Debounced callbacks with cancel/flush |
useThrottle |
Value throttling for rate-limiting |
useThrottleCallback |
Throttled callbacks with cancel/flush |
useTimer |
Countdown timer with drift compensation |
useTimeout |
Declarative setTimeout with reset/clear and isPending |
useInterval |
Declarative setInterval with start/stop/toggle and isRunning |
useLocalStorage |
localStorage with cross-tab sync |
useSessionStorage |
sessionStorage persistence |
useCookie |
Browser cookie as React state, SSR-aware |
useEventListener |
DOM events with auto cleanup |
useOnClickOutside |
Outside click detection |
useClickAnyWhere |
Global click detection |
useCopyToClipboard |
Clipboard operations |
useGeolocation |
Device geolocation with tracking |
useUserMedia |
Camera & microphone streams with guaranteed teardown |
useIntersectionObserver |
Element visibility detection |
useResizeObserver |
Element size tracking (content/border/device-pixel box) with debounce/throttle and SSR |
useWindowSize |
Window size tracking with debounce/throttle and SSR support |
useHover |
Element hover detection with delay |
useKeyPress |
Keyboard key, shortcut, and combination detection |
useMap |
Map data structure state with immutable updates |
useSet |
Set data structure state with immutable updates |
useList |
Array state with push/filter/sort/insertAt/updateAt |
useQueue |
FIFO queue state with enqueue/dequeue and immutable updates |
useStack |
LIFO stack state with push/pop/peek and immutable updates |
useHistoryState |
Undo/redo state history with time-travel |
useStep |
Multi-step navigation for wizards, forms, carousels |
useSignal |
Event-driven communication |
useUnmount |
Unmount callback |
useInit |
One-time initialization |
useMemoryMonitor |
Browser memory monitoring |
useIsClient |
True once hydrated on the client (SSR guard) |
useIsomorphicLayoutEffect |
SSR-safe useLayoutEffect |
usePrevious |
Value from the previous render |
useLatest |
Ref that always holds the latest value |
useEventCallback |
Stable callback that sees the latest state |
useUpdateEffect |
useEffect that skips the first render |
useMount |
Run a callback once on mount |
useIsFirstRender |
True only on the first render |
useMediaQuery |
Match CSS media queries (matchMedia, SSR-safe) |
usePreferredColorScheme |
System color scheme (prefers-color-scheme) |
useReducedMotion |
Reduced-motion preference (a11y) |
useDarkMode |
Dark mode: system/light/dark, persistence, DOM apply |
useDocumentTitle |
Set document.title with restore-on-unmount |
useControllableState |
Controlled/uncontrolled state primitive (Radix/Mantine pattern) |
useMergedRefs |
Merge multiple refs into one (forwardRef helper) |
useDisclosure |
open/close/toggle state for modals, drawers, popovers |
useMutationObserver |
Watch an element for DOM mutations (childList/attributes/characterData) |
useScrollPosition |
Throttled scroll offset (x, y) of the window or an element |
useScrollLock |
Lock body scroll for modals/drawers — iOS-aware, nested-lock counted |
useHotkeys |
High-level keyboard shortcuts — combos, sequences, mod alias, scoping, input-field guard |
useFocusTrap |
Trap keyboard focus in a subtree (modals/dialogs) — Tab cycling, initial/return focus, Escape |
useFocusWithin |
Track whether keyboard focus is anywhere within a subtree — reactive :focus-within with onFocus/onBlur edges |
useLongPress |
Long-press ("press and hold") gestures for mouse and touch — time threshold, movement cancellation, onStart/onFinish/onCancel
|
useAsyncFn |
Run a manual-trigger async function with idle/pending/success/error lifecycle, race-safe stale-response guarding, and unmount safety |
useAsync |
Full async task lifecycle — object-style state, immediate auto-run, and AbortController cancellation |
usePolling |
Poll an async function on an interval — non-overlapping self-scheduling ticks, pause/resume, an enabled gate, and exponential backoff |
useRafState |
A drop-in useState that batches updates to requestAnimationFrame — rapid scroll/resize/pointer/animation updates coalesce to at most one commit per frame |
useObjectState |
Object state with immutable partial updates (patch/merge) and reset |
useSelection |
Multi/single selection state for lists and tables — Set-based, checkbox-ready with indeterminate support |
useInfiniteScroll |
Sentinel-driven infinite loading built on IntersectionObserver — fires loadMore once per intersection, respects hasMore/loading/enabled
|
usePagination |
Headless pagination state machine — controlled/uncontrolled current page, derived pageCount, a slice-ready 0-based range, and an ellipsis-aware items pager model |
useNetworkState |
Online/offline status + Network Information API (effectiveType, downlink, saveData), SSR-safe |
usePageVisibility |
Track tab/window visibility (foreground vs. background) via the Page Visibility API, with optional onChange and SSR support |
useIdle |
Report user inactivity after a timeout, with throttled activity listeners, visibility awareness, and SSR support |
usePermission |
Read Permissions API status with live updates — { state, status, isSupported, error }, SSR-safe, accepts any permission name |
useScript |
Load an external script with idle/loading/ready/error status, <script> deduplication across components, and ref-counted cleanup — SSR-safe |
useUserMedia |
Camera and microphone streams — getUserMedia lifecycle, device enumeration and switching, torch, normalized errors, and a teardown guarantee (no track outlives the component) |
| Export | Description |
|---|---|
MemoryMonitor |
Real-time memory monitoring panel with leak detection, snapshots, and reports |
| Export | Description |
|---|---|
VirtualKeyboard |
On-screen keyboard component (inline / docked / floating, with an optional trigger) bound to any input |
useVirtualKeyboard |
Headless engine — modifier state, layout engine, caret-aware editing, prop-getters |
qwertyLayout, azertyLayout, qwertzLayout, dvorakLayout, colemakLayout, numericLayout, phoneLayout, emailLayout
|
Built-in data-driven layouts (5 Latin + numeric / phone / email) |
createLayout, resolveLayout, randomizeLayout
|
Author a custom layout / resolve one against modifiers / shuffle char-key positions (seedable) |
identityComposer |
Default 1:1 composer (IME seam) |
Also ships a @usefy/virtual-keyboard/headless entry (hook + engine + types, no CSS), an opt-in @usefy/virtual-keyboard/hangul entry (hangulComposer + hangulLayout — Korean 두벌식 IME), and an opt-in @usefy/virtual-keyboard/styles.css.
| Export | Description |
|---|---|
NetworkIndicator |
Drop-in online/offline banner — offline warning + auto-dismissing "back online" confirmation, render escape hatch, onStatusChange callback |
DEFAULT_OFFLINE_MESSAGE, DEFAULT_ONLINE_MESSAGE, DEFAULT_ONLINE_DURATION
|
The component's defaults, reusable in custom render UIs |
| Export | Description |
|---|---|
ScrollProgress |
Drop-in reading-progress bar — fixed top/bottom bar filled by scrollTop / (scrollHeight - clientHeight), window or container target, render escape hatch |
DEFAULT_BAR_COLOR, DEFAULT_BAR_HEIGHT, DEFAULT_Z_INDEX, DEFAULT_ARIA_LABEL
|
The component's defaults, reusable in custom render UIs |
| Export | Description |
|---|---|
SpotlightTour |
Guided onboarding tour — animated SVG-mask spotlight, step tooltip, gates, auto-scroll, tourId persistence, keyboard + dialog a11y, theming, renderStep
|
SpotlightBeacon |
Pulsing invitation dot pinned to an element that starts the tour on click |
useSpotlightTour, resetTour
|
The full headless state machine + persistence reset (also via @usefy/spotlight-tour/headless) |
computeTooltipPosition, getSpotlightRect, resolveTarget
|
The pure positioning engine, for bespoke UIs |
Also ships a @usefy/spotlight-tour/headless entry (hook + engine + types, no CSS) and an opt-in @usefy/spotlight-tour/styles.css.
| Export | Description |
|---|---|
fireConfetti, resetConfetti
|
One-liner burst on an auto-managed full-viewport canvas (SSR no-op, idle auto-teardown) |
Confetti |
Overlay/inline canvas component with an imperative controllerRef (fire/emit/stop/clear), onComplete, fireOnMount
|
useConfetti |
Component-scoped canvas hook — { canvasRef, fire, emit, stop, clear, isActive } with edge-only re-renders |
runPreset + celebration, fireworks, sideCannons, pride, stars, snow, rain
|
Tree-shakeable preset data + a cancelable runner that works on any layer |
textShape, imageShape, pathShape
|
Emoji/text sprites, image sprites, and palette-colored Path2D confetti |
createConfettiEngine, spawnParticle, stepParticle, resolveFireOptions
|
The framework-free engine + pure physics (also via @usefy/confetti/headless) |
Also ships a zero-React @usefy/confetti/headless entry (engine + shapes + presets + types, zero dependencies).
| Export | Description |
|---|---|
SignaturePad |
Container-filling signature canvas — guideline, defaultValue, reactive readOnly, imperative controllerRef (clear/undo/redo/toPNG/toSVG/toJSON/fromJSON), edge-only onChange
|
useSignaturePad |
The engine on a canvas you own — { canvasRef, isEmpty, strokeCount, canUndo, canRedo, clear, undo, redo, toPNG, toSVG, toJSON, fromJSON }, zero renders while ink flows |
createSignatureEngine |
Framework-free engine: pointer pipeline, incremental rendering, history, exports, ingest() replay seam |
filterPoints, bezierFor, widthForSegment, flattenSegment, strokeGeometry, inkBounds, strokesToSVG
|
The pure, deterministic ink pipeline (hand-testable math) |
Also ships a zero-React @usefy/signature-pad/headless entry (engine + ink math + types, zero dependencies).
| Export | Description |
|---|---|
DiffViewer |
Split/unified diff table — collapsible context, row virtualization, renderContent highlighter seam, theme, classNames, labels, "No changes" / "too large / too different + diff anyway" states |
computeDiff |
The composed engine — two strings → { hunks, stats, truncated, truncatedReason?, inlineBudgetExhausted? }, with size/cost guards |
toSplitRows, toUnifiedRows, alignRows
|
Pure view models — both views render the same DiffLine objects |
myersDiff, myersDiffBounded, splitLines, tokenizeWords, normalizeLine, similarity, inlineSegments, buildHunks, resolveOptions
|
The pure, hand-testable diff core (CJK-aware, linear-space Myers) |
Also ships a zero-React @usefy/diff-viewer/headless entry (engine + tokenizer + hunks + types, zero dependencies) and a @usefy/diff-viewer/styles.css export (styles otherwise inject at runtime).
| Export | Description |
|---|---|
QRCode |
The component — render="svg" | "canvas", every styling option as a prop, imperative controllerRef (toSVG/toPNG/download/getMatrix), onError/throwOnError, DOM passthrough |
useQRCode |
{ matrix, error, svgProps, canvasRef, toSVG, toPNG, download } — the encoded symbol plus structured SVG data for markup you render yourself |
encodeQR |
The ISO/IEC 18004 encoder — versions 1–40, L/M/Q/H, mixed-mode segmentation, ECI, forced version/mask |
toSVG, toSVGProps, drawToCanvas, toPNG
|
Four outputs from one matrix; toSVGProps is the zero-client-JS server-rendering path |
logoSafety, contrastRatio, MAX_SAFE_MODULE_GAP
|
Scannability analysis — logo occlusion vs the level's recovery budget, WCAG contrast, and the measured per-shape gap ceilings |
matrixToPaths, segment, penaltyScore, maskAt, dataCapacityBits
|
The pure encoder and geometry internals (hand-testable math) |
Also ships a zero-React, no-"use client" @usefy/qr-code/headless entry (encoder + renderers + types, zero dependencies) that a React Server Component can import directly.
| Export | Description |
|---|---|
QRScanner |
The component — camera preview, viewfinder overlay, torch and camera-switch controls, file/drop/paste fallback, source="camera" | "file", imperative controllerRef
|
useQRScanner |
{ videoRef, state, result, results, error, start, stop, pause, resume, devices, switchCamera, setTorch, scanFile, capture } — the camera and the loop with no UI attached |
decode, decodeFile, decodeFirst
|
Any image source → results, choosing between the native and internal engines |
decodeImageData |
Synchronous, DOM-free decode — what the worker and the tests use |
isNativeSupported, decodeWithNative
|
The platform BarcodeDetector path, probed once and cached |
createWorkerDecoder |
Wrap a Worker running the ./worker entry — no blob URLs, CSP-safe |
mapCorners, mapPointToElement, cornersToPolygon
|
Source-pixel geometry → element pixels, through object-fit and front-camera mirroring |
joinStructuredAppend |
Assemble a multi-symbol payload, reporting what is still missing |
toGray, binarize, findFinderPatterns, sampleGrid, rsDecode, parseSegments
|
The pure decode stages, individually (hand-testable math) |
Also ships a zero-React, no-"use client" @usefy/qr-scanner/headless entry and a @usefy/qr-scanner/worker entry, both importable from a server component or a Web Worker.
| Browser | Version |
|---|---|
| Chrome | 66+ |
| Firefox | 63+ |
| Safari | 13.1+ |
| Edge | 79+ |
We welcome contributions! Please see our Contributing Guide for details.
# Clone the repo
git clone https://github.com/mirunamu00/usefy.git
# Install dependencies
pnpm install
# Run tests
pnpm test
# Start Storybook
pnpm storybookMIT © mirunamu
Built with care by the usefy team
