Upload files to Firebase Storage with automatic retries, batch uploads, and pre-upload validation.
Full documentation: firebase-storage-kit.vercel.app/docs
npm install firebase firebase-storage-kitAlso works with Yarn, pnpm, or Bun. See Installation for all package managers.
import { getStorage } from "firebase/storage";
import { StorageManager } from "firebase-storage-kit";
const storage = getStorage(app);
const manager = new StorageManager(storage);
const handle = manager.uploadFile(file, {
path: `uploads/${file.name}`,
validate: {
maxSizeBytes: 10 * 1024 * 1024,
allowedMimeTypes: ["image/jpeg", "image/png", "image/webp"],
allowedExtensions: [".jpg", ".jpeg", ".png", ".webp"],
},
retry: { maxRetries: 3 },
});
handle.on("progress", (upload) => {
console.log(upload.progress);
});
handle.on("retry", ({ attempt, maxAttempts, delayMs }) => {
console.log(`Retry ${attempt}/${maxAttempts} in ${delayMs}ms`);
});
handle.on("success", (upload) => {
console.log(upload.downloadURL);
});
handle.on("error", (upload) => {
if (upload.error?.name === "ValidationError") {
console.error("Invalid file:", upload.error.message);
return;
}
console.error("Upload failed:", upload.error?.message);
});const { stream } = await manager.downloadStream("videos/launch-demo.mp4", {
onProgress: (loaded, total) => {
console.log(`${Math.round((loaded / total) * 100)}%`);
},
});
await stream.pipeTo(writable);The object is delivered as a ReadableStream, so it can be piped without buffering the full file in memory.
import type { FirebaseStorage } from "firebase/storage";
import { useState } from "react";
import type { UploadHandle } from "firebase-storage-kit";
import { useStorageManager, useUpload } from "firebase-storage-kit/react";
function ImageUpload({ storage }: { storage: FirebaseStorage }) {
const manager = useStorageManager(storage);
const [handle, setHandle] = useState<UploadHandle | null>(null);
const upload = useUpload(handle);
function onPick(event: React.ChangeEvent<HTMLInputElement>) {
const file = event.target.files?.[0];
if (!file) return;
setHandle(
manager.uploadFile(file, {
path: `uploads/${file.name}`,
validate: {
maxSizeBytes: 10 * 1024 * 1024,
allowedMimeTypes: ["image/jpeg", "image/png", "image/webp"],
allowedExtensions: [".jpg", ".jpeg", ".png", ".webp"],
},
retry: { maxRetries: 3 },
})
);
}
return (
<>
<input type="file" accept="image/*" onChange={onPick} />
{upload && <p>{upload.progress.toFixed(0)}% uploaded</p>}
</>
);
}See React hooks.
MIT