CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-lowdb

Tiny local JSON database for Node, Electron and the browser

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

browser.mddocs/

Browser Storage

Browser storage adapters and presets for localStorage and sessionStorage integration. These adapters provide seamless integration with browser storage APIs while maintaining the same lowdb interface for consistent data management across environments.

Capabilities

Browser Storage Presets

Pre-configured database instances with browser storage adapters for immediate use.

/**
 * Create a LowSync instance with LocalStorage adapter for persistent browser storage
 * @param key - Storage key for localStorage
 * @param defaultData - Default data structure
 * @returns Configured LowSync instance with data pre-loaded from localStorage
 */
function LocalStoragePreset<Data>(key: string, defaultData: Data): LowSync<Data>;

/**
 * Create a LowSync instance with SessionStorage adapter for session-only browser storage
 * @param key - Storage key for sessionStorage
 * @param defaultData - Default data structure
 * @returns Configured LowSync instance with data pre-loaded from sessionStorage
 */
function SessionStoragePreset<Data>(key: string, defaultData: Data): LowSync<Data>;

Usage Examples:

import { LocalStoragePreset, SessionStoragePreset } from "lowdb/browser";

// Persistent storage across browser sessions
type AppData = {
  user: { id: number; name: string; preferences: object };
  settings: { theme: string; language: string };
};

const defaultData: AppData = {
  user: { id: 0, name: "", preferences: {} },
  settings: { theme: "light", language: "en" }
};

const db = LocalStoragePreset("myapp-data", defaultData);

// Update user preferences
db.update((data) => {
  data.user.name = "Alice";
  data.settings.theme = "dark";
});

// Session-only storage (cleared when tab closes)
const sessionDb = SessionStoragePreset("session-data", { cart: [] });
sessionDb.update(({ cart }) => cart.push({ id: 1, name: "Product" }));

LocalStorage Adapter

Synchronous adapter for browser localStorage with automatic JSON serialization.

/**
 * Sync adapter for browser localStorage with automatic JSON parsing/stringifying
 * @template T - The type of data stored in localStorage
 */
class LocalStorage<T> implements SyncAdapter<T> {
  constructor(key: string);
  
  /** Read and parse data from localStorage, returns null if key doesn't exist */
  read(): T | null;
  
  /** Stringify and store data in localStorage */
  write(obj: T): void;
}

Usage Examples:

import { LowSync } from "lowdb";
import { LocalStorage } from "lowdb/browser";

// Direct adapter usage
const adapter = new LocalStorage<{ count: number }>("app-counter");
const db = new LowSync(adapter, { count: 0 });

// Initialize from localStorage
db.read();

// Update and persist
db.data.count++;
db.write(); // Immediately saved to localStorage

// Data persists across browser sessions
console.log(localStorage.getItem("app-counter")); // {"count":1}

SessionStorage Adapter

Synchronous adapter for browser sessionStorage with automatic JSON serialization.

/**
 * Sync adapter for browser sessionStorage with automatic JSON parsing/stringifying
 * @template T - The type of data stored in sessionStorage
 */
class SessionStorage<T> implements SyncAdapter<T> {
  constructor(key: string);
  
  /** Read and parse data from sessionStorage, returns null if key doesn't exist */
  read(): T | null;
  
  /** Stringify and store data in sessionStorage */
  write(obj: T): void;
}

Usage Examples:

import { LowSync } from "lowdb";
import { SessionStorage } from "lowdb/browser";

// Session-only storage
const adapter = new SessionStorage<string[]>("temp-notes");
const notesDb = new LowSync(adapter, []);

notesDb.read();
notesDb.data.push("Temporary note");
notesDb.write(); // Saved to sessionStorage

// Data is cleared when tab closes
console.log(sessionStorage.getItem("temp-notes")); // ["Temporary note"]

WebStorage Base Class

Base class for browser storage adapters (not directly exported, but used internally).

/**
 * Base sync adapter for browser storage APIs (localStorage/sessionStorage)
 * @template T - The type of data stored
 */
class WebStorage<T> implements SyncAdapter<T> {
  constructor(key: string, storage: Storage);
  
  /** Read and parse JSON from storage, returns null if key doesn't exist */
  read(): T | null;
  
  /** Stringify and store JSON in storage */
  write(obj: T): void;
}

Browser-Specific Behavior

Storage Persistence

LocalStorage:

  • Data persists across browser sessions
  • Survives page reloads and browser restarts
  • Shared across all tabs/windows of the same origin
  • Typically limited to 5-10MB per origin

SessionStorage:

  • Data persists only for the current browser tab/window session
  • Cleared when tab is closed
  • Isolated per tab (not shared between tabs)
  • Same storage limits as localStorage

Storage Quotas

Browser storage has size limitations:

import { LocalStoragePreset } from "lowdb/browser";

