File upload manager for Svelte 5 + Firebase Storage. Concurrent uploads, resumable transfers, file validation, and a Dropbox-style upload panel — zero extra dependencies.
npm install svelte-firebase-upload firebase<script>import { initializeApp } from'firebase/app';import { getStorage } from'firebase/storage';import { FirebaseUploadManager, UploadPanel, UploadDropZone } from'svelte-firebase-upload';constapp=initializeApp({ /* your config */ });conststorage=getStorage(app);constmanager=newFirebaseUploadManager({ maxConcurrentUploads:3, autoStart:true });manager.setStorage(storage);let showPanel =$state(true);</script>
<UploadDropZoneuploadManager={manager} accept="image/*,.pdf" />
<UploadPaneluploadManager={manager} bind:visible={showPanel} />- Concurrent uploads with configurable concurrency limits
- Resumable transfers with chunk-based recovery
- File validation — size limits, type checks, duplicate detection, security scanning
- Dropbox-style UI — floating panel with progress, tabs, per-file actions
- Drag & drop zone — standalone component with file filtering
- Error handling — stall detection, toast notifications, retry with backoff
- Network awareness — monitors connection quality, adapts to conditions
- Bandwidth throttling — adaptive rate limiting
- Plugin system — extensible hooks for every upload lifecycle event
- SSR safe — all browser APIs guarded for SvelteKit
- Themeable — CSS custom properties for full visual control
- TypeScript — fully typed API
Floating panel that shows upload progress, errors, and per-file actions.
<UploadPaneluploadManager={manager}
bind:visible={showPanel}
position="bottom-right"onerror={(item, error) =>console.log('Failed:', item.file.name)}
/>| Prop | Type | Default | Description |
|---|---|---|---|
uploadManager | FirebaseUploadManager | required | Manager instance |
visible | boolean | true | Bindable show/hide |
position | 'bottom-right' | 'bottom-left' | 'bottom-right' | Panel position |
onerror | (item, error) => void | — | Error callback |
Drag & drop area with click-to-browse. Supports custom content via slot.
<UploadDropZoneuploadManager={manager}
accept="image/*,.pdf"path="user-uploads/"maxSize={10*1024*1024}
/>| Prop | Type | Default | Description |
|---|---|---|---|
uploadManager | FirebaseUploadManager | required | Manager instance |
accept | string | '' | File type filter |
multiple | boolean | true | Allow multiple files |
maxSize | number | — | Max file size (bytes) |
path | string | 'uploads/' | Storage directory |
disabled | boolean | false | Disable interaction |
constmanager=newFirebaseUploadManager({maxConcurrentUploads: 5,// default: 5chunkSize: 5*1024*1024,// default: 5MBretryAttempts: 3,// default: 3retryDelay: 1000,// default: 1000msautoStart: true,// default: falseenableSmartScheduling: true// default: false});manager.setStorage(storage);// Add filesawaitmanager.addFiles(fileList,{path: 'photos/'});// Controlawaitmanager.start();awaitmanager.pause();awaitmanager.resume();awaitmanager.stop();// Validationconstresults=awaitmanager.validateFiles(files,{maxSize: 10*1024*1024,allowedTypes: ['image/*','.pdf']});// State (all reactive with $state)manager.totalProgress// 0-100manager.currentSpeed// bytes/secmanager.successCountmanager.failureCountmanager.isProcessingmanager.queuemanager.failedmanager.completedimport{LoggingPlugin,AnalyticsPlugin}from'svelte-firebase-upload';awaitmanager.registerPlugin(newLoggingPlugin({logLevel: 'info'}));awaitmanager.registerPlugin(newAnalyticsPlugin());Built-in presets: LoggingPlugin, AnalyticsPlugin, FileProcessingPlugin, ValidationEnhancementPlugin, QueueOptimizationPlugin.
Override CSS custom properties to match your design:
:root {
--sfu-panel-bg:#ffffff;
--sfu-panel-border:#e5e7eb;
--sfu-panel-shadow:025px50px-12pxrgba(0,0,0,0.25);
--sfu-text-primary:#111827;
--sfu-text-secondary:#6b7280;
--sfu-progress-bg:#e5e7eb;
--sfu-progress-fill:#3b82f6;
--sfu-success:#22c55e;
--sfu-error:#ef4444;
--sfu-warning:#f59e0b;
--sfu-radius:12px;
--sfu-font-family: system-ui, -apple-system, sans-serif;
}Your storage bucket needs CORS configured for local development:
[{
"origin": ["http://localhost:5173"],
"method": ["GET", "POST", "PUT", "DELETE", "HEAD"],
"maxAgeSeconds": 3600,
"responseHeader": ["Content-Type", "Authorization", "Content-Length", "User-Agent", "x-goog-resumable"]
}]Apply with: gcloud storage buckets update gs://YOUR_BUCKET --cors-file=cors.json
MIT