cloudflare workers hono angular saas
via PatrickJS/awesome-cursorrules
Full-stack SaaS on Cloudflare Workers with Hono APIs, Angular frontends, and enterprise integrations.
What is cloudflare workers hono angular saas?
This rule configures a complete SaaS stack combining Cloudflare Workers (Hono v4.12+), Angular 21+ frontends, D1/Neon databases, and production observability tools. Use it for building type-safe, scalable SaaS applications with strict TypeScript, RPC-style APIs, and enterprise security/auth patterns.
- Enforce strict TypeScript with Zod validation, inline Hono handlers for type inference, and typed RPC clients via hc<AppType>
- Configure Angular 21+ standalone components with signals, control flow syntax, and PrimeNG UI components
- Set up Drizzle v1 ORM with D1/Neon, batch APIs, and Zod schema generation for type safety
- Implement Clerk JWT auth with webhook sync, RBAC via org roles, and route-layer access control
- Define security headers (HSTS, CSP nonce-based, X-Frame-Options, COOP/COEP) and Turnstile CAPTCHA on all forms
- Establish TDD with Playwright E2E (6 breakpoints, axe-core a11y), Vitest unit tests, and Lighthouse/WCAG 2.2 AA quality gates
Applies to
File patterns this rule matches.
Rule definition (reference)
Source of truth, from the repository.
Cloudflare Workers + Hono + Angular SaaS
Full-stack SaaS on Cloudflare Workers with Hono API, Angular frontend, and enterprise integrations.
Stack
CF Workers+Hono v4.12+ | Angular 21+Ionic 8+PrimeNG 21 | D1/Neon | Drizzle v1 | Zod | Clerk Core 3 | Stripe | Inngest v4 | Resend | Bun 1.3 | Playwright v1.59+ | Vitest | ESLint+Prettier | PostHog | Sentry
TypeScript
- Strict mode, never
any(useunknown), preferinterfaceovertype readonlywhen not reassigned,undefinedovernull- Zod as source of truth for validation
- ESLint flat config (
eslint.config.ts) + typescript-eslint + Prettier
Hono API
- Inline handlers for RPC type inference (never separate controller files)
- Method chaining:
app.use().get().post()preserves types hc<AppType>(BASE_URL)for typed client@hono/zod-validatoron ALL request bodiesapp.onError()+app.notFound()centralized- Split large apps:
app.route('/path', subApp) - Error envelope:
{ error: string, code?: string, details?: unknown } createFactory<{ Bindings: Env }>()for reusable middleware chainsGET /healthreturns{ status, version, timestamp }
Angular
- Standalone only (no NgModules), Angular 21 zoneless by default
- Signals stable:
signal(),computed(),effect(),linkedSignal(),resource() HttpResourcefor data fetching- Control flow:
@if/@for/@switch/@defer(not*ngIf/*ngFor) - kebab-case files, one component per file,
providedIn: 'root' - PrimeNG for UI components
Drizzle v1
sqliteTablefor D1, plural snake_case tables$inferSelect/$inferInsertfor typescreateInsertSchema/createSelectSchemafromdrizzle-orm/zod- Batch API (not
BEGIN— D1 doesn't support transactions) - Prepared statements for repeated queries
CF Workers
- CPU limit: 10ms free / 30s paid
ctx.waitUntil()for async post-response workctx.passThroughOnException()for graceful degradation- Bindings typed via
Envinterface - D1 global read replication for latency reduction
- Workers Builds for native CI/CD (preview URLs per branch)
Inngest v4 (Background Jobs)
eventType('name', { schema: z.object({...}) })per-event (v4 breaking)inngest/cloudflareadapter +inngest.setEnvVars(c.env)for Workers- Step functions:
step.run(),step.sleep(),step.waitForEvent(),step.sendEvent() step.ai.infer()offloads inference (zero compute during wait)step.realtime.publish()for durable pub/sub- Each step idempotent, retried independently
Testing (TDD)
- Failing test FIRST, then implement
- Playwright for E2E: 6 breakpoints (375, 390, 768, 1024, 1280, 1920)
- Vitest for unit tests
- No sleeps — use
waitFor/toBeVisible() - Selectors:
data-testid> role > text - axe-core 0 violations
PROD_URLenv var for production testing
Security (OWASP Top 10:2025)
- Must: HSTS, CSP (nonce-based strict), X-Content-Type-Options, X-Frame-Options
- Must: Referrer-Policy, Permissions-Policy, COOP, COEP, CORP
- Remove: X-XSS-Protection, Expect-CT, Server, X-Powered-By
- Turnstile on all forms, Zod validation on all inputs
- Stripe webhooks: verify signature, deduplicate via KV
Auth (Clerk)
- JWT verified per-request (no session store)
- Webhook sync: Clerk → D1 for user data
- RBAC: Clerk org roles for org-scoped, D1 for app-level
- Route layers: public → auth-only → role-gated → owner-only
Quality
- Lighthouse: a11y ≥95, perf ≥75
- WCAG 2.2 AA compliance
- LCP ≤2.5s, CLS ≤0.1, INP ≤200ms
- JS ≤200KB gz, CSS ≤50KB gz
- Functions ≤50 lines, cyclomatic complexity ≤10
Deploy
npx wrangler deploy && curl -sX POST \
"https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/purge_cache" \
-H "Authorization: Bearer ${CF_API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"purge_everything":true}'
Hono Worker Starter
import { Hono } from 'hono';
import { secureHeaders } from 'hono/secure-headers';
import { cors } from 'hono/cors';
interface Env {
DB: D1Database;
KV: KVNamespace;
AI: Ai;
TURNSTILE_SECRET: string;
}
const app = new Hono<{ Bindings: Env }>();
app.use('*', secureHeaders());
app.use('/api/*', cors({ origin: ['https://yourdomain.com'] }));
app.get('/health', (c) => c.json({ status: 'ok', timestamp: new Date().toISOString() }));
export default app;
Related rules
Senior full-stack TypeScript, React, Node.js guidance with clean architecture, testing, and WHY-oriented reasoning.
Quantitative factor research skills for designing, evaluating, and mining alpha factors in equities markets.
Android development with Jetpack Compose, clean architecture, and Material Design 3.
Angular development with Novo Elements UI library using standalone components.
Expert Angular 18 + TypeScript development with Jest, emphasizing clean code and performance.
Manage Kubernetes clusters, add-ons, stacks, and credentials via the Ankra CLI platform.