create-binsby
v1.0.18
Published
Scaffold a Binsby framework project.
Readme
create-binsby
Interactive project scaffolder for Binsby. Generates a new Binsby application with the correct directory structure, configuration files, and entry points.
Usage
pnpm create binsby
# or
npx create-binsby
# With a project name and defaults (no prompts)
pnpm create binsby my-app --yes
# Skip the install step
pnpm create binsby my-app --yes --skip-installNo installation required — use directly via package manager's create command.
CLI flags
| Flag | Effect |
|------|--------|
| [project-name] | Positional argument. When given, replaces the "Project name" prompt. |
| -y, --yes | Skip all prompts and use defaults (pnpm, path aliases, production hardening, no plugins). |
| --skip-install | Don't run the package manager install after scaffolding. |
| -h, --help | Print usage. |
The scaffolder aborts if the target directory exists and is non-empty.
Interactive prompts
| Prompt | Type | Options | Default | Description |
|--------|------|---------|---------|-------------|
| Project name | text | free text | current directory name or my-binsby-app | Directory name and package.json name |
| Package manager | select | pnpm, npm, yarn, bun | pnpm | Used for the auto-install step |
| Use path aliases? | confirm | yes / no | yes | Enables paths mapping in tsconfig.json |
| Path alias prefix | text | free text (shown only when path aliases enabled) | @/ | Prefix for path aliases (e.g. @/* maps to ./src/*). Automatically normalized to include @ prefix and / suffix |
| Production hardening? | confirm | yes / no | yes | Generates a production-grade server.ts with validateEnv, structured logger, Redis-backed rate limit store, and dependency probes. Adds @bgunnarsson/binsby-cache-redis + ioredis and emits src/shared/lib/redis.server.ts |
| Optional plugins | multiselect | umbraco, cms, sentry, bugsnag, gtm, storybook | none | Adds the selected @bgunnarsson/binsby-plugin-* packages. Storybook lands in devDependencies; the rest in dependencies. Wiring is left to the user |
After file generation, the scaffolder runs install automatically and prints next steps:
cd <project-name>
pnpm run devWhat it generates
Running the scaffolder creates the following structure:
<project-name>/
├── public/ # Static assets
├── src/
│ ├── app/
│ │ ├── api/ # File-based API routes (Hono handlers)
│ │ ├── server.ts # Server entry point
│ │ ├── entry.client.tsx # Client hydration entry
│ │ └── +path.server.tsx # Default catch-all SSR route
│ ├── features/ # Feature modules
│ ├── middleware/
│ │ └── meta.ts # Request/envelope meta middleware
│ ├── shared/
│ │ └── styles/
│ │ └── main.css # Tailwind entry
│ └── views/
│ ├── layouts/
│ │ ├── base.tsx # Default layout
│ │ └── rules.ts # Path → layout match rules
│ ├── Frontpage.server.tsx
│ ├── Error404.server.tsx
│ ├── Error500.server.tsx
│ └── index.ts # Template registry (used by pickTemplate)
├── .gitignore
├── .env.example # When production hardening is enabled
├── binsby.config.ts # Framework configuration
├── package.json
├── tsconfig.json
└── index.html # HTML templateGenerated file details
binsby.config.ts — Framework configuration with styles: 'tailwind', cache policy, server settings, layouts (rules + sourceDir/compiledDir), file-based API config, actions, banner, and a globalMiddlewares array wired with metaMiddleware.
src/app/server.ts — Server entry point. Imports config and starts either the dev or production server based on NODE_ENV. With production hardening enabled, the production branch runs validateEnv for REDIS_URL/PORT, dynamically imports redis.server.ts and @bgunnarsson/binsby-cache-redis/rate-limit after env validation, attaches a redis DependencyProbe, and wires a structured logger plus request/response observability hooks into the server options.
src/shared/lib/redis.server.ts (production hardening only) — ioredis singleton with enableOfflineQueue: false, exponential-backoff retry capped at 30s, and throttled error logging.
src/app/entry.client.tsx — Client entry. Installs client-side navigation, route progress bar, and islands hydration.
src/app/+path.server.tsx — Catch-all SSR route. Resolves a page for the current pathname (stub resolvePage function — replace with your CMS or filesystem lookup), uses pickTemplate(views, page.type) to pick the matching React component, builds an envelope with ensureEnvelope, and falls back to Error404 / Error500 on miss / throw.
src/views/Frontpage.server.tsx — Default homepage template. Receives an Envelope-shaped data prop.
src/views/Error404.server.tsx, Error500.server.tsx — Error templates rendered by the catch-all route on miss / throw.
src/views/index.ts — Template registry exporting views (used by pickTemplate) and a TemplateKey type.
src/views/layouts/base.tsx — Default Layout that wraps the rendered element/HTML in a #__binsby_main container.
src/views/layouts/rules.ts — LayoutRule[] selecting which layout(s) apply to which paths. Default rule matches everything to base.
src/middleware/meta.ts — metaMiddleware that builds a request object from ctx.c.req (with resolvePublicOrigin fallback for relative URLs) and writes request + meta (pathname, locale, method, url, host, query) onto both ctx.state and the response envelope.
src/shared/styles/main.css — Tailwind entry (@import "tailwindcss").
index.html — HTML shell with SSR outlet, preload, and stylesheet link for /main.min.css.
tsconfig.json — Strict TypeScript config targeting ES2022 with Bundler module resolution, JSX support, and incremental builds. When path aliases are enabled, includes the configured paths mapping.
Generated dependencies
Runtime dependencies
| Package | Description |
|---------|-------------|
| @bgunnarsson/binsby-actions | Server action discovery |
| @bgunnarsson/binsby-document | SSR document shaping |
| @bgunnarsson/binsby-islands | Islands registry and hydration |
| @bgunnarsson/binsby-middleware | Render pipeline middleware |
| @bgunnarsson/binsby-router | Routing and render context |
| @bgunnarsson/binsby-server | Dev and production server runtime |
| react | UI library |
| react-dom | React DOM renderer |
Dev dependencies
| Package | Description |
|---------|-------------|
| @bgunnarsson/binsby-vite | Shared Vite config (SWC + React) |
| @types/node | Node.js type definitions |
| @types/react | React type definitions |
| @types/react-dom | React DOM type definitions |
| cross-env | Cross-platform environment variables |
| hono | Lightweight web framework (API routes) |
| tsx | TypeScript execution for dev server |
| typescript | TypeScript compiler |
| vite | Build tool |
Tailwind dependencies
Tailwind CSS is included by default. The following dev dependencies are always added:
| Package | Description |
|---------|-------------|
| @bgunnarsson/binsby-plugin-tailwind | Binsby Tailwind integration |
| @tailwindcss/cli | Tailwind CSS CLI |
| tailwindcss | Tailwind CSS framework |
A tw:dev script is also generated for Tailwind watch mode.
Conditional dependencies (production hardening)
When production hardening is enabled, these runtime dependencies are added:
| Package | Description |
|---------|-------------|
| @bgunnarsson/binsby-cache-redis | Redis-backed rate-limit store (and optionally fragment / fetch cache) |
| ioredis | Redis client used by the singleton in src/shared/lib/redis.server.ts |
Conditional dependencies (plugins)
Selected from the Optional plugins multiselect. Each adds the matching @bgunnarsson/binsby-plugin-* package — runtime for everything except Storybook, which is a devDependency:
| Plugin | Package | Location |
|--------|---------|----------|
| Umbraco | @bgunnarsson/binsby-plugin-umbraco | dependencies |
| Headless CMS | @bgunnarsson/binsby-plugin-binally | dependencies |
| Sentry | @bgunnarsson/binsby-plugin-sentry | dependencies |
| Bugsnag | @bgunnarsson/binsby-plugin-bugsnag | dependencies |
| Google Tag Manager | @bgunnarsson/binsby-plugin-gtm | dependencies |
| Storybook | @bgunnarsson/binsby-plugin-storybook | devDependencies |
Scaffolder dependencies
@clack/prompts— interactive terminal promptsexeca— runs the package manager install subprocesspicocolors— terminal colours for output
