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

unotoken

v0.3.0

Published

unotoken — yokotoken + cloud features (OAuth unlock, team vaults, key escrow, device signatures)

Readme

unotoken

yokotoken + cloud features.

unotoken is a private extension of yokotoken, the agent-native encrypted credential vault. It adds cloud features on top of the open-source MIT core:

  • OAuth unlock -- Sign in with Google or GitHub to unlock your vault (no passphrase needed)
  • Device signatures -- New devices must be approved via email code before accessing the vault
  • Team vaults -- Share encrypted vaults across a team (coming soon)
  • Key escrow -- Recovery keys held by your organization (coming soon)

How it works

unotoken depends on yokotoken as an npm package. All of yokotoken's public API is re-exported, so unotoken is a drop-in replacement:

// Before
import { getSecret } from 'yokotoken/sdk';
import { NetworkVaultClient } from 'yokotoken/client';

// After (identical API)
import { getSecret } from 'unotoken/sdk';
import { NetworkVaultClient } from 'unotoken/client';

The CLI wraps yokotoken and adds new commands:

# All yokotoken commands work as-is
unotoken init
unotoken serve
unotoken unlock
unotoken set my/secret "value"
unotoken get my/secret

# New: OAuth commands
unotoken auth link google      # Link Google account for passwordless unlock
unotoken auth link github      # Link GitHub account
unotoken auth list             # Show linked providers
unotoken auth unlink google    # Remove a linked provider
unotoken auth config --show    # View OAuth configuration

Installation

npm install unotoken

Or for CLI usage:

npm install -g unotoken

Package exports

| Import path | Description | |-------------|-------------| | unotoken | Full vault API (re-exports yokotoken) | | unotoken/sdk | Worker SDK for agent access (re-exports yokotoken/sdk) | | unotoken/client | Network client for remote vaults (re-exports yokotoken/client) |

Development

npm install
npm run typecheck
npm test
npm run build

Build-Time Env Injection

unotoken replaces .env files with vault-backed secrets. Two modes:

exec -- inject secrets into a child process

No .env file needed. Secrets are injected as environment variables directly:

# Run your app with vault secrets injected
unotoken exec --prefix myapp/ -- npm run dev

# In package.json:
"scripts": {
  "dev": "unotoken exec --prefix myapp/ -- next dev",
  "build": "unotoken exec --prefix myapp/ -- next build"
}

Path mapping: myapp/stripe/secret/key becomes STRIPE_SECRET_KEY.

dotenv -- generate .env files from vault

For tools that require a .env file on disk:

# Generate .env.local from vault
unotoken dotenv --prefix myapp/ --out .env.local

# Clean up after build (CI/CD)
unotoken dotenv --clean .env.local

Scoped tokens

Create tokens that only access specific prefixes:

# Create a token restricted to myapp/* secrets
unotoken token create --name myapp-ci --prefix myapp/

# Multi-prefix tokens
unotoken token create --name shared --prefix myapp/ --prefix common/

Real-app demo (levelfit)

A hands-on demo script walks through the complete flow using real secrets:

bash scripts/demo-levelfit.sh

