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

@fireart/envsync

v0.1.0

Published

Sync environment configuration across your team and devices

Readme

EnvSync CLI

The envsync command owns the local machine and the developer workflow: the filesystem, .env files, device identity, terminal UX and local project config. The API owns the source of truth.

Install

Requires Node.js 22.12+.

npm install -g envsync

Or run without installing:

npx envsync login

Commands

| Command | What it does | | ----------------- | -------------------------------------------------- | | envsync login | Signs in with Google, then registers this device | | envsync current | Shows the signed-in account and the current device | | envsync logout | Removes stored credentials from this machine |

init, switch and save land in later steps.

Using the short env form

The binary is named envsync on purpose. Installing a binary called env would shadow the POSIX /usr/bin/env on PATH and break things like env FOO=1 node app.js. If you want the short form from CLI.md, alias it:

alias env="envsync"

Local development

# from the repo root
yarn build:cli
node apps/cli/dist/index.js login

# or watch mode
yarn dev:cli

Point the CLI at a different API with ENVSYNC_API_URL:

ENVSYNC_API_URL=http://localhost:3000 node apps/cli/dist/index.js current

Publishing

From the repo root (requires an npm account that can publish envsync):

npm login
yarn publish:cli

prepublishOnly builds dist/ first. Only dist/ is included in the tarball (files in package.json). Bump version in apps/cli/package.json before each release.

Where state lives

~/.config/envsync/config.json     device id + device name
OS keychain (account "auth")      access token
OS keychain (account "identity")  Ed25519 device identity key pair

$XDG_CONFIG_HOME is honoured on macOS/Linux; Windows uses %APPDATA%/envsync. If no OS credential store is available (a container, CI, or Linux without libsecret) the CLI falls back to ~/.config/envsync/credentials.json with 0600 permissions and warns that it did so.

How login works

Google sign-in only bootstraps a brand-new device. Once the device is registered, every later authentication is a signed challenge with no browser.

First run (bootstrap)

  1. The CLI starts a throwaway HTTP server on an OS-assigned loopback port.
  2. It opens the browser at GET /auth/google?state=..., where state carries the loopback port and a random nonce through Google.
  3. The API mints tokens, stores them behind a single-use code (60s TTL) and redirects to http://127.0.0.1:<port>/callback?code=...&nonce=....
  4. The CLI checks the nonce and exchanges the code at POST /auth/cli/exchange.
  5. It generates an Ed25519 identity key pair and registers the device, sending only the public key.

Tokens never travel through the browser URL, so they stay out of browser history.

Every later authentication (challenge)

  1. POST /auth/challenge/start with the device id returns a random nonce that the API stores with a 60s expiry.
  2. The CLI signs the nonce with its identity private key.
  3. POST /auth/challenge/complete verifies the signature against the stored public key and returns an access token only.

There is no refresh token for the CLI: when the access token expires, the CLI silently runs another challenge. The private key never leaves this machine.