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

create-bini-app

v10.0.2

Published

Build full-stack React apps for web, desktop, and mobile — from one codebase.

Readme

            XXXXXXXXXXXXXXXX               
         XXXXXXXXXXXXXXXXXXXXXz            
       YXXXXXXXXXXXXXXXXXXXXXXXX           
      vXXXXXXXXXXn    YXXXXXXXXXX          
      XXXXXXXXX        XXXXXXXXXX          
      XXXXXXXXX       XXXXXXXXXX           
      XXXXXXXXX  XXXXXXXXXXXXXX            
      XXXXXXXXX  XXXXXXXXXXXYz             
      XXXXXXXXX  XXXXXXXXXXXXXXXXY         
      XXXXXXXXX      YXXXXXXXXXXXXX        
      XXXXXXXXX          YXXXXXXXXX        
      XXXXXXXXX           XXXXXXXXXz       
      XXXXXXXXX  Xn     YXXXXXXXXXX        
      XXXXXXXXX  XXXXXXXXXXXXXXXXXX        
      XXXXXXXXX  XXXXXXXXXXXXXXXX          
      XXXXXXXXX  XXXXXXXXXXXXX             

Build full-stack React apps for web, desktop, and mobile — from one codebase.

npm version total downloads license node version

vite react typescript hono tailwindcss react-router tauri


Quick Start

npx create-bini-app@latest my-app
cd my-app
npm install
npm run dev

That's it — http://localhost:3000 opens automatically.


Why Bini.js

Most React starters give you a bundler and call it a day. Bini.js gives you a framework: file-based routing, a backend, environment handling, a native app story, and a deployment CLI, wired together and configured correctly from the first commit.

  • One codebase, every target. The same routes, API handlers, and components compile to a web app, a desktop binary, or a mobile app. Nothing is emulated or wrapped — desktop and mobile builds are real Tauri apps.
  • Convention over configuration. Drop a file in src/app/, get a route. Drop a file in src/app/api/, get an endpoint. No router config, no manual code splitting, no boilerplate.
  • Fast by default. Vite + Rolldown for bundling, Oxlint + Oxfmt for linting and formatting — all Rust-based, all pre-configured.

Features

Framework

  • File-based routing with nested layouts, dynamic segments, and per-route metadata
  • .mdx and .md content routes work out of the box alongside .tsx/.jsx — no extra setup
  • Folder-scoped loading.tsx, not-found.tsx, and error.tsx — the nearest one up the folder tree wins, same mental model as layouts
  • Automatic code splitting — every route is lazy-loaded with no React.lazy() boilerplate
  • Auto-imports for common React, React Router, and env hooks — zero import statements needed

Backend

  • API routes powered by Hono — plain functions or full Hono apps, colocated in src/app/api/
  • One handler, every runtime: Vite dev middleware, bini-server, or a bini-deploy-generated edge function — no code changes required between them
  • Environment variable loading with startup banners, across Node.js, Bun, Deno, and edge runtimes

Native

  • Desktop and mobile builds via Tauri — Windows, macOS, Linux, Android, and iOS from the same project
  • Native plugin wiring generated automatically from the web APIs you actually call
  • Code signing, bundle identifiers, and app icons handled at scaffold time

Developer Experience

  • Animated dev overlay with Shiki-highlighted error panels and clickable stack frames
  • TypeScript or JavaScript, Tailwind CSS v4, CSS Modules, or no styling — your choice at scaffold time
  • Oxlint + Oxfmt — 50–100× faster than ESLint and Prettier, pre-configured out of the box

Deployment

  • bini-deploy — a bundled CLI (npm run deploy) that generates hosting config for your chosen platform and pushes the project to GitHub
  • Static export with smart 404.html fallback for any static host
  • Hosting config generation for Netlify Edge Functions, Vercel, Cloudflare Workers, Node.js, and Deno

Requirements

| | | |---|---| | Node.js | >= 20.19.0 (required by Vite 8) |


CLI

npx create-bini-app@latest              # interactive
npx create-bini-app@latest my-app       # skip the name prompt
npx create-bini-app@latest my-app --typescript --tailwind --platform macos

