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

xenvault

v1.1.14

Published

CLI to pull SOPS-encrypted secrets from a private GitHub repo

Readme

xenvault

CLI to pull SOPS-encrypted secrets from a private GitHub secrets repo into your projects.

How it works

Secrets live in a dedicated GitHub repo structured like this:

secrets-repo/
  .sops.yaml
  myapp/
    .env.development
    .env.production
  anotherapp/
    .env.staging

Each .env.<environment> file is encrypted with SOPS + age. xenvault fetches and decrypts them into your project directory.

Prerequisites

brew install sops age

You also need an age private key with access to the secrets. Set one of:

export SOPS_AGE_KEY_FILE=~/.age/key.txt   # path to key file
export SOPS_AGE_KEY=AGE-SECRET-KEY-1...   # inline key (good for CI)

If you don't have a key yet, generate one and share the public key with the repo owner:

age-keygen -o ~/.age/key.txt
# Share the "Public key: age1..." line with the repo owner

Installation

npm install -g xenvault

Commands

xenvault init

Initialize either a new project inside the secrets repo, or a secrets.config.json in a consumer project.

? What would you like to initialize?
> New project in secrets repo
  secrets.config.json (to pull secrets into this directory)

New project in secrets repo — run from inside the secrets repo. Creates the project directory.

secrets.config.json — run from a consumer project. Saves the secrets repo location so xenvault pull knows where to fetch from.


xenvault list

List all projects and environments available in the secrets repo.

xenvault list
  myapp                    development, production
  anotherapp               staging

Works from inside the secrets repo (no PAT needed) or remotely via GitHub API.


xenvault pull

Fetch and decrypt secrets into your project directory.

# Interactive
xenvault pull

# Direct (skips prompts)
xenvault pull --project myapp --env development --output .

Writes .env.<environment> into the output directory (defaults to current directory).

Flags:

| Flag | Description | |------|-------------| | --project | Project name (skips interactive prompt) | | --env | Environment name, e.g. development | | --output | Output directory (default: .) |


xenvault view <file>

Decrypt and print an encrypted file to stdout. Must have a local clone of the secrets repo.

xenvault view path/to/.env.development

xenvault edit <file>

Open an encrypted file in your editor via sops. Must have a local clone of the secrets repo.

xenvault edit path/to/.env.development

Uses the $EDITOR environment variable (SOPS default).


Configuration

Remote access (consumer projects)

Run xenvault init → choose secrets.config.json to create this file in your project:

{
  "github": {
    "url": "https://github.com/your-org/secrets-repo"
  }
}

You also need a GitHub PAT with repo read scope. Set it via:

export SECRETS_GITHUB_PAT=ghp_...

Local access (inside the secrets repo)

No PAT needed. xenvault detects the secrets repo by looking for .sops.yaml in the directory tree.


Secrets repo structure

Files must follow the convention <project>/.env.<environment>:

myapp/.env.development
myapp/.env.production
anotherapp/.env.staging

A minimal .sops.yaml for age encryption:

creation_rules:
  - path_regex: .*\.env\..*
    age: >-
      age1abc...(team member 1),
      age1xyz...(team member 2)

Encrypt a new file:

sops --encrypt .env.development > myapp/.env.development

Adding a new team member

The new member generates their own key — the private key never leaves their machine.

1. New member generates an age key pair:

age-keygen -o ~/.age/key.txt
export SOPS_AGE_KEY_FILE=~/.age/key.txt  # add to ~/.zshrc

The command prints a public key like:

Public key: age1abc123...

They send you just that age1abc123... line.

2. Repo owner adds the public key to .sops.yaml:

creation_rules:
  - path_regex: .*\.env\.development.*
    age: >-
      age1existing...,
      age1abc123...

3. Repo owner re-encrypts affected files:

sops updatekeys myapp/.env.development
# repeat for each file they need access to

This adds a copy of the data key encrypted for their public key — no secret is ever shared.

4. New member sets up their consumer project:

brew install sops age
export SOPS_AGE_KEY_FILE=~/.age/key.txt

# in their project directory
xenvault init   # choose "secrets.config.json"
export SECRETS_GITHUB_PAT=ghp_...
xenvault pull