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

@itznotabug/vitepot

v0.0.2

Published

Static-first Vite/VitePress honeypot plugin for serving fake sensitive files to crawlers, scanners, and bots.

Downloads

5,228

Readme

VitePot 🐝

npm version CI License Vite VitePress TypeScript

Static-first honeypot plugin for VitePress and other Vite-powered static sites.

VitePot emits realistic-looking sensitive files like /.env, /wp-config.php, /backup.sql, /.git/config, /vercel.json, and settings.py so noisy crawlers, path probers, and low-effort scanners spend time on bait instead of your real surface area.

What It Does

  • Serves traps from memory in vitepress dev
  • Emits real trap files during vitepress build
  • Reuses the same trap responses in preview
  • Generates syntax-aware fake content for env, PHP, SQL, Git, JSON, JS, YAML, Python, INI, logs, and plain text
  • Uses reserved .test domains and RFC 5737 test-net IPs so generated data never points to real infrastructure
  • Supports custom traps with sync content, async content, binary content, and per-trap directory placement

Installation

bun add @itznotabug/vitepot

Usage

Quick Start

// .vitepress/config.mts
import { defineConfig } from 'vitepress';
import { vitepot } from '@itznotabug/vitepot';

export default defineConfig({
    vite: {
        plugins: [
            vitepot()
        ],
    },
});

That enables the built-in trap set at the site root.

Full Example

import { defineConfig } from 'vitepress';
import { vitepot } from '@itznotabug/vitepot';

export default defineConfig({
    vite: {
        plugins: [
            vitepot({
                variants: ['cms-roots', 'archive-roots'],
                dirs: ['/legacy'],
                custom: [
                    { 
                        path: '/private.env'
                    },
                    { 
                        path: '/secrets.ini', kind: 'ini' 
                    },
                    {
                        path: '/credentials.txt',
                        content: 'admin=disabled\nroot=disabled\n',
                    },
                    {
                        path: '/ai-keys.json',
                        contentType: 'application/json',
                        content: async ({ helpers }) =>
                            JSON.stringify(
                                {
                                    openai: helpers.fakeOpenAIKey(),
                                    anthropic: helpers.fakeAnthropicKey(),
                                    google: helpers.fakeGoogleAIKey(),
                                },
                                null,
                                2,
                            ),
                    },
                    {
                        path: '/archive.bin',
                        contentType: 'application/octet-stream',
                        content: new Uint8Array([0xde, 0xad, 0xbe, 0xef]),
                    },
                ],
            }),
        ],
    },
});

Runtime Model

Dev

During vitepress dev, VitePot registers middleware and serves trap responses directly from memory. No files are written.

Build

During vitepress build, VitePot generates the trap set and emits static assets into the output bundle. If a trap path collided with an existing output file, VitePot skips it and logs a warning.

Preview

During preview, the same trap middleware is mounted so local preview behavior stays aligned with the built output.

Built-In Trap Set

The default set includes 43 file traps across:

  • leaked env and credential files
  • Git and source-control metadata
  • WordPress and PHP config files
  • SQL dumps and backups
  • server config and auth files
  • framework and deployment config files
  • application logs

Examples:

  • /.env
  • /.aws/credentials
  • /.git/config
  • /wp-config.php
  • /config.php
  • /backup.sql
  • /web.config
  • /wp-login.php
  • /xmlrpc.php
  • /vercel.json
  • /next.config.js
  • /config/database.yml
  • /settings.py
  • /connectionstrings.config

Placement

Variants

Variants mirror compatible built-in traps into common subpaths.

vitepot({
    variants: ['cms-roots'],
});

Available presets:

  • cms-roots/blog, /site, /wordpress
  • app-roots/public, /api
  • archive-roots/backup, /backups, /old

Variant expansion is filtered by trap compatibility. Example: cms-roots expands /wp-config.php, but not /.env.

Explicit Directories

You can also mirror traps into directories you choose:

vitepot({
    dirs: ['/legacy', '/staging'],
});

API

Plugin Options

interface VitePotOptions {
    enabled?: boolean;
    variants?: VariantPreset[];
    dirs?: string[];
    custom?: CustomTrap[];
}

enabled

Turns the plugin on or off. Defaults to true.

variants

Adds built-in preset directories for compatible built-in traps.

dirs

Adds explicit extra directories for expansion. Root is always included automatically.

custom

Adds user-defined file traps.

type CustomTrap = {
    path: string;
    kind?: TrapKind;
    content?: string | Uint8Array | Promise<string | Uint8Array> |
        ((ctx: CustomTrapContext) => string | Uint8Array | Promise<string | Uint8Array>);
    contentType?: string;
    dirs?: string[];
};

Rules:

  • path must start with /
  • file paths must not end with /
  • content overrides the built-in generator
  • dirs on a custom trap applies only to that trap

Trap Kinds

Built-in generator families map file paths to realistic content shapes:

  • env
  • wordpress
  • php
  • sql
  • git
  • server
  • json
  • js
  • yaml
  • python
  • ini
  • log
  • text

If kind is omitted on a custom trap, VitePot infers it from the path.

Fake Data Helpers

Custom content factories receive deterministic helpers:

helpers.fakeDomain()           // calmrouter.test
helpers.fakeEmail()            // [email protected]
helpers.fakeHostname()         // db-3.calmrouter.test
helpers.fakeTestNetIPv4()      // 192.0.2.15
helpers.fakeMysqlPassword()    // strong fake password
helpers.fakeApiToken()         // generic token
helpers.fakePhpSecret()        // 64-char hex secret
helpers.fakeJwtLikeSecret()    // JWT-like secret
helpers.fakeCloudKey()         // AWS-style access key
helpers.fakeTimestamp()        // ISO timestamp
helpers.fakeOpenAIKey()        // sk-proj-...
helpers.fakeAnthropicKey()     // sk-ant-api...
helpers.fakeGoogleAIKey()      // AIzaSy...
helpers.fakeHuggingFaceToken() // hf_...
helpers.fakeStripeKey()        // sk_live_...
helpers.fakeSupabaseKey()      // JWT-like Supabase key
helpers.fakeClerkKey()         // sk_live_...
helpers.fakeVercelToken()      // Vercel-style token
helpers.fakeSentryDSN()        // https://[email protected]/123

All generated domains use the reserved .test TLD, and all generated IPs use RFC 5737 test-net ranges.

Development

bun install
bun run check
bun test
bun run typecheck
bun run build