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

@skybolt/vite-plugin

v3.5.1

Published

Vite plugin for Skybolt - High-performance asset caching for multi-page applications

Readme

@skybolt/vite-plugin

Vite plugin for Skybolt - High-performance asset caching for multi-page applications.

What is Skybolt?

Skybolt eliminates HTTP requests for cached assets on repeat visits by using Service Workers and the Cache API. On first visit, assets are inlined in the HTML and cached. On subsequent visits, the server sends regular <link> and <script> tags, which the Service Worker intercepts and serves instantly from cache.

Result: Zero network requests for CSS/JS on repeat visits. Assets load in ~5ms.

Installation

pnpm add @skybolt/vite-plugin

Usage

1. Configure Vite

// vite.config.js
import { defineConfig } from 'vite'
import { skybolt } from '@skybolt/vite-plugin'

export default defineConfig({
  base: '/assets/',
  build: {
    manifest: true,  // Required!
    outDir: 'dist',
    rollupOptions: {
      input: {
        critical: 'src/css/critical.css',
        main: 'src/css/main.css',
        app: 'src/js/app.js'
      }
    }
  },
  plugins: [skybolt()]
})

2. Build

pnpm run build

This generates:

dist/
├── assets/
│   ├── critical-Hx7kQ9mN.css
│   ├── main-Pw3rT8vL.css
│   └── app-Km5nR2xQ.js
├── .skybolt/
│   └── render-map.json      # For server adapters
└── skybolt-sw.js            # Service Worker

3. Use with a Server Adapter

Install a Skybolt adapter for your language:

  • PHP: composer require jensroland/skybolt
  • Ruby: gem install skybolt
  • Python: pip install skybolt (or: uv add skybolt / poetry add skybolt)
  • Go: go get github.com/JensRoland/skybolt-go

Then, use the adapter to include Skybolt-managed assets in your HTML.

Example (PHP):

<?php
$sb = new Skybolt\Skybolt(__DIR__ . '/dist/.skybolt/render-map.json');
?>
<!DOCTYPE html>
<html>
<head>
    <?= $sb->css('src/css/critical.css') ?> 
    <?= $sb->launchScript() ?> 
    <?= $sb->css('src/css/main.css') ?> 
</head>
<body>
    <h1>Hello Skybolt!</h1>
    <?= $sb->script('src/js/app.js') ?> 
</body>
</html>

4. Serve the Service Worker

Configure your web server to serve /skybolt-sw.js from dist/skybolt-sw.js.

Apache (.htaccess):

RewriteRule ^skybolt-sw\.js$ dist/skybolt-sw.js [L]

Nginx:

location = /skybolt-sw.js {
    alias /path/to/dist/skybolt-sw.js;
}

PHP (development):

<?php
// public/skybolt-sw.js (or use a router)
header('Content-Type: application/javascript');
header('Service-Worker-Allowed: /');
readfile(__DIR__ . '/../dist/skybolt-sw.js');

Options

skybolt({
  // Output directory for render-map.json (relative to build output)
  outDir: '.skybolt',

  // URL path where Service Worker will be served
  swPath: '/skybolt-sw.js',

  // Enable debug logging
  debug: false
})

How It Works

First Visit

  1. Server reads render-map.json
  2. Server checks cookie (empty - new visitor)
  3. Server inlines assets with sb-* attributes
  4. Browser receives HTML with inlined CSS/JS
  5. Skybolt client extracts content and caches via Service Worker
  6. Client writes asset versions to cookie

Repeat Visit

  1. Server reads render-map.json
  2. Server checks cookie (has asset versions)
  3. Server sends regular <link> and <script> tags
  4. Browser requests assets
  5. Service Worker intercepts and serves from Cache API (~5ms)
  6. Zero network requests!

After Build (Cache Invalidation)

  1. You run pnpm run build
  2. Vite generates new hashes for changed files
  3. Plugin updates render-map.json
  4. Visitor returns, server detects hash mismatch
  5. Server inlines new assets
  6. Client updates cache and cookie
  7. Automatic invalidation!

Cache Digest

Skybolt uses Cache Digest - a Cuckoo filter-based probabilistic data structure that provides compact cookie storage for cache state tracking.

Size Comparison

Instead of storing asset names and hashes explicitly (src/css/main.css:Pw3rT8vL,...), Skybolt compresses this into a compact binary filter stored in the sb_digest cookie:

| Assets | Plain Text | Cache Digest | Compression | | ------ | ------------ | ------------ | ----------- | | 10 | ~400 bytes | ~50 bytes | 88% | | 50 | ~2,000 bytes | ~350 bytes | 84% | | 100 | ~4,000 bytes | ~700 bytes | 84% | | 200 | ~8,000 bytes | ~1,400 bytes | 84% |

Trade-offs

  • No false negatives: If an asset is cached, the filter will always report it
  • Small false positive rate (~1-3%): Occasionally reports uncached assets as cached, causing a network fetch instead of inline - a minor one-time performance hit
  • Supports deletion: Unlike Bloom filters, items can be removed when evicting or invalidating cache entries

API

import { CuckooFilter, createCacheDigest } from '@skybolt/vite-plugin/cache-digest'

// Create from asset list
const assets = ['src/css/main.css:Pw3rT8vL', 'src/js/app.js:Km5nR2xQ']
const digest = createCacheDigest(assets)

// Serialize to cookie (URL-safe base64)
const cookie = digest.toBase64()

// Restore on server
const restored = CuckooFilter.fromBase64(cookie)
restored.lookup('src/css/main.css:Pw3rT8vL')  // true
restored.lookup('unknown:asset')              // false (definitely not present)

Render Map Schema

The render-map.json contains everything server adapters need:

{
  "version": 1,
  "generated": "2025-11-24T12:00:00.000Z",
  "skyboltVersion": "3.0.0",
  "basePath": "/assets/",
  "assets": {
    "src/css/main.css": {
      "url": "/assets/main-Pw3rT8vL.css",
      "hash": "Pw3rT8vL",
      "size": 85000,
      "content": "body{margin:0}..."
    }
  },
  "client": {
    "script": "class SkyboltClient{..."
  },
  "serviceWorker": {
    "filename": "skybolt-sw.js",
    "path": "/skybolt-sw.js"
  }
}

Browser Support

  • Chrome/Edge 60+
  • Firefox 55+
  • Safari 11.1+

Requires Service Worker and Cache API support. Falls back gracefully to standard external assets when unavailable.

Publishing

To publish a new version, run one command from the packages/vite-plugin directory:

pnpm version patch   # 3.1.1 → 3.1.2
pnpm version minor   # 3.1.1 → 3.2.0
pnpm version major   # 3.1.1 → 4.0.0

This automatically:

  1. Updates package.json
  2. Syncs version to README.md and the JS source files using scripts/sync-version.js
  3. Regenerates minified files
  4. Commits all changes
  5. Creates a git tag (e.g., v3.1.2)
  6. Triggers the postversion script, which creates the vite-plugin-v* tag

You then have to run git push origin main --tags to push the changes and tag to GitHub, which triggers the publish workflow.

The workflow uses vite-plugin-v* tags (not just v*) to differentiate from the adapter package tags. It also includes --provenance for supply chain security.

The publish-vite-plugin.yml Github Action will automatically build and publish the package to NPM using OIDC authentication.

License

MIT