yabasha/cas
@yabasha/cas is a command-line interface tool designed to instantly scaffold professional-grade, AI-ready monorepos. It is tailored for developers building production SaaS applications who require a standardized, high-performance foundation built on the Composable AI Stack. By providing interactive prompts and CLI-driven configuration, the tool allows users to selectively integrate complex architectural components like background workers, external API gateways, and automated evaluation harnesses without manual setup.
Technically, the project emphasizes a hardened "production-first" philosophy, prioritizing type safety and runtime security. The generated monorepo leverages Bun, Turborepo, Next.js 16, and Convex, utilizing Zod for robust environment and schema validation across the entire workspace. Notable design highlights include a dedicated @acme/ai package that implements guardrail patterns and automatic Langfuse tracing, as well as a hardened ElysiaJS gateway that features structured logging, CSP middleware with nonces, and secure rate limiting.
This project is an excellent starting point for developers who want to bypass the configuration overhead often associated with complex AI-integrated apps. It balances flexibility with strict conventions, ensuring that projects remain maintainable through features like verified dependency pinning, automated version checks, and built-in Stripe webhook handling. Whether you are bootstrapping a minimal service or a complex, event-driven AI platform with automated feedback loops, @yabasha/cas provides a stable and highly opinionated baseline.
- Stars
- 0
- Forks
- 0
- Language
- TypeScript
- Updated
- 1d ago
§ Readme
Edit on GitHub ↗@yabasha/cas
A CLI scaffolding tool for the Composable AI Stack — quickly bootstrap a Bun + Turborepo + Convex monorepo for AI-powered applications, with optional components you can opt into.
What you get
The template the CLI clones is a hardened, production-ready monorepo for AI-integrated SaaS apps. Highlights from the latest cut:
- Env validation via
@acme/config— a Zod schema withNODE_ENV-conditional required fields and a frozenenvexport. - Convex Auth (
@convex-dev/authwith Password provider) plusrequireUser/requireUserDocguards. - Stripe webhook handler at
POST /stripe/webhookwith async signature verification (Web Crypto), idempotency markers written after successful processing, and Stripe-friendly retries on failure. - Hardened Elysia gateway with
pinostructured logging (header redaction), CORS,timingSafeEqualbearer guard, in-memory rate limiter with periodic sweep, and SIGINT/SIGTERM graceful shutdown. - CSP middleware with per-request nonces,
'strict-dynamic', dev-only'unsafe-eval', andupgrade-insecure-requestsgated to production. @acme/aiguardrail pattern (runWithGuardrails) — Vercel AI SDK + Zod input/output schemas + moderation hook + automatic Langfuse tracing.- BullMQ worker with Convex scheduled functions for cron-like jobs.
- Eval harness (
@acme/evals) with Langfuse scoring and non-zero exit on regression.
Layout
apps/web— Next.js 16 (App Router) + Tailwind 4 + shadcn/ui, CSP middlewareapps/convex(always) — Convex backend, Convex Auth, Stripe webhook, idempotency tableapps/api(optional) — Hardened ElysiaJS API gateway on Bunapps/worker(optional) — BullMQ background worker & eval runner (Bun)packages/ai(always) — Vercel AI SDK + Langfuse tracing + guardrail patternpackages/config(always) — Zod env schema + dotenv loaderpackages/prompts(always) — versioned prompt templatespackages/schemas(always) — Zod schema definitionspackages/shared(always) — shared utilitiespackages/evals(optional) — eval harness with Langfuse scoringtooling/scripts/check-versions.ts— fails CI if pinned versions drift
Why
packages/configandpackages/aiare always included: they are workspace dependencies ofapps/convex(env validation) andapps/worker(LLM calls). Removing them would produce a broken scaffold.
Pinned tech stack (template defaults)
| Tool | Version |
|---|---|
| Bun | 1.3.7 |
| Turborepo | 2.7.6 |
| TypeScript | 5.9.3 |
| Next.js | 16.1.6 (App Router) |
| React | 19.2.4 |
| Tailwind CSS | 4.1.18 |
| ElysiaJS | 1.4.22 |
| Convex | 1.31.6 |
| ESLint | 9.39.2 |
| Prettier | 3.8.1 |
The template ships with bun run check:versions so CI can fail if any pinned dependency drifts.
Features
- Interactive & non-interactive modes — guided prompts or CLI flags
- Component selection — opt into:
- API Service (
apps/api, hardened ElysiaJS on Bun) - Background Worker (
apps/worker, BullMQ + Convex scheduled functions) - AI Evaluations (
packages/evals, Langfuse-scored)
- API Service (
- Template customization — replaces project name, author, license, and year across all
package.jsonfiles - Multi-package-manager support —
bun(default),npm,yarn,pnpm - Dry-run mode — preview the plan without writing anything
- Git initialization — fresh repo by default (
--no-gitto skip) - Update notifications — checks npm for newer versions of
@yabasha/cas
Installation
# Global installation with bun (recommended)
bun add -g @yabasha/cas
# Or with npm (Node.js fallback)
npm install -g @yabasha/cas
Usage
Interactive Mode
Run without arguments to use the interactive prompt:
cas init
This will guide you through:
- Project name
- Author name
- License selection
- Component selection
- Package manager choice
Non-interactive Mode
Provide all options via CLI flags:
# Create with all optional components
cas init my-project --all
# Create minimal project (no optional components)
cas init my-project --minimal
# Select specific components
cas init my-project --with-api --with-worker
# Full customization
cas init my-project \
--author "Your Name" \
--license MIT \
--package-manager bun \
--with-api \
--with-evals
Using bunx/npx
# With bun (recommended)
bunx @yabasha/cas init my-project
# With npm (Node.js fallback)
npx @yabasha/cas init my-project
CLI Options
| Option | Alias | Description |
|---|---|---|
--dir <path> | -d | Target directory (defaults to project name) |
--author <name> | -a | Author name for package.json |
--license <license> | -l | License type |
--with-api | Include hardened ElysiaJS API service (apps/api) | |
--with-worker | Include BullMQ background worker (apps/worker) | |
--with-evals | Include AI evaluations (packages/evals) | |
--with-config | Deprecated: packages/config is always included (required by apps/convex) | |
--all | Include all optional components | |
--minimal | Exclude all optional components (packages/config and packages/ai are always included) | |
--force | -f | Overwrite existing directory |
--no-install | Skip dependency installation | |
--no-git | Skip git repository initialization | |
--package-manager <pm> | -p | Package manager: bun (default), npm, yarn, pnpm |
--dry-run | Preview changes without creating files |
Supported Licenses
MIT(default)Apache-2.0ISCGPL-3.0BSD-3-ClauseUNLICENSED
Examples
Create a full-stack AI project
cas init my-ai-app --all --author "Jane Doe" --license MIT
Create API-only project
cas init my-api --with-api --minimal
Preview what would be created
cas init my-project --all --dry-run
Force recreate existing project
cas init my-project --force --all
Skip automatic dependency installation
cas init my-project --all --no-install
Project Structure
After scaffolding with --all, you'll get:
my-project/
├── apps/
│ ├── web/ # Next.js 16 + Tailwind 4 + shadcn/ui + CSP middleware
│ ├── convex/ # Convex + Convex Auth + Stripe webhooks (primary backend)
│ ├── api/ # Hardened Elysia gateway (optional)
│ └── worker/ # BullMQ + Convex scheduled functions (optional)
├── packages/
│ ├── ai/ # Vercel AI SDK + Langfuse tracing + runWithGuardrails
│ ├── config/ # Zod env schema + dotenv loader
│ ├── prompts/ # Versioned prompt templates
│ ├── schemas/ # Zod schema definitions
│ ├── shared/ # Shared utilities
│ └── evals/ # Eval harness with Langfuse scoring (optional)
├── tooling/
│ └── scripts/ # check-versions and other repo tooling
├── .env.example # Required env surface (Convex, Stripe, LLM, Langfuse, Redis)
├── turbo.json
├── package.json
├── CLAUDE.md # Guidance for Claude / Claude Code
├── AGENTS.md
└── README.md
Environment variables
After scaffolding, copy .env.example to .env and fill in:
| Variable | Required | Notes |
|---|---|---|
CONVEX_DEPLOYMENT, NEXT_PUBLIC_CONVEX_URL | yes | From bunx convex dev output |
NEXT_PUBLIC_APP_URL, SITE_URL | yes | Web origin (CORS + CSP + Auth) |
STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET | yes (if billing) | Required by the Convex webhook handler |
API_BEARER_TOKEN, API_PORT | if apps/api | Elysia bearer guard + listen port |
OPENAI_API_KEY, ANTHROPIC_API_KEY | yes (LLM) | Consumed by @acme/ai |
LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY, LANGFUSE_BASE_URL | yes (tracing) | Default base URL is https://cloud.langfuse.com |
REDIS_URL | if apps/worker | BullMQ connection string |
AUTH_GITHUB_ID, AUTH_GITHUB_SECRET | optional | External OAuth provider |
WEBHOOK_TOLERANCE_SECONDS, LOG_LEVEL | optional | Hardening tunables |
Convex secrets live in the Convex dashboard, not
.env. Usebunx convex env set <NAME> <VALUE>fromapps/convex.
Scaling the rate limiter (apps/api)
apps/api ships an in-memory rate limiter (src/middleware/rate-limit.ts) that's fine for single-instance deployments. For multi-worker/multi-region deployments, swap the backing store for Upstash or Redis:
bun add --filter=api @upstash/ratelimit @upstash/redis- Replace the
Mapinrate-limit.tswith an UpstashRatelimitinstance. - Set
UPSTASH_REDIS_REST_URLandUPSTASH_REDIS_REST_TOKEN.
The middleware exposes X-RateLimit-Backend: memory so you can verify which store is in use at runtime.
Programmatic API
You can also use the scaffolding functionality programmatically:
import { scaffold, validateProjectName, slugify } from '@yabasha/cas'
// Scaffold a new project
const result = await scaffold({
projectName: 'my-project',
dir: './my-project',
author: 'Your Name',
license: 'MIT',
withApi: true,
withWorker: true,
withEvals: false,
withConfig: true, // ignored — packages/config is always scaffolded
all: false,
minimal: false,
force: false,
noInstall: false,
noGit: false,
packageManager: 'bun',
dryRun: false,
})
if (result.success) {
console.log('Project created at:', result.dir)
}
// Validate project name (npm conventions)
const validation = validateProjectName('my-project')
if (!validation.valid) {
console.error(validation.message)
}
// Convert name to slug
const slug = slugify('My Project Name') // 'my-project-name'
Exported Functions
| Function | Description |
|---|---|
scaffold(options) | Main scaffolding function |
validateProjectName(name) | Validates project name against npm conventions |
slugify(name) | Converts a string to a valid package name |
printSuccessMessage(options) | Displays success message with next steps |
Development
Prerequisites
- Bun (recommended)
- Node.js 20+ (fallback)
Setup
# Clone the repository
git clone https://github.com/yabasha/cas.git
cd cas
# Install dependencies
bun install
# Build the project
bun run build
# Run in development mode
bun run dev
Scripts
| Script | Description |
|---|---|
bun run build | Build the CLI |
bun run dev | Watch mode with auto-rebuild |
bun run lint | Run ESLint |
bun run format | Format code with Prettier |
bun test | Run tests |
bun run test:watch | Run tests in watch mode |
Testing
# Run all tests
bun test
# Watch mode
bun run test:watch
Project Structure
src/
├── __tests__/ # Unit tests
├── args.ts # CLI argument parsing
├── banner.ts # ASCII banner display
├── cli.ts # Main CLI entry point
├── index.ts # Public API exports
├── prompts.ts # Interactive prompts
├── template.ts # Template processing logic
├── types.ts # TypeScript type definitions
└── utils.ts # Utility functions
Requirements
- Bun (recommended) or Node.js 20+ (fallback)
- Internet connection (for cloning the template repository)
- Git (for repository initialization)
Note: This CLI is built with full Bun support. Node.js is supported as a fallback runtime and will be automatically detected.
Related
- Composable AI Stack - The template repository
License
MIT
§ Cite this project
For papers, blog posts, & AI referencesBashar Ayyash. (2026). yabasha/cas [Computer software]. https://yabasha.dev/open-source/cas§ Related repositories
yabasha/monolith
This project provides a robust, scalable architecture for modern full-stack development by combining a Laravel 12 backend with a Next.js 16 frontend in a unified monorepo. It is designed for developers who value explicit structure, clear boundaries between application layers, and high-performance workflows. By organizing the core application code within an apps directory and isolating shared UI primitives in a packages workspace, it enables teams to build complex systems while maintaining a consistent design language.
- TypeScript
- 2 stars
- 0 forks
- updated 4mo ago
yabasha/composable-ai-stack
The Composable AI Stack (CAS) is a production-ready monorepo template designed for developers building AI-integrated SaaS applications. It provides a structured, modular foundation that abstracts the complexity of scaling from localized prototyping to robust enterprise deployments. By standardizing the integration of LLMs, database interactions, and billing logic, it enables teams to focus on core product features rather than boilerplate architecture.
- TypeScript
- 1 stars
- 0 forks
- updated 1d ago
yabasha/yabasha-gex
GEX is a versatile command-line interface tool designed to help developers audit, document, and manage their Node.js package environments. It provides a structured approach to generating reproducible reports for local projects and globally installed packages. By supporting multiple runtime environments—Node.js (npm), Bun, Yarn, and pnpm—it serves as a unified utility for teams needing to track dependency states, enforce license compliance, or simplify vulnerability auditing across diverse infrastructure.
- TypeScript
- 1 stars
- 0 forks
- updated 1d ago