The demo covers:

  1. Scoped token creation -- create a token restricted to levelfit/*
  2. Access verification -- confirm the token can access levelfit/ but not other prefixes
  3. exec injection -- run a process with vault secrets as env vars (no file on disk)
  4. dotenv generation -- produce a .env file equivalent to a hand-maintained .env.local
  5. Cleanup -- remove generated files and revoke demo tokens

Prerequisites: vault running (unotoken serve), vault unlocked (unotoken unlock), secrets stored under levelfit/ prefix.

Package.json Scripts Integration

Replace .env files with vault-backed secrets in your npm scripts. Here are before/after patterns for common setups.

Next.js

Before (.env.local on disk):

{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  }
}

After (vault-backed):

{
  "scripts": {
    "dev": "unotoken exec --prefix myapp/ -- next dev",
    "build": "unotoken exec --prefix myapp/ -- next build",
    "start": "unotoken exec --prefix myapp/ -- next start"
  }
}

Vite

Before:

{
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  }
}

After:

{
  "scripts": {
    "dev": "unotoken exec --prefix myapp/ -- vite",
    "build": "unotoken exec --prefix myapp/ -- vite build",
    "preview": "unotoken exec --prefix myapp/ -- vite preview"
  }
}

Node.js API Server

Before:

{
  "scripts": {
    "dev": "tsx watch src/server.ts",
    "start": "node dist/server.js"
  }
}

After:

{
  "scripts": {
    "dev": "unotoken exec --prefix myapi/ -- tsx watch src/server.ts",
    "start": "unotoken exec --prefix myapi/ -- node dist/server.js"
  }
}

CI/CD (GitHub Actions)

Use UNOTOKEN_TOKEN and UNOTOKEN_URL environment variables for remote vault access:

# .github/workflows/deploy.yml
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
      - run: npm ci
      - name: Build with vault secrets
        env:
          UNOTOKEN_TOKEN: ${{ secrets.VAULT_TOKEN }}
          UNOTOKEN_URL: https://vault.example.com:13100
        run: unotoken exec --prefix myapp/ -- npm run build

Or as a single inline command:

UNOTOKEN_TOKEN=${{ secrets.VAULT_TOKEN }} UNOTOKEN_URL=https://vault.example.com unotoken exec --prefix myapp/ -- npm run build

Fallback Pattern

If the vault might be unavailable (e.g., a new team member who hasn't set up the vault yet), use a fallback to .env.local:

{
  "scripts": {
    "dev": "unotoken exec --prefix myapp/ -- next dev || (echo 'Vault unavailable, using .env.local fallback' && next dev)",
    "build": "unotoken exec --prefix myapp/ -- next build || (echo 'Vault unavailable, using .env.local fallback' && next build)"
  }
}

This runs with vault secrets when available, and falls back to any .env.local file on disk when the vault is locked or unreachable.

Moving from .env to unotoken

A step-by-step migration guide for replacing hand-maintained .env files with vault-backed secrets.

Step 1: Import existing secrets into the vault

# Start the vault if not running
unotoken serve &
unotoken unlock

# Import each secret from your .env.local
unotoken set myapp/database/url "postgresql://user:pass@host/db"
unotoken set myapp/stripe/secret/key "sk_live_..."
unotoken set myapp/next/public/stripe/publishable/key "pk_live_..."

# Or bulk-import from a .env file (one per line)
while IFS='=' read -r key value; do
  # Convert KEY_NAME to key/name path format
  path=$(echo "$key" | tr '[:upper:]' '[:lower:]' | tr '_' '/')
  unotoken set "myapp/$path" "$value"
done < .env.local

Step 2: Create a scoped token

# Create a token restricted to your app's prefix
unotoken token create --name myapp-dev --prefix myapp/

# Save the displayed token -- it's only shown once
# For CI/CD, store it as a GitHub Actions secret (VAULT_TOKEN)

Step 3: Update package.json scripts

Replace direct commands with unotoken exec:

 {
   "scripts": {
-    "dev": "next dev",
-    "build": "next build"
+    "dev": "unotoken exec --prefix myapp/ -- next dev",
+    "build": "unotoken exec --prefix myapp/ -- next build"
   }
 }

Step 4: Update .gitignore

If using dotenv mode (generating .env.local from the vault), add the generated file to .gitignore since it's now a build artifact:

# Generated by unotoken (vault-backed, not hand-maintained)
.env.local

Step 5: Remove .env.local

Once you've verified everything works with vault-backed secrets:

# Verify vault injection works
npm run dev  # should start with all env vars injected

# Remove the old .env.local
rm .env.local

Path-to-Variable Mapping Reference

Vault paths are converted to environment variable names by:

  1. Stripping the prefix (e.g., myapp/)
  2. Replacing / with _
  3. Uppercasing the result

| Vault Path | Env Variable | |------------|-------------| | myapp/stripe/secret/key | STRIPE_SECRET_KEY | | myapp/database/url | DATABASE_URL | | myapp/next/public/stripe/publishable/key | NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY | | myapp/resend/api/key | RESEND_API_KEY |

Architecture

yokotoken (MIT, public)
  |
  +-- unotoken (private, cloud add-on)
        |-- Re-exports all yokotoken API
        |-- OAuth PKCE browser flow engine
        |-- Google + GitHub OIDC/OAuth providers
        |-- Wrapped key storage for OAuth-derived unlock
        |-- Device signatures (email-verified device approval)
        |-- CLI extensions (auth link, auth unlink, auth list, auth config)

Upstream updates are clean: just bump the yokotoken version in package.json.

License

UNLICENSED (private)