Skip to main content
IndexedDB provides a powerful NoSQL database API built into every modern browser. BlazorEssentials.IndexedDb makes it easy to use from your Blazor WebAssembly applications with a strongly-typed C# API.

No Setup Required

Uses the browser’s built-in IndexedDB - no server or external dependencies.

Offline Ready

Data persists locally, enabling full offline functionality.

Type-Safe

Object stores are strongly typed with compile-time safety.

Indexed Queries

Create indexes for fast lookups on any property.

Installation

dotnet add package BlazorEssentials.IndexedDb

Quick Start

Define Your Entities

Use attributes to configure how entities are stored:
Models/TodoItem.cs
using CloudNimble.BlazorEssentials.IndexedDb;

[ObjectStore("todos")]
public class TodoItem
{
    public int Id { get; set; }

    public string Title { get; set; } = "";

    public bool IsCompleted { get; set; }

    [Index]
    public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
}

Create Your Database

Inherit from IndexedDbDatabase and add IndexedDbObjectStore<T> properties:
Data/AppDatabase.cs
using CloudNimble.BlazorEssentials.IndexedDb;
using Microsoft.JSInterop;

public class AppDatabase : IndexedDbDatabase
{
    public IndexedDbObjectStore<TodoItem> Todos { get; set; }

    public AppDatabase(IJSRuntime jsRuntime) : base(jsRuntime)
    {
        Name = "MyAppDb";
        Version = 1;
    }
}

Register and Use

builder.Services.AddScoped<AppDatabase>();

CRUD Operations

Create

var todo = new TodoItem
{
    Id = 1,
    Title = "Learn Blazor",
    IsCompleted = false
};

await Database.Todos.AddAsync(todo);

Read

var allTodos = await Database.Todos.GetAllAsync();

Update

var todo = await Database.Todos.GetAsync(1);
todo.IsCompleted = true;

await Database.Todos.PutAsync(todo);

Delete

await Database.Todos.DeleteAsync(1);

Indexes

Create indexes for fast lookups on frequently queried properties:
[ObjectStore("users")]
public class User
{
    public int Id { get; set; }

    [Index]
    public string Email { get; set; } = "";

    [Index(Unique = false)]
    public string Department { get; set; } = "";
}
Query using indexes:
// Find user by email
var user = await Database.Users
    .GetByIndexAsync("Email", "[email protected]")
    .FirstOrDefaultAsync();

// Find all users in a department
var engineers = await Database.Users
    .GetByIndexAsync("Department", "Engineering");

Key Ranges

Use KeyRange for range queries on indexed properties:
// Items created today
var todayItems = await Database.Todos
    .GetByIndexAsync("CreatedAt", KeyRange.LowerBound(DateTime.Today));

// Items in a date range
var rangeItems = await Database.Todos
    .GetByIndexAsync("CreatedAt", KeyRange.Bound(startDate, endDate));

Best Practices

Choose key paths that uniquely identify your entities. Auto-incrementing integers or GUIDs work well for most cases.
Only create indexes on properties you’ll query frequently. Each index adds storage overhead and slows down writes.
When changing your schema, increment the Version property. IndexedDB will trigger an upgrade event to migrate existing data.

API Reference