Polystore

A library to unify KV-stores. Allows you to write code that works on any KV store, both on the front-end and backend. Supports substores and intuitive expiration times. Get started:

npm install polystore
import kv from "polystore";
import { createClient } from "redis";

const URL = process.env.REDIS_URL;
const store = kv(createClient(URL).connect());

await store.set("hi", data, { expires: "1h" });
console.log(await store.get("hi"));
// { hello: "world" }

Easy peasy

It's a KV store. It has add(), set(), get(), has(), del() and more.

Documented

Getting started, API, Clients and custom stores for your convenience.

Tested and Typed

600+ tests, TS definitions and JSDocs for the best experience using the library.

Universal Javascript

Use it with React, Angular, Plain JS, Node.js, Bun, Tauri, Electron, etc.

Tiny Footprint

At just 3kb (min+gzip), the impact on your app loading time is minimal.

Intuitive expirations

Write the expiration as 100s, 1week, etc. and forget time-related bugs.

🧩 Support for many clients

We support 10+ clients with documentation for each of them. Adding your own client is also easy, you only need to define 3 methods: .get(), .set() and .entries().

Clients Documentation

import kv from "polystore";

const store1 = kv(new Map());
const store2 = kv(localStorage);
const store3 = kv(redisClient);
const store4 = kv("cookie");
const store5 = kv("file:///users/me/kv.json");
const store6 = kv(yourOwnStore);

🏖️ Clean and intuitive API

A set of high-performance item operations with .add(), .set(), .get(), .has() or .del(). We also provide group operations to manage your data easily.

API Documentation

import kv from "polystore";
const store = kv(new Map());

const key1 = await store.add("value1");
const key2 = await store.set("key2", "value2");
const val1 = await store.get("key1");
const has1 = await store.has("key1");
const key1 = await store.del("key1");

🛗 Create substores

Create a new substore with .prefix(), then you can ignore anything related to the prefix and treat it as if it was a brand new store.

Substore Documentation

const session = store.prefix("session:");
session.set("key1", "value1");

console.log(await session.all());
// { "key1": "value1" }

console.log(await store.all());
// { "session:key1": "value1" }

⏰ Easy expiration time

Simply write { expires: "1day" } with ANY client and forget about calculating TTL, Unix time, seconds vs milliseconds bugs, etc.

Expiration Documentation

await store.get("key");  // null

await store.set("key", "hi", { expires: "1s" });
await store.get("key");  // "hi"

await sleep(2000);

await store.get("key");  // null

🏃‍♂️‍➡️ Iterate over the data

Iterate asynchronously straight on the store! It will return a pair of [key, value] for each of the entries. You can also use it on a substore as well.

Iterator Documentation

for await (const [key, value] of store) {
  console.log(key, value);
}

const session = store.prefix('session:');
for await (const [key, value] of session) {
  console.log(key, value);
}

✨ Magic Autocomplete

Added jsdocs so the expected parameters and return value will be clearly defined in your IDE/Code Editor.

We added the description, a representative example and even a link for more information for every one of the methods available! We want you to have the best development experience possible with Polystore!

Created by Francisco and other contributors.

Need help? Book a call.