bini-deploy
OfficialZero-config deployment for Bini.js projects - web, desktop, and mobile, all from one CLI.
Overview
bini-deploy scans your project, generates the right hosting configuration for your target platform, and pushes it straight to GitHub. No YAML spelunking, no platform-specific docs to read first.
Features
Web Hosting
Netlify, Vercel, Cloudflare Workers, Deno Deploy. Picks adapter, writes config, wires API routes.
File-based API
Drop files in src/app/api/, bini-deploy scans and mounts each as route with dynamic segments.
Automatic CORS
API routes get permissive CORS headers out of the box on every non-Node adapter.
Native Support
Windows, macOS, Linux, iOS, Android via Tauri with tailored next-step instructions.
Git Built-in
Init repo if needed, sets up identity and auth if missing, commits and pushes.
Smart Diagnostics
Push failures diagnosed - bad credentials, repo not found, or diverged history with accurate recovery.
Installation
$ npm install --save-dev bini-deploy
Quick Start
Interactive mode - just run it and answer the prompts:
$ npx bini-deploy
bini-deploy will guide you through two prompts:
? Select your target platform:> WebWindowsmacOSiOSLinuxAndroid↑↓ navigate • ⏎ select
? Select hosting provider:> Node.js (default - bini-server)NetlifyVercelCloudflare WorkersDeno Deploy↑↓ navigate • ⏎ select
Non-interactive mode - for scripts and CI:
$ npx bini-deploy --platform web --hosting vercel --repo https://github.com/you/your-app --yes
Usage
$ npx bini-deploy [options]
| Flag | Description |
|---|---|
| --platform <type> | web, windows, macos, ios, linux, android |
| --hosting <name> | node (default), netlify, vercel, cloudflare, deno (web only) |
| --repo <url> | GitHub repo URL, e.g. https://github.com/you/app |
| --generate-entry <host> | Generate production entry file only |
| --yes, -y | Skip prompts and use flags |
| --help, -h | Show usage information |
Examples:
$ npx bini-deploy --platform web --hosting vercel --repo https://github.com/you/your-app --yes $ npx bini-deploy --platform windows --repo https://github.com/you/your-app -y $ npx bini-deploy --generate-entry netlify $ npx bini-deploy
Supported Hosting Providers
| Provider | Runtime | Config Generated |
|---|---|---|
| Node.js (default) | Node (bini-server) | None - bini-server handles build/serve |
| Netlify | Edge Functions (Deno) | netlify.toml + netlify/edge-functions/api.ts |
| Vercel | Node.js Runtime | vercel.json + api/index.ts |
| Cloudflare Workers | Workers | wrangler.toml + worker.ts |
| Deno Deploy | Deno | server/index.ts |
bini-server, a zero-dependency production server. Choosing it skips config generation entirely.API Routes
Any file in src/app/api/ becomes an API route. Nested folders map to URL segments, bracket segments become dynamic params, and spread segments become wildcards:
export default async function handler(req) {
const id = new URL(req.url).pathname.split('/').pop();
return { id, name: 'Ada Lovelace' };
}package.json has "type": "module", every relative import must include its file extension explicitly - ./utils.js not ./utils - or deployed function will crash with ERR_MODULE_NOT_FOUND.Hono Support
If your route file imports from hono, bini-deploy detects it and mounts it as a full Hono app:
import { Hono } from 'hono';
const app = new Hono();
app.get('/', (c) => c.json({ message: 'Hello from Hono!' }));
app.post('/', async (c) => {
const body = await c.req.json();
return c.json({ received: body });
});
export default app;How it Works
- Scan - scans your
src/app/api/directory for route files - Generate - creates platform-specific entry file and configuration
- Clean - removes leftover files from previously selected platform
- Push - commits and pushes everything to GitHub
- Deploy - hosting platform automatically deploys from GitHub
Git Behavior
- Existing remote - uses it without modification
- New projects - adds provided URL as origin
- Always main - automatically handles branch naming, never pushes to master
- Git identity - prompts for
user.name/user.emailonce if not set, local only - GitHub auth - prompts for username + PAT if push rejected, saves via credential store
- Remote-ahead recovery - fetches and merges remote history automatically with
--allow-unrelated-histories -X ours
Requirements
- Node.js >= 18
- Vite >= 6
- A GitHub repository (created ahead of time)
- git available on PATH