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';
const app = initializeApp({ /* your config */ });
const storage = getStorage(app);
const manager = new FirebaseUploadManager({
maxConcurrentUploads: 3,
autoStart: true
});
manager.setStorage(storage);
let showPanel = $state(true);
</script>
<UploadDropZone uploadManager={manager} accept="image/*,.pdf" />
<UploadPanel uploadManager={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.
<UploadPanel
uploadManager={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.
<UploadDropZone
uploadManager={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 |
const manager = new FirebaseUploadManager({
maxConcurrentUploads: 5, // default: 5
chunkSize: 5 * 1024 * 1024, // default: 5MB
retryAttempts: 3, // default: 3
retryDelay: 1000, // default: 1000ms
autoStart: true, // default: false
enableSmartScheduling: true // default: false
});
manager.setStorage(storage);
// Add files
await manager.addFiles(fileList, { path: 'photos/' });
// Control
await manager.start();
await manager.pause();
await manager.resume();
await manager.stop();
// Validation
const results = await manager.validateFiles(files, {
maxSize: 10 * 1024 * 1024,
allowedTypes: ['image/*', '.pdf']
});
// State (all reactive with $state)
manager.totalProgress // 0-100
manager.currentSpeed // bytes/sec
manager.successCount
manager.failureCount
manager.isProcessing
manager.queue
manager.failed
manager.completedimport { LoggingPlugin, AnalyticsPlugin } from 'svelte-firebase-upload';
await manager.registerPlugin(new LoggingPlugin({ logLevel: 'info' }));
await manager.registerPlugin(new AnalyticsPlugin());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: 0 25px 50px -12px rgba(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