loading
Warning:
Chromium onlynavigator.storageBuckets ships in Chromium-based browsers and is not implemented in Firefox or Safari. Every member here degrades to a false/null/empty answer where the API is absent, so nothing throws - it simply does nothing. Feature-detect with IsSupported and keep StorageManager as the fallback.

Check for support

IsSupported

True when the runtime exposes navigator.storageBuckets.

Razor
@inject Bit.Butil.StorageBuckets storageBuckets

if (await storageBuckets.IsSupported())
{
    // safe to open buckets
}
Live sample
support output
Results will appear here when you interact with the samples.

Open a bucket

Open / Get / Keys

Open creates the bucket when it is not there and returns it as it is when it is - so it is safe to call on every start-up. The options only apply at creation. Names are lower-case letters, digits, dash and underscore, not starting with a dash or underscore.

C#
StorageBucketInfo? bucket = await storageBuckets.Open("drafts",
    persisted: true,
    durability: StorageBucketDurability.Strict,
    quota: 50 * 1024 * 1024,
    expires: DateTimeOffset.UtcNow.AddDays(30));

// asking for persistence does not grant it - read the answer back
var isPersisted = bucket?.Persisted;

string[] names = await storageBuckets.Keys();
Live sample
bucket output
Results will appear here when you interact with the samples.

Persistence and quota

Persist / Persisted / Estimate

Persistence is per bucket here rather than per origin: mark the one bucket holding data you cannot re-fetch, and leave the caches evictable. Estimate reports that bucket's own usage and quota.

C#
var granted = await storageBuckets.Persist("drafts");
var isPersisted = await storageBuckets.Persisted("drafts");

StorageEstimate estimate = await storageBuckets.Estimate("drafts");
// estimate.Usage / estimate.Quota, in bytes
Live sample
persistence output
Results will appear here when you interact with the samples.

Expiry

SetExpires / GetExpires

An expiry is permission to delete, not a scheduled deletion: the browser may drop the bucket any time after it, and usually keeps it for a while longer. Useful for a bucket holding a season's worth of downloaded content.

C#
await storageBuckets.SetExpires("drafts", DateTimeOffset.UtcNow.AddDays(7));

DateTimeOffset? expires = await storageBuckets.GetExpires("drafts");
Live sample
expiry output
Results will appear here when you interact with the samples.

Files inside a bucket

WriteText / WriteBytes / ReadText / ReadBytes / List / Remove

Each bucket owns a whole file system of its own - the same origin private file system, rooted in the bucket rather than in the origin. That is what makes a bucket a real compartment rather than a label: deleting it takes its files with it.

C#
await storageBuckets.WriteText("drafts", "letters/draft.txt", "unsent");

string? text = await storageBuckets.ReadText("drafts", "letters/draft.txt");

// Anything that isn't text goes through the byte pair - ReadText would UTF-8 decode it away.
await storageBuckets.WriteBytes("drafts", "letters/seal.bin", [0x00, 0xC3, 0x28, 0xFF]);
byte[]? bytes = await storageBuckets.ReadBytes("drafts", "letters/seal.bin");

OpfsEntry[] entries = await storageBuckets.List("drafts", "letters");

await storageBuckets.Remove("drafts", "letters", recursive: true);
Live sample
bucket file output
Results will appear here when you interact with the samples.

Delete a bucket

Delete

Deletes the bucket and everything in it - its files, its IndexedDB databases and its caches. This is the operation the whole API exists for: one call that throws away a category of data without touching the rest.

C#
await storageBuckets.Delete("drafts");
Live sample
delete output
Results will appear here when you interact with the samples.
Note:
Only Open and the writes create The browser's own open() is create-or-get, so reaching for a bucket by name is what brings it into existence. Butil keeps that to the members where it is the point: Open, WriteText and WriteBytes. Everything else - Get, Persisted, Estimate, GetExpires, List, ReadText, ReadBytes, Persist, SetExpires, Remove - answers null/false/empty for a name that is not in Keys, and creates nothing.

API reference

Member
Signature
Description
IsSupported
ValueTask<bool> IsSupported()
True when the runtime exposes navigator.storageBuckets.
Open
ValueTask<StorageBucketInfo?> Open(string name, bool persisted = false, StorageBucketDurability durability = Default, long? quota = null, DateTimeOffset? expires = null)
Opens the named bucket, creating it when it is not there. The options apply only at creation.
Get
ValueTask<StorageBucketInfo?> Get(string name)
Reads a bucket's current state, or null when there is no such bucket. Creates nothing.
Keys
ValueTask<string[]> Keys()
Lists the names of every bucket this origin has, alphabetically.
Delete
ValueTask<bool> Delete(string name)
Deletes a bucket and everything in it - files, databases and caches.
Persist
ValueTask<bool> Persist(string name)
Asks the browser to exempt this bucket from eviction. The user agent decides.
Persisted
ValueTask<bool> Persisted(string name)
True when this bucket is exempt from eviction.
Estimate
ValueTask<StorageEstimate> Estimate(string name)
This bucket's own quota and usage in bytes. UsageDetails is always empty here.
SetExpires
ValueTask<bool> SetExpires(string name, DateTimeOffset expires)
Sets the point after which the browser may delete the bucket.
GetExpires
ValueTask<DateTimeOffset?> GetExpires(string name)
Reads the bucket's expiry, or null when it has none.
List
ValueTask<OpfsEntry[]> List(string name, string path = &quot;&quot;)
Lists a directory inside the bucket's own file system. Not recursive.
ReadText
ValueTask<string?> ReadText(string name, string path)
Reads a file inside the bucket as text; null when there is no file there.
ReadBytes
ValueTask<byte[]?> ReadBytes(string name, string path)
Reads a file inside the bucket as bytes; null when there is no file there. The counterpart to WriteBytes - ReadText would UTF-8 decode binary content away.
WriteText
ValueTask<bool> WriteText(string name, string path, string text)
Writes text to a file inside the bucket, creating what is missing along the path.
WriteBytes
ValueTask<bool> WriteBytes(string name, string path, byte[] data)
Writes bytes to a file inside the bucket, creating what is missing along the path.
Remove
ValueTask<bool> Remove(string name, string path, bool recursive = false)
Deletes a file or directory inside the bucket.
StorageBucketInfo
class StorageBucketInfo { string Name; bool Persisted; string? Durability; long? Expires; long? Quota; long? Usage; }
A bucket's state, gathered from its several individual promises into one payload.
StorageBucketDurability
enum StorageBucketDurability { Default, Relaxed, Strict }
How hard the browser tries not to lose the latest writes. Fixed when the bucket is created.
An unhandled error has occurred. Reload 🗙