try {
  const db = LocalStoragePreset("large-dataset", { data: [] });
  
  // Add large amounts of data
  db.update(({ data }) => {
    for (let i = 0; i < 100000; i++) {
      data.push({ id: i, content: "Large content string..." });
    }
  });
} catch (error) {
  if (error.name === "QuotaExceededError") {
    console.error("Storage quota exceeded");
    // Handle storage limit reached
  }
}

Cross-Origin Restrictions

Storage is isolated by origin (protocol + domain + port):

// Each origin has separate storage
// https://app.example.com - separate storage
// https://api.example.com - separate storage  
// http://app.example.com - separate storage

const db = LocalStoragePreset("shared-data", {});
// This data is only accessible from the current origin

Data Synchronization

Multiple Tabs

LocalStorage data is shared between tabs and can be synchronized:

import { LocalStoragePreset } from "lowdb/browser";

const db = LocalStoragePreset("shared-state", { count: 0 });

// Listen for storage changes from other tabs
window.addEventListener("storage", (event) => {
  if (event.key === "shared-state" && event.newValue) {
    // Reload data when changed by another tab
    db.read();
    console.log("Data updated by another tab:", db.data);
  }
});

// Update data (will trigger storage event in other tabs)
db.update((data) => {
  data.count++;
});

React Integration

Example integration with React for reactive updates:

import { useEffect, useState } from "react";
import { LocalStoragePreset } from "lowdb/browser";

function useLocalStorageDb<T>(key: string, defaultData: T) {
  const [db] = useState(() => LocalStoragePreset(key, defaultData));
  const [data, setData] = useState(db.data);
  
  useEffect(() => {
    const handleStorageChange = (event: StorageEvent) => {
      if (event.key === key) {
        db.read();
        setData({ ...db.data });
      }
    };
    
    window.addEventListener("storage", handleStorageChange);
    return () => window.removeEventListener("storage", handleStorageChange);
  }, [db, key]);
  
  const updateData = (updater: (data: T) => void) => {
    db.update(updater);
    setData({ ...db.data });
  };
  
  return [data, updateData] as const;
}

// Usage in component
function App() {
  const [data, updateData] = useLocalStorageDb("app-data", { todos: [] });
  
  const addTodo = (todo: string) => {
    updateData((data) => {
      data.todos.push({ id: Date.now(), text: todo, done: false });
    });
  };
  
  return <div>{/* Component JSX */}</div>;
}

Error Handling

Browser storage adapters may encounter various errors:

import { LocalStoragePreset } from "lowdb/browser";

try {
  const db = LocalStoragePreset("my-data", { items: [] });
  
  db.update(({ items }) => {
    // Add large object that might exceed quota
    items.push({ id: 1, largeData: "...".repeat(1000000) });
  });
} catch (error) {
  // Handle different storage errors
  switch (error.name) {
    case "QuotaExceededError":
      console.error("Storage quota exceeded");
      // Could implement cleanup or user notification
      break;
    case "SecurityError":
      console.error("Storage access denied (private browsing?)");
      break;
    default:
      console.error("Storage error:", error);
  }
}

// Handle JSON parsing errors for corrupted data
try {
  const db = LocalStoragePreset("potentially-corrupted", {});
  db.read(); // Might fail if localStorage contains invalid JSON
} catch (error) {
  if (error instanceof SyntaxError) {
    console.error("Corrupted data in localStorage");
    // Could clear corrupted data and reinitialize
    localStorage.removeItem("potentially-corrupted");
  }
}

Performance Considerations

Synchronous Operations

Browser storage adapters are synchronous and may block the main thread:

// For large datasets, consider batching updates
const db = LocalStoragePreset("large-dataset", { items: [] });

// Instead of multiple individual updates
// for (let i = 0; i < 1000; i++) {
//   db.update(({ items }) => items.push({ id: i })); // 1000 storage writes
// }

// Use single batch update
db.update(({ items }) => {
  for (let i = 0; i < 1000; i++) {
    items.push({ id: i });
  }
}); // 1 storage write

Memory Usage

Browser storage loads all data into memory. For large datasets:

  • Consider data pagination or lazy loading
  • Implement data cleanup strategies
  • Use IndexedDB for larger datasets (via custom adapters)

Private Browsing Mode

Some browsers restrict storage in private/incognito mode:

function isStorageAvailable() {
  try {
    const test = "__storage_test__";
    localStorage.setItem(test, test);
    localStorage.removeItem(test);
    return true;
  } catch {
    return false;
  }
}

if (isStorageAvailable()) {
  const db = LocalStoragePreset("app-data", {});
} else {
  // Fallback to memory storage
  const db = new LowSync(new MemorySync(), {});
}

Browser Compatibility

Browser storage adapters work in all modern browsers that support:

  • localStorage/sessionStorage APIs (IE8+, all modern browsers)
  • JSON.parse/JSON.stringify (IE8+, all modern browsers)
  • ES6 Classes and Modules (modern browsers or with transpilation)

For older browser support, ensure your build process includes appropriate polyfills and transpilation.

docs

browser.md

core.md

index.md

node.md

tile.json