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

@appshell/runtime

v1.0.0-alpha.72

Published

The shared singleton that delivers a package's runtime configuration to it

Readme

@appshell/runtime

The store that delivers a package's runtime configuration (vars) to it.

This is a shared singleton. There is exactly one instance per page, held in the module federation share scope, and both the host and every package must declare it as such. It replaced window.__appshell_vars__<scope>.

Most packages should not import this directly — use @appshell/runtime/vars below, which supplies the scope for you.

@appshell/runtime/vars

The accessor most packages actually want. It reads this package's vars, with no scope to pass and no way to name someone else's:

import { getVars } from '@appshell/runtime/vars';

const { BACKGROUND_COLOR } = getVars<{ BACKGROUND_COLOR: string }>();

It is a subpath rather than a main-entry export for a reason. AppshellPlugin compiles the package's own scope into whatever imports it, and the main entry is the shared module — one instance for the whole page — so a scope baked in there would be one package's, and every other package would read the wrong vars.

The exact-match share key '@appshell/runtime' does not catch '@appshell/runtime/vars', so each package bundles its own copy of the accessor with its own scope, while the store they all reach stays the single shared instance.

getVars throws MissingScopeError when the package was built without AppshellPlugin, since nothing substituted the scope.

Contract

setVars(scope, vars); // the host, immediately before loading a remote
readVars(scope); // a package, reading its own configuration
hasVars(scope); // branch instead of catch

@appshell/loader calls setVars before it loads a remote, so a package's vars are in place before its modules evaluate — including a read at module-eval time.

The first write for a scope wins and is frozen. Re-delivering the identical vars is a no-op, because the same remote can be mounted more than once; replacing them throws VarsConflictError.

readVars throws MissingVarsError rather than returning an empty object. A package that silently renders with no configuration is the failure this replaced.

What this does and does not fix

Against the global it replaced, it fixes: unbounded, never-cleaned-up keys; silent cross-package overwrite; the load-order coupling between host and remote; and being untyped and undiscoverable.

It does not make a scope's vars private. Any code on the page can call readVars('SomeOtherScope'), and a package that loads early can squat on a scope that has not been delivered yet. Nothing short of a separate realm — an iframe, a worker — would change that, and none of this is a security boundary. Do not put a secret in vars; the registry serves them to the browser in the composition either way.

Setup

Both sides declare it, or each ends up with its own empty store:

new ModuleFederationPlugin({
  shared: {
    '@appshell/runtime': { singleton: true },
  },
});

AppshellPlugin fails the build when a package omits it.