| Flag | Description | |---|---| | --typescript / --javascript | Language | | --tailwind / --css-modules / --none | Styling | | --platform <target> | web (default) · windows · macos · linux · android · ios | | --app-name <name> | Display name — desktop/mobile app name and window title | | --sign / --nosign | Auto-confirm or skip code-signing setup | | --npm / --pnpm / --yarn / --bun | Force a package manager instead of auto-detecting | | --install / --no-install | Install dependencies without prompting | | --force | Overwrite an existing directory | | --version, -v / --help, -h | Print version / show help |

In non-interactive environments (CI, no TTY), prompts are skipped and defaults apply: TypeScript, Tailwind, web platform. Flags always override the defaults.


Project Structure

my-app/
├── src/
│   ├── app/
│   │   ├── api/                    ← API route handlers
│   │   │   └── hello.ts            → /api/hello
│   │   ├── layout.tsx              ← Root layout + metadata
│   │   ├── page.tsx                ← /
│   │   ├── not-found.tsx           ← Custom 404 (optional, folder-scoped)
│   │   ├── loading.tsx             ← Custom loading screen (optional, folder-scoped)
│   │   ├── error.tsx               ← Custom error boundary (optional, folder-scoped)
│   │   └── globals.css
│   ├── main.tsx                    ← Entry point
│   └── App.tsx                     ← Generated by bini-router — don't edit
├── public/
│   ├── favicon.ico
│   ├── apple-touch-icon.png
│   ├── og-image.png
│   ├── logo.png                    ← Source icon for native app icons
│   └── site.webmanifest
├── .oxlintrc.json
├── .oxfmtrc.json
├── vite.config.ts
└── package.json

not-found.tsx, loading.tsx, and error.tsx aren't scaffolded by default, but bini-router picks them up anywhere in src/app/ if you add them — see Routing.


Scripts

| Command | Description | |---|---| | dev | Start the Vite dev server with HMR | | build | Type-check, then bundle for production | | preview | Preview the production build | | type-check | tsc --noEmit | | lint / format / check | Oxlint / Oxfmt / both + type-check | | deploy | Run bini-deploy — generate hosting config (web) or just push (native), then push to GitHub | | export (web only) | Static SPA export | | start (web only) | Serve the production build via bini-server | | tauri:dev / tauri:build (desktop only) | Run or build the desktop app | | android / android:build, ios / ios:build (mobile only) | Run or build the mobile app |

deploy is present in every scaffold, regardless of platform — see Deployment for exactly what it does on each target. export and start are web-only; a desktop or mobile scaffold never sees them. See Platforms for the full command and requirement breakdown per target.


Routing

bini-router maps files in src/app/ to URLs. No router config, no manual React.lazy() — every route is code-split automatically.

src/app/
  page.tsx                 → /
  about.tsx                → /about
  about.mdx                → /about (MDX also works for pages/content routes)
  dashboard/
    layout.tsx              wraps /dashboard and its children
    page.tsx                → /dashboard
    [id]/page.tsx           → /dashboard/:id
  not-found.tsx             custom 404 (optional, folder-scoped)
  loading.tsx                custom loading screen (optional, folder-scoped)
  error.tsx                  custom error boundary (optional, folder-scoped)
// src/app/dashboard/[id]/page.tsx — useParams is auto-imported, no import needed
export default function Dashboard() {
  const { id } = useParams();
  const [count, setCount] = useState(0);
  return <h1>Dashboard {id}: {count}</h1>;
}

Layouts — root and nested — render children through <Outlet />:

// src/app/dashboard/layout.tsx
export default function DashboardLayout() {
  return (
    <div>
      <aside>Sidebar</aside>
      <main><Outlet /></main>
    </div>
  );
}

Export metadata from any layout to control <title>, Open Graph, Twitter cards, and icons. Root metadata is injected into index.html at build time; nested metadata updates document.title at runtime. It never ships to the client bundle.

export const metadata = {
  title: 'Dashboard',
  description: 'Your personal dashboard',
  openGraph: { images: [{ url: '/og-image.png', width: 1200, height: 630 }] },
};

Layouts with an <html> tag, or without a default export, are excluded from the route chain automatically. layout.tsx, not-found.tsx, loading.tsx, and error.tsx must be .tsx/.jsx/.ts/.js — MDX isn't supported for these, since they define app structure rather than content. page files and other flat/content routes support .mdx/.md in addition.

Folder-scoped boundaries

loading.tsx, not-found.tsx, and error.tsx all use the same "nearest wins" resolution as layouts: a file in a subfolder only affects that subfolder, and shadows (without deleting) the same file in any ancestor folder. A route without a closer match falls through to the nearest ancestor that has one, all the way up to the root, and to a built-in default if nothing exists anywhere.

// src/app/dashboard/error.tsx — only catches errors thrown inside /dashboard/*
export default function DashboardError({ error, reset }: { error: Error; reset: () => void }) {
  return (
    <div>
      <h2>Something broke in the dashboard</h2>
      <p>{error.message}</p>
      <button onClick={reset}>Try again</button>
    </div>
  );
}

API Routes

Files in src/app/api/ become endpoints. Export a plain function or a Hono app — both work identically in dev and in production.

// src/app/api/hello.ts — plain handler
export default function handler(req: Request) {
  return Response.json({ message: 'hello', method: req.method });
}
// src/app/api/users/[id].ts — Hono app, dynamic segment
import { Hono } from 'hono';

const app = new Hono();
app.get('/users/:id', (c) => c.json({ id: c.req.param('id') }));

export default app;

getEnv and requireEnv are auto-imported for reading environment variables server-side — no dotenv setup needed.

How it routes: in dev and preview, a Vite middleware matches /api/* against src/app/api/ with HMR on every save. In production on the node target, bini-server reads the same handlers directly at request time — no build step, no generated entry file. For other hosting targets, running bini-deploy (via npm run deploy) generates the platform-specific entry file that merges your Hono apps into one instance (netlify/edge-functions/api.ts, api/index.ts, etc.); plain handlers are wrapped automatically. In packaged desktop/mobile apps, the same Hono instance runs in-memory in the WebView — no server process, no code changes required.


Environment Variables

bini-env loads .env files automatically and prints which ones are active on every dev/preview start, in priority order: .env.local.env.[mode].local.env.[mode].env.

# .env
BINI_PUBLIC_API_URL=https://api.example.com   # client-side: import.meta.env.BINI_*
[email protected]               # server-side: requireEnv() in API routes
import.meta.env.BINI_PUBLIC_API_URL             // client code
const user = requireEnv('SMTP_USER');           // API routes — throws if missing, auto-imported

⚠️ Never put secrets in BINI_* or VITE_* variables — both prefixes are exposed to the browser bundle.


Production Server

Web target only. bini-server is a zero-dependency Node.js server — no Express, no Fastify — that serves dist/, proxies /api/* to your Hono handlers, and adds what vite preview doesn't: ETag/304 caching, graceful shutdown, body/handler timeouts, and automatic port fallback.

npm run build
npm start                 # PORT=8080 npm start to override the port

Override the default directories if needed: BINI_API_DIR (default src/app/api), BINI_DIST_DIR (default dist).


Static Export

Web target only. bini-export pre-renders every static route to its own index.html and strips server-only files, producing a dist/ that works on any static host.

npm run export             # vite build --mode export

Dynamic routes aren't pre-rendered — they resolve client-side via a generated 404.html: a copy of index.html if you have a custom not-found.tsx, otherwise a redirect script that preserves the path through sessionStorage. Works out of the box on GitHub Pages, Netlify, Vercel, Cloudflare Pages, S3 + CloudFront, Firebase Hosting, and Surge.


Platforms

One codebase, six targets. --platform picks which one you scaffold; each gets exactly the dependencies, scripts, and config it needs — nothing more. Every target also gets a deploy script for pushing the project to GitHub via bini-deploy — see Deployment for what it does on each one.

npx create-bini-app@latest my-app --platform macos
npx create-bini-app@latest my-app --platform android --app-name "My App" --nosign

Web

Overview — the default target. A standard Vite + React SPA with file-based routing and a Hono API layer.

Features

  • Zero-dependency production server (bini-server) and static export (bini-export)
  • bini-deploy generates hosting config for Netlify Edge, Vercel, Cloudflare Workers, Node.js, or Deno and pushes to GitHub

Commands

| Command | Description | |---|---| | npm run dev | Dev server with HMR | | npm start | Serve the production build | | npm run export | Static export | | npm run deploy | Generate hosting config for your chosen platform and push to GitHub |

Requirements — Node.js >= 20.19.0. Nothing else.


Windows

Overview — a native desktop binary running inside WebView2.

Features

  • Filesystem, clipboard, notifications, and dialogs via @tauri-apps/api, auto-wired by bini-native
  • Authenticode code signing, configurable at scaffold time or later

Commands

| Command | Description | |---|---| | npm run tauri:dev | Run in development mode | | npm run tauri:build | Build a distributable binary | | npm run tauri:icon | Regenerate icons from public/logo.png | | npm run deploy | Push the project to GitHub via bini-deploy |

deploy does not build, sign, or package the binary itself — run tauri:build first, then deploy to push source and any generated config to GitHub.

Requirements

  • Microsoft C++ Build Tools (download) — install with "Desktop development with C++"
  • Microsoft Edge WebView2 Runtime (download)

macOS

Overview — a native desktop binary running inside WKWebView.

Features

  • Same @tauri-apps/api access as Windows/Linux, auto-wired by bini-native
  • Ad-hoc signing for local runs, or Developer ID + notarization for distribution

Commands

| Command | Description | |---|---| | npm run tauri:dev | Run in development mode | | npm run tauri:build | Build a distributable binary | | npm run tauri:icon | Regenerate icons from public/logo.png | | npm run deploy | Push the project to GitHub via bini-deploy |

deploy does not build, sign, or notarize the app itself — run tauri:build (and your notarization step) first, then deploy to push to GitHub.

Requirements

  • Xcode Command Line Tools — xcode-select --install
  • Homebrew, then brew install gtk+3 webkit2gtk pkg-config
  • Full Xcode (Mac App Store) if you also plan to build for iOS

Linux

Overview — a native desktop binary running inside WebKitGTK, distributed as an AppImage.

Features

  • Same @tauri-apps/api access as Windows/macOS, auto-wired by bini-native
  • GPG-signed AppImage output, configurable at scaffold time or later

Commands

| Command | Description | |---|---| | npm run tauri:dev | Run in development mode | | npm run tauri:build | Build a distributable AppImage | | npm run tauri:icon | Regenerate icons from public/logo.png | | npm run deploy | Push the project to GitHub via bini-deploy |

Requirements — one of:

# Debian/Ubuntu
sudo apt install -y libwebkit2gtk-4.0-dev build-essential libssl-dev \
  libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev libxdo-dev pkg-config

# Fedora
sudo dnf install webkit2gtk4.0-devel openssl-devel gtk3-devel \
  libappindicator-gtk3-devel librsvg2-devel libxdo-devel pkg-config

# Arch
sudo pacman -S webkit2gtk base-devel openssl gtk3 libappindicator-gtk3 librsvg libxdo pkg-config

Android

Overview — a real native APK/AAB via Tauri's Android backend, not a WebView wrapper.

Features

  • Camera, filesystem, notifications, and geolocation auto-wired by bini-native
  • Back button, status bar, and splash screen configurable in src-tauri/gen/android
  • Release signing (keystore + keystore.properties), configurable at scaffold time or later

Commands

| Command | Description | |---|---| | npm run android | Run on an emulator or connected device | | npm run android:build | Build a release APK/AAB | | npm run deploy | Push the project to GitHub via bini-deploy |

deploy does not build a signed APK or submit to the Play Store — run android:build first, then deploy to push to GitHub. Store submission is manual.

Requirements

  • Java JDK 17 (JAVA_HOME set) — download
  • Android Studio, with SDK/Build Tools/NDK (ANDROID_HOME set) — download
  • Rust targets: rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android

iOS

Overview — a real native app via Tauri's iOS backend, running inside WKWebView. macOS + Xcode required.

Features

  • Same native plugin wiring story as Android
  • Xcode-managed automatic signing for local runs; manual certificate/profile signing for CI

Commands

| Command | Description | |---|---| | npm run ios | Run on the Simulator or a connected device | | npm run ios:build | Build the app | | npm run deploy | Push the project to GitHub via bini-deploy |

deploy does not build, sign, or submit to TestFlight/App Store — those remain manual (or CI-driven) steps; deploy only pushes the project source to GitHub.

Requirements

  • Xcode (Mac App Store) + Command Line Tools — xcode-select --install
  • CocoaPods — sudo gem install cocoapods
  • Rust targets: rustup target add aarch64-apple-ios x86_64-apple-ios aarch64-apple-ios-sim

Notes — iOS projects also get a bare "tauri": "npx @tauri-apps/cli" script in package.json. Xcode's build phase calls it directly (npm run tauri -- ios xcode-script ...), bypassing the commands above — builds triggered from inside Xcode fail with Missing script: "tauri" without it. Don't rename or remove it.


Developer Experience

Dev overlay. An animated status badge in the corner reflects loading/idle/error state live. On error, it expands into a Shiki-highlighted code frame with a clickable file link and filtered call stack. Disable with DISABLE_BINI_OVERLAY=true npm run dev.

Auto-imports. These are available in every file under src/app/ (including .mdx/.md) with no import statement:

| From | Symbols | |---|---| | react | useState useEffect useRef useMemo useCallback useContext createContext useReducer useId useTransition useDeferredValue | | react-router-dom | Link NavLink useNavigate useParams useLocation useSearchParams Outlet | | bini-env | getEnv requireEnv |

A manual import of any of these is detected and injection is skipped — no duplicates.

Linting & formatting. Oxlint and Oxfmt ship pre-configured (.oxlintrc.json, .oxfmtrc.json) — Rust-based, 50–100× faster than ESLint/Prettier, no setup required.

npm run lint     # Oxlint
npm run format   # Oxfmt
npm run check    # both + type-check — CI-ready

Deployment

bini-deploy is bundled into every scaffold and exposed as npm run deploy. What it does depends on the platform:

  • Web — prompts for a hosting target (node, netlify, vercel, cloudflare, or deno), generates that platform's entry file and any hosting config (netlify.toml, vercel.json, wrangler.toml) directly in your project, then commits and pushes everything to the GitHub repository you specify.
  • Windows / macOS / Linux / Android / iOS — generates no hosting config (there's nothing to host). It commits and pushes the project as-is to GitHub, and prints the manual next-step commands for that platform (clone, install, build). It does not build, sign, notarize, or submit anything to an app store — those remain separate, manual (or CI) steps.
npm run deploy                                              # interactive
npx bini-deploy --platform web --hosting vercel --repo https://github.com/you/app --yes   # non-interactive

| Platform | File generated | |---|---| | netlify | netlify/edge-functions/api.ts + netlify.toml | | vercel | api/index.ts + vercel.json | | cloudflare | worker.ts + wrangler.toml | | deno | server/index.ts | | node | (none — bini-server reads src/app/api/ directly) |

Vercel and Deno Deploy read their entry file before running your build — bini-deploy commits the generated file for you, so it's there before CI runs.

Netlify example, generated automatically by bini-deploy when you choose it:

# netlify.toml
[build]
  command = "vite build"
  publish = "dist"

[[edge_functions]]
  path = "/api/*"
  function = "api"

[[redirects]]
  from = "/*"
  to = "/index.html"
  status = 200

Edge Functions run on Deno, not Node — packages depending on Node built-ins (fs, nodemailer) won't work there.

Node.js (Railway, Render, Fly.io, a VPS): npm run build && npm start. bini-server reads handlers directly from src/app/api/, so deploy the whole project — not just dist/. Use pm2 on a bare VPS.

GitHub Pages / subpaths — set base: '/my-repo/' in vite.config.ts, then npm run export for a fully pre-rendered, subpath-aware dist/.


Packages

| Package | Role | |---|---| | bini-router | File-based routing, layouts, MDX/Markdown pages, folder-scoped loading/not-found/error, metadata, auto-imports, dev/preview API routing | | bini-deploy | Generates hosting config for web targets and pushes the project to GitHub, for every platform | | bini-native | Automatic Tauri plugin wiring for desktop and mobile | | @tauri-apps/cli | Compiles the app to a native Windows/macOS/Linux/Android/iOS binary | | bini-server | Zero-dependency production server (web only) | | bini-export | Static SPA export (web only) | | bini-overlay | Dev error overlay | | bini-env | Environment variable loading | | hono | API route runtime | | vite | Dev server + Rolldown bundler | | react / react-router-dom | UI + routing | | oxlint / oxfmt | Linting + formatting |

Most packages install at latest; typescript is pinned to ^6.0.0 (TypeScript 7 shipped without a public compiler API, which breaks several build tools in this stack).


Resources


MIT © Binidu Ranasinghe