A powerful, flexible, and completely headless file upload library for applications. Built with TypeScript, zero dependencies, and designed to work with any UI framework or design system.
- π― Completely Headless - No UI components, just pure logic and state management
- π Multi-File Upload - Effortlessly handle single or multiple files simultaneously
- π¨ Framework Agnostic - Provides stable, isolated wrappers for React, Vue, Svelte, Angular, Solid, Qwik, Lit, and jQuery
- π Real-time Progress - Precise tracking with speed (bps) and time remaining estimates
- π§© Chunked Upload - Intelligent large file splitting with concurrent chunk processing
- βΈοΈ Pause & Resume - Full control over the upload lifecycle at any moment
- π Auto Retry - Robust error handling with customizable exponential backoff
- πΌοΈ Preview Generation - Built-in high-performance preview generation for images and videos
- π Metadata Extraction - Automatically extract dimensions, duration, and extended file metadata
- βοΈ Cloud Ready - Flexible adapter pattern for AWS S3, Google Cloud, Azure, and more: TBD
- ποΈ Smart Compression - Optional client-side image compression before transfer
- β Advanced Validation - Deep validation for MIME types, extensions, size, and custom logic
- π TypeScript First - 100% type safety and excellent IntelliSense support
- π³ Tree Shakeable - Import only what you need, keeping bundles tiny
- π¦ Zero Dependencies - Highly secure, fast, and completely self-contained core engine
Install the relevant library for use in available framework.
| Framework | Package Name | Installation Command |
|---|---|---|
| @verbpatch/headless-uploader | npm install @verbpatch/headless-uploader |
|
| @verbpatch/react-uploader | npm install @verbpatch/react-uploader |
|
| @verbpatch/svelte-uploader | npm install @verbpatch/svelte-uploader |
|
| @verbpatch/vue-uploader | npm install @verbpatch/vue-uploader |
|
| @verbpatch/jquery-uploader | npm install @verbpatch/jquery-uploader |
|
| @verbpatch/angular-uploader | npm install @verbpatch/angular-uploader |
|
| @verbpatch/lit-uploader | npm install @verbpatch/lit-uploader |
|
| @verbpatch/preact-uploader | npm install @verbpatch/preact-uploader |
|
| @verbpatch/qwik-uploader | npm install @verbpatch/qwik-uploader |
|
| @verbpatch/solid-uploader | npm install @verbpatch/solid-uploader |
import { useUploader } from "@verbpatch/headless-uploader";
const uploader = useUploader({
http: {
endpoint: "/api/upload",
},
autoUpload: true,
onUploadProgress: (file, progress) => {
console.log(`${file.metadata.name}: ${progress.percentage}%`);
},
});
// Bind to a file input
const input = document.getElementById('my-input');
input.addEventListener('change', (e) => uploader.handleFileSelect(e));
// Or handle drag & drop
const dropzone = document.getElementById('dropzone');
dropzone.addEventListener('dragover', (e) => uploader.handleDragOver(e));
dropzone.addEventListener('drop', (e) => uploader.handleDrop(e));import { useUploader } from "@verbpatch/react-uploader";
function MyUploader() {
const uploader = useUploader({
http: { endpoint: "/api/upload" },
maxFiles: 5,
onUploadSuccess: (file, response) => {
console.log('Upload finished!', response);
}
});
const state = uploader.getState();
return (
<div>
<div
onDrop={uploader.handleDrop}
onDragOver={uploader.handleDragOver}
style={{ border: '2px dashed #ccc', padding: '20px' }}
>
Drop files here or <input type="file" onChange={uploader.handleFileSelect} multiple />
</div>
<ul>
{state.files.map(file => (
<li key={file.id}>
{file.metadata.name} - {file.status}
({file.progress.percentage.toFixed(1)}%)
<button onClick={() => uploader.cancelUpload(file.id)}>Cancel</button>
</li>
))}
</ul>
</div>
);
}