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

bini-export

v1.0.1

Published

Pure static SPA export for bini-router — pre-renders routes, generates 404.html, strips platform files

Readme

bini-export

npm version license vite bini-router typescript PRs Welcome

Pure static SPA export for bini-router projects.
Pre-renders every static route, generates the right 404.html, and strips all platform server files — leaving dist/ ready for GitHub Pages, Netlify static, Vercel, Cloudflare Pages, S3, and any other static host.


Features

  • 🗂️ Per-route pre-rendering — each static route gets its own index.html so any static host serves pages directly without client-side routing tricks
  • 🔴 Custom 404 support — if src/app/not-found.tsx exists it's used as 404.html; otherwise a smart redirect fallback is generated
  • 🧹 Platform file cleanup — deletes all bini-router platform entries (Netlify, Vercel, Cloudflare, Node, Deno, Bun, AWS) after build, leaving a pure SPA dist/
  • 📁 Empty dir pruning — leftover empty directories are removed automatically
  • 🔇 Zero effect on normal builds — completely inert unless --mode export is passed
  • ⚙️ Configurable — custom clean paths, mode name, and opt-in/out of each feature
  • 🎨 Vite-style output — clean, coloured build logs matching Vite's style

Install

npm install -D bini-export

Setup

1. Add to vite.config.ts

import { defineConfig } from 'vite'
import react            from '@vitejs/plugin-react'
import { biniEnv }      from 'bini-env'
import { biniroute }    from 'bini-router'
import { biniExport }   from 'bini-export'

export default defineConfig({
  base: '/my-repo/', // required for GitHub Pages subpath deployments
  plugins: [
    react(),
    biniEnv(),
    biniroute({ platform: 'netlify' }), // keep your normal platform
    biniExport(),                        // 👈 add this
  ],
})

2. Add the export script to package.json

{
  "scripts": {
    "dev"    : "vite --host --open",
    "build"  : "vite build",
    "export" : "vite build --mode export",
    "preview": "vite preview --host --open"
  }
}

Usage

| Command | What happens | |---|---| | pnpm build | Normal build — platform entry generated as usual | | pnpm export | Static export — routes pre-rendered, 404.html generated, platform files deleted |

Normal build output

dist/
netlify/
  edge-functions/
    api.ts          ← bini-router platform entry (kept)

Static export output

dist/
  index.html        ← SPA shell
  about/
    index.html      ← pre-rendered /about
  dashboard/
    index.html      ← pre-rendered /dashboard
  404.html          ← custom or default fallback

Build log

  ß bini-export  static export mode

  ß bini-export  pre-rendering 4 route(s)
  ➜  /about → dist/about/index.html
  ➜  /dashboard → dist/dashboard/index.html
  ➜  /profile → dist/profile/index.html
  ➜  404.html ← redirect template dist/404.html
  ➜  removed netlify/edge-functions/api.ts

  ß bini-export  export complete — 1 file(s) removed

404 Handling

bini-export automatically picks the right 404.html strategy based on your project:

| Situation | What gets generated | |---|---| | src/app/not-found.tsx exists | 404.html is a copy of index.html — the host boots the SPA and React Router renders your custom page | | No custom not-found | 404.html uses a redirect script that saves the original path to sessionStorage and sends the user to /, where the SPA restores the URL via history.replaceState |


Pre-rendering

On every pnpm export, bini-export reads your auto-generated src/App.tsx and extracts all static routes, skipping dynamic :param and * catch-all routes. For each route it copies dist/index.html into dist/<route>/index.html.

This means any static host can serve /about directly without needing a redirect, and your app loads instantly on any pre-rendered route.

Dynamic routes (e.g. /blog/:slug) are not pre-rendered — they are handled client-side as normal by React Router via the 404 redirect fallback.


Works on any static host

| Host | Static routes | Dynamic routes | |---|---|---| | GitHub Pages | ✅ pre-rendered | ✅ via 404.html redirect | | Netlify static | ✅ pre-rendered | ✅ via 404.html redirect | | Vercel static | ✅ pre-rendered | ✅ via 404.html redirect | | Cloudflare Pages | ✅ pre-rendered | ✅ via 404.html redirect | | AWS S3 + CloudFront | ✅ pre-rendered | ✅ configure error page to 404.html | | Firebase Hosting | ✅ pre-rendered | ✅ via 404.html redirect | | Surge.sh | ✅ pre-rendered | ✅ via 404.html redirect |


Options

biniExport({
  /**
   * Extra paths to delete after the static export build,
   * relative to the project root.
   * The plugin already covers all bini-router platform outputs by default.
   * @default []
   */
  cleanPaths: ['some/generated/file.ts'],

  /**
   * The Vite mode that activates this plugin.
   * Must match the --mode flag you pass to vite build.
   * @default 'export'
   */
  mode: 'export',

  /**
   * Generate a 404.html fallback.
   * Uses your custom not-found page if present, otherwise a redirect template.
   * @default true
   */
  copy404: true,

  /**
   * Pre-render each static route as its own index.html.
   * @default true
   */
  prerender: true,
})

Default paths cleaned

The plugin removes whichever of these exist after the build:

| Platform | Generated file | |---|---| | Netlify | netlify/edge-functions/api.ts | | Cloudflare Workers | worker.ts | | Node / Deno / Bun | server/index.ts · server/index.js | | AWS Lambda | handler.ts · handler.js | | Vercel | api/index.ts · api/index.js |

Empty parent directories left behind are pruned automatically.


How it works

biniExport() is a Vite plugin that hooks into closeBundle — the lifecycle event that fires after every file has been written to disk. When the build mode matches (default: export), it:

  1. Reads dist/index.html
  2. Scans src/App.tsx for static routes and copies index.html into each route directory
  3. Injects a sessionStorage redirect receiver into every pre-rendered index.html so dynamic route fallbacks work correctly
  4. Writes 404.html — using your custom not-found page if one exists, or the redirect template otherwise
  5. Deletes all known bini-router platform output files and prunes empty directories

In any other mode it is completely inert — zero effect on normal builds.


License

MIT © Binidu Ranasinghe