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

with-simple-cache

v0.15.3

Published

A wrapper that makes it simple to add cache to any function

Readme

with-simple-cache

with-simple-cache

ci_on_commit deploy_on_tag

A wrapper that makes it simple to add cache to any function.

Notable features:

  • Wrapper pattern for simple and clean usage
  • Automatic cache key definition
  • Customizable cache data store

Install

npm install --save with-simple-cache

Quick start

Synchronous Cache, Synchronous Logic

in order prevent redundant sync computations from one machine, you can use a synchronous cache

for example:

import { createCache } from 'simple-in-memory-cache';
import { withSimpleCache } from 'with-simple-cache';

const solveSuperToughMathProblem = withSimpleCache(
  ({ a, b }) => ({ solution: a + b }),
  { cache: createCache() },
);
const result1 = solveSuperToughMathProblem({ a: 1, b: 1 }); // runs the logic, sticks the output into the cache, returns a reference to that output
const result2 = solveSuperToughMathProblem({ a: 1, b: 1 }); // finds the output in the cache, returns a reference to that output
expect(result1).toBe(result2); // same exact object, identified by same reference

Synchronous Cache, Asynchronous Logic

in order to prevent duplicate async requests from one machine, you can use a synchronous cache

for example:

import { createCache } from 'simple-in-memory-cache';
import { withSimpleCache } from 'with-simple-cache';

const getApiResult = withSimpleCache(
  async ({ name, number }) => axios.get(URL, { name, number }),
  { cache: createCache() },
);
const result1 = getApiResult({ name: 'casey', number: 821 }); // calls the api, puts promise of results into cache, returns that promise
const result2 = getApiResult({ name: 'casey', number: 821 }); // returns the same promise from above, because it was found in cache - since same input as request above was used
expect(result1).toBe(result2); // same exact object - the promise
expect(await result1).toBe(await result2); // same exact object - the result of the promise

Asynchronous Cache, Asynchronous Logic

in order to cache the output of async logic in a persistant store or across machines, you'll likely find you need to use an async cache.

for example

import { createCache as createOnDiskCache } from 'simple-on-disk-cache';
import { withSimpleCacheAsync } from 'with-simple-cache';

const getApiResult = withSimpleCacheAsync(
  async ({ name, number }) => axios.get(URL, { name, number }),
  { cache: createOnDiskCache() },
);
const result1 = getApiResult({ name: 'casey', number: 821 }); // calls the api, puts promise of results into cache, returns that promise
const result2 = getApiResult({ name: 'casey', number: 821 }); // returns the same promise from above, because it was found in cache - since same input as request above was used
expect(result1).toBe(result2); // same exact object - the promise
expect(await result1).toBe(await result2); // same exact object - the result of the promise

note: this wrapper additionally uses an in-memory cache internally to cache the promise the async cache returns, to prevent duplicate requests

Examples

Add cache to an existing function

import { createCache } from 'simple-in-memory-cache';
import { withSimpleCache } from 'with-simple-cache';

const getRecipesFromApiWithCache = withSimpleCache(getRecipesFromApi, { cache: createCache() });

Define the function with cache directly

import { createCache } from 'simple-in-memory-cache';
import { withSimpleCache } from 'with-simple-cache';

const getBookByName = withSimpleCache(
  async (name: string) => {
    /* ... get the book ... */
    return book;
  },
  {
    cache: createCache(),
  },
);

Use a custom persistance layer

local storage, for example:

import { withSimpleCache } from 'with-simple-cache';

const getRecipesFromApiWithLocalStorageCache = withSimpleCache(getRecipesFromApi, {
  // just define how a cache can `get` from and `set` to this data store
  cache: {
    get: (key) => localStorage.getItem(key),
    set: (key, value) => localStorage.setItem(key, value),
  },
});

Use an asynchronous persistance layer

some extra logic is required in order to work with asynchronous caches. therefore, a different wrapper is available for this usecase: withSimpleCacheAsync.

asynchronous cache on-disk, for example:

import { createCache } from 'simple-on-disk-cache';
import { withSimpleCacheAsync } from 'with-simple-cache';

const getRecipesFromApiWithAsyncCache = withSimpleCacheAsync(getRecipesFromApi, {
  cache: createCache({ directory: { s3: { bucket: '__bucket__', prefix: '__prefix__' } } }),
});

Use a custom key serialization method

serialize the key as the sha hash of the args, for example

import { createCache } from 'simple-in-memory-cache';
import { withSimpleCache } from 'with-simple-cache';

const getRecipesFromApiWithLocalStorageCache = withSimpleCache(getRecipesFromApi, {
  cache: createCache(),
  serialize: {
    key: (args) =>
        crypto.createHash('sha256').update(JSON.stringify(args)).digest('hex'),
  }
});

Use a custom value serialization and deserialization method

if your cache requires you to store data as a string, as is typically the case with asynchronous caches, you can define how to serialize and deserialize the response of your logic

import { createCache } from 'simple-on-disk-cache';
import { withSimpleCacheAsync } from 'with-simple-cache';

const getRecipesFromApiWithLocalStorageCache = withSimpleCacheAsync(getRecipesFromApi, {
  cache: createCache({ directory: { s3: { bucket: '__bucket__', prefix: '__prefix__' } } }),
  serialize: {
    value: async (response) => JSON.stringify(await response),
  },
  deserialize: {
    value: async (cached) => JSON.parse(await cached)
  }
});

Define the cache at runtime from function inputs

if your cache is defined as part of the inputs to your function (e.g., if you're using the input context pattern), you define where to find the cache in the inputs

for example

import { createCache, SimpleInMemoryCache } from 'simple-in-memory-cache';
import { withSimpleCache } from 'with-simple-cache';

const getBookByName = withSimpleCache(
  async ({ name: string}, context: { cache: SimpleInMemoryCache<Book> }) => {
    /* ... get the book ... */
    return book;
  },
  {
    cache: ({ fromInput }) => fromInput[1].context.cache, // grab the cache from the input's "context" parameter (the second input parameter)
  },
);

const book = await getBookByName({ name: 'Hitchhikers Guide to the Galaxy' }, { cache: createCache() });

Features

Automatic cache key

The arguments your function is invoked with is used as the cache key, after serialization. For example:

import { createCache } from 'simple-in-memory-cache';
import { withSimpleCache } from 'with-simple-cache';

const getZodiacSign = withSimpleCache(async ({ birthday }: { birthday: string }) => /* ... */, { cache: createCache() });

getZodiacSign({ birthday: '2020-07-21' }); // here the cache key is `[{"birthday":"2020-07-21"}]`

note: array order does matter

Customizable cache data store

You can easily use a custom cache or custom data store / persistance layer with this wrapper.

import { withSimpleCache } from 'with-simple-cache';

const getZodiacSign = withSimpleCache(
  async ({ birthday }: { birthday: string }) => /* ... */,
  {
    cache: {
      get: (key: string) => /* ... how to get from your custom data store ... */,
      set: (key: string, value: any) => /** ... how to set to your custom data store ... */,
    }
  }
);