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

@stim-cli/cache

v1.14.0

Published

Cache provider contract and tier coordination for Stim.

Readme

@stim-cli/cache

The cache provider contract Stim uses for Metro transforms and native build artifacts, plus the tier coordination, timeout, and warning policy that sit in front of it.

The local filesystem is always the first tier. A project can add one optional second tier by pointing cache.provider at a module that implements this contract. Stim ships no network provider; writing one is an addition, not a change to Stim.

If Stim is not installed globally, replace stim with npx stim.

Selecting a provider

{
  "cache": {
    "provider": "./tools/cache-provider.cjs",
    "options": { "bucket": "mobile-cache" }
  }
}

The reference is a package name or a path relative to the settings file that declares it. Commit .stim.json beside the app's package.json; monorepo apps do not inherit an ancestor's provider. Machine settings override committed settings. cache.options merges by key from the layer that selects the provider, higher-precedence layers that name no provider, and lower-precedence layers that name the same provider resolved from the same directory; options written for another provider are ignored. Keep secrets out of committed settings; read them from the environment or from machine settings.

Writing a provider

export const apiVersion = 1;

export async function createCacheProvider({ projectRoot, options }) {
  return {
    metro: {
      async get({ key, cacheName, signal }) {
        return null;
      },
      async set({ key, value, cacheName, signal }) {},
    },
    builds: {
      async resolve({ platform, key, destinationDir, signal }) {
        return null;
      },
      async store({ platform, key, sourcePath, overwrite, signal }) {},
    },
  };
}

A provider implements one or both capabilities. It owns transport, serialization, archive format, authentication, and remote retention. Stim owns fingerprints, cache keys, and local artifact paths.

metro.get returns the stored value or null.

builds.resolve returns an existing path to the artifact, or null for a miss. destinationDir is a scratch directory Stim creates and owns: a provider that fetches the artifact must materialize it there and return a path inside it, and must leave the directory empty on a miss. The built-in filesystem tier already holds the artifact, so it returns its own cache path instead.

builds.store receives the .app directory or .apk file that Stim just built. overwrite: false must keep an entry that already exists for the key, and overwrite: true must replace it.

Every call receives an AbortSignal. A provider must honor it: Stim abandons the call at the deadline and keeps building or bundling with the local tier.

stim gc never deletes provider data, and the contract has no delete operation, so shared team or CI data is never removed by a local command.

Failure rules

Provider failures are cache misses. A timeout, module error, authentication error, or network error produces one warning per failure class per command or supervisor run and never fails a bundle, an install, a launch, or a successful build.

Contract tests

Run the shipped checks against your own module:

import { runCacheProviderContract } from '@stim-cli/cache';

const results = await runCacheProviderContract({
  provider: await createCacheProvider({ projectRoot, options }),
  projectRoot,
  workDir,
});

for (const result of results) {
  if (!result.passed) throw new Error(`${result.name}: ${result.error}`);
}

Pass providerModule instead of provider to load the module the way Stim does, which also checks apiVersion and the factory:

const results = await runCacheProviderContract({
  providerModule: './tools/cache-provider.cjs',
  projectRoot,
  workDir,
});

cacheProviderContractChecks() returns the same checks as individual cases for a test runner that reports each one separately. Both helpers only check the capabilities a provider advertises, bound every check with a deadline, and verify that a call settles once its AbortSignal aborts.

Budgets

Every provider call is bounded. The defaults are 2s for a Metro read, 10s for a Metro write, 30s for a build lookup, 60s for a build upload, and 10s to load the module. Override any of them per run with an environment variable:

STIM_CACHE_METRO_READ_TIMEOUT_MS=5000 stim start
STIM_CACHE_BUILD_RESOLVE_TIMEOUT_MS=60000 stim ios

The variables are STIM_CACHE_METRO_READ_TIMEOUT_MS, STIM_CACHE_METRO_WRITE_TIMEOUT_MS, STIM_CACHE_BUILD_RESOLVE_TIMEOUT_MS, STIM_CACHE_BUILD_UPLOAD_TIMEOUT_MS, and STIM_CACHE_LOAD_TIMEOUT_MS. Each takes whole milliseconds; any other value keeps the default.

The tiered Metro store also exposes flush(), which resolves once queued provider writes have drained. Metro never calls it; every in-flight write holds a referenced deadline, so a Metro process drains on its own within the write budget. It exists for tests and embedders that own the process.

Metro reads are also capped: at most six can be in flight, and the tier turns itself off for the rest of the run after five consecutive failures, so a broken provider costs one round of warnings rather than a timeout per transform.

The npm scope remains @stim-cli until the @stim scope is available.