npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@febkosq8/local-save

v0.7.0

Published

Lightweight wrapper around IndexedDB for secure and structured client-side data storage.

Downloads

512

Readme

local-save is a lightweight wrapper around IndexedDB for secure and structured client-side data storage. It provides encryption, expiration, and organized data storage across configurable categories.


Looking to experience how local-save can securely store and retrieve data?

👉 Try the Live Demo 👈

Features

  • Lightweight & Widespread Support: No external dependencies and works in all modern browsers.
  • TypeScript Support : Written in TypeScript for maximum type-safety and a great developer experience.
  • Encryption Support : Uses SubtleCrypto for secure data encryption with AES-GCM algorithm.
  • Category Management : Organize data into predefined categories.
  • Data Expiry : Allows setting an expiration threshold for data and a method to clear expired data.
  • IndexedDB Management : Handles IndexedDB, object store creation and IndexedDB versioning management automatically.
  • Logging : Debug logs for detailed insights.

Installation

npm install @febkosq8/local-save
# or
pnpm add @febkosq8/local-save

Usage

Configuration Options

| Option Key | Type | Default | Description | | ----------------------------- | ---------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | dbName | string | "LocalSave" | Name of the IndexedDB database. | | encryptionKey | string | undefined | Encryption key that should be either [16, 24, or 32] characters to be used for AES-GCM encryption. If not provided, data will be stored in plain text. | | categories | string[] | ["userData"] | Array of categories (Object store names). | | expiryThreshold | number | 2592000000 | Data expiration threshold in milliseconds. | | blockedTimeoutThreshold | number | 10000 | Timeout in milliseconds before blocked IndexedDB open/delete requests fail. | | clearOnDecryptError | boolean | true | Whether to clear a category if decryption fails. | | printLogs | boolean | false | Whether to print logs (Debug and errors). |

Initialization

Create a new instance of LocalSave with the available configuration options

import LocalSave from "@febkosq8/local-save";
...
const localSaveConfig = {
  encryptionKey: "MyRandEncryptKeyThatIs32CharLong", // Encryption key for data
  categories: ["userData", "settings"], // Define categories for data storage
  expiryThreshold: 14 * 24 * 60 * 60 * 1000, // Clear data older than 14 days (in ms)
  blockedTimeoutThreshold: 15000, // Wait up to 15s when IndexedDB requests are blocked
};
const localSave = new LocalSave(localSaveConfig);

Storing data

Store data in a category

Here userData is the category. The key is user001 for the data { name: "John Doe", age: 30 }.

await localSave.set('userData', 'user001', { name: 'John Doe', age: 30 });

List saved data keys in a category

List all keys of the data stored in a category

const keys = await localSave.listKeys('userData');
console.log(keys); // ['user001']

Fetching data

Fetch data from a category using the category and key

The data will be returned along with the timestamp when it was stored. If the data is expired, it will return null.

try {
    const localDataFetch = await localSave.get('userData', 'user001');
    const { timestamp, data } = localDataFetch;
    console.log(data); // { name: "John Doe", age: 30 }
    console.log(timestamp); // UNIX timestamp of calling `set` method
    //handle data here
} catch (error) {
    //Error will be thrown if the decryption fails
    //handle error here
}

Removing data

Remove data using the category and key

await localSave.remove('userData', 'user001');

Clearing a category

Clear all data from a category

await localSave.clear('userData');

Clearing expired data

Clear all expired data from all categories

// If a value is provided, it will override the default expiry threshold
// This can be placed on top of the file to clear expired data on page load
await localSave.expire(14 * 24 * 60 * 60 * 1000); // Clear data older than 14 days from all categories (in ms)

Destroying the entire database

Clear all data from all categories and delete the database

await localSave.destroy();

Decrypting data manually

Decrypt data using the encryption key

This is useful when you want to decrypt the DBItemEncryptedBase64 string manually without using the get method

const decryptedData = await localSave.decryptData(DBItemEncryptedBase64);