v2.0.0 · MIT license · TypeScript

uploaderkit

File uploads for React and Node, from one shared contract.

Scopes both sides validate against, a headless uploader with progress / abort / compression, and a server storage service with pluggable providers.

Installation

npm install uploaderkit

Features

Everything the package ships, from its own README.

  • One contract, both sides

    a scope registry declares where a file lands, who may read it, what is accepted and how big it may be. The browser and the server validate against the same object, so a rejection is never a surprise at the end of a 40 MB upload.

  • Headless first

    useUploader owns selection, validation, compression, per-file progress, abort and error state; it renders nothing. /ui is an opt-in skin over it, so an app with its own design system loses no behavior by skipping it.

  • Client-side validation before the first byte

    extension, size and magic numbers, so an .exe renamed to .pdf never leaves the machine.

  • Real upload progress

    the default strategy is XHR because fetch still has no usable upload progress in browsers. Every in-flight upload is abortable, per file or all at once.

  • Image compression in the scope

    declare compress and images are downscaled and re-encoded before travelling. EXIF (GPS, camera) drops in the process.

  • Pluggable transport

    the UploadStrategy is a single function (file, scope, entityId, { onProgress, signal }). Swap the endpoint, the auth header or the whole protocol without touching hook state.

  • Server storage service

    createStorage re-runs the same validation, encrypts the scopes that ask for it, and answers signed expiring URLs for private objects.

  • Boot-time guards

    a private scope on a provider that cannot sign, or an encrypted scope without an injected cipher, throws at construction. Deploys fail loudly instead of 500ing on the first upload.

  • Framework adapters

    structural handlers for Express (the app owns multer) and for the Next.js App Router (native Request/Response). No framework dependency is pulled in.

  • Provider adapters

    Google Cloud Storage (two-bucket layout), any S3-compatible backend (AWS, Cloudflare R2, Backblaze B2, MinIO, Wasabi) and an in-memory provider for tests. All optional peers: choosing GCS never installs the AWS SDK.

  • Named slots

    SlottedUploader fills one file per named position (letterhead, ID, tax certificate); a bulk drop routes each file to its slot and renames it so re-uploads overwrite in place.

  • No cipher shipped by default

    private scopes declare encrypt: true and the app injects CryptoHooks. createAesGcmCrypto is available as a reference implementation.

  • You choose when the upload fires

    uploadOn: 'select' sends as soon as a valid file lands; 'manual' holds files until upload() — the form-submit flow, reachable from the styled components through controllerRef. onUploadStart announces the moment a batch leaves.

  • Retry with backoff + concurrency cap

    opt-in resilience for flaky networks: transient strategy failures retry behind exponential backoff, and large batches queue behind a concurrency limit.

  • Confirmation dialogs built in

    confirmRemove / confirmReplace gate destructive file actions behind an accessible dialog (focus lands on cancel), and ConfirmDialog is exported for app-level use.

  • Paste and camera capture

    a focused dropzone accepts a pasted screenshot, and capture opens the mobile camera directly.

  • Translatable copy

    every user-facing string flows through a labels object, on the client AND on the server. English by default, ES_LABELS included, any language via a partial override.

  • Rebrandable theme

    the styled layer reads --color-ui-* CSS variables so one :root override rebrands the whole styled layer.

  • Sizes, icons and motion

    size='sm' | 'md' compacts every row and zone, icon swaps (or removes) the dropzone glyph, and the whole surface animates: rows fade in, the drag state scales the zone, overlays enter and exit with a transition, the uploading indicator pulses.

  • Touch-first by default

    on coarse pointers the zone reads as a tap target ("Toca para elegir un archivo") with press feedback instead of advertising a drag nobody can do; capture opens the camera directly.

Entry points

Import only what you use; each subpath is tree-shaken independently.

  • uploaderkit
  • uploaderkit/react
  • uploaderkit/ui
  • uploaderkit/presets
  • uploaderkit/server
  • uploaderkit/server/express
  • uploaderkit/server/next
  • uploaderkit/adapters/s3
  • uploaderkit/adapters/gcs
  • uploaderkit/adapters/memory

On this page