clawfire
v0.6.20
Published
AI-First Firebase app framework — Speak. Build. Deploy.
Downloads
3,565
Maintainers
Readme
Clawfire
AI-First Firebase App Framework — Speak. Build. Deploy.
Clawfire lets you build Firebase apps by talking to AI. Define your API contracts with Zod, and get type-safe routing, auto-generated clients, security rules, and deployment — all from a single source of truth.
Features
- Contract-based API — Define input/output with Zod schemas. Runtime validation, type safety, and docs come for free.
- File-based Routing —
functions/routes/todos/create.tsbecomesPOST /api/todos/create. No configuration. - Page Routing —
app/pages/about.htmlbecomes/about. Layouts, components, and SPA navigation built in. - Layouts & Components —
_layout.htmlwraps pages via<slot />.<c-nav />insertsapp/components/nav.html. - SPA Navigation — Internal links swap page content without full reload. Tailwind CSS via CDN.
- Two-Port Dev Server — Frontend app on port 3000, API + Playground on port 3456. One command.
- Hot Reload — API, page, and CSS changes reload instantly. No manual refresh needed.
- API Playground — Interactive API explorer auto-generated from your route definitions.
- Auto Client Generation — Type-safe
api.todos.create({ title })client generated from your contracts. - Firebase-Native — Firestore, Auth, Functions, Hosting. Fully integrated, no alternatives needed.
- Security by Default — Input validation, CORS deny, rate limiting, XSS sanitization, log masking — all ON.
- Auto Security Rules — Firestore rules generated from model definitions.
- AI Skills — Six
/clawfire-*Claude Code commands to manage your entire project.
Quick Start
1. Create a New Project
mkdir my-app && cd my-app
npx clawfire init
npm install2. Start the Dev Server
npm run devThis starts two servers in a single process:
⚡ Clawfire Dev Server
─────────────────────────────────────
App : http://localhost:3000
API : http://localhost:3456/api/...
Playground : http://localhost:3456
Pages : ON (app/pages/)
Routes (5):
POST /api/health [public] Health check endpoint
POST /api/todos/create [public] Create a new todo
POST /api/todos/delete [public] Delete a todo
POST /api/todos/list [public] List all todos
POST /api/todos/update [public] Update a todo
Hot Reload : ON
Watching: functions/routes/, functions/schemas/, app/pages/, app/components/, public/3. Open in Your Browser
| URL | What You'll See | |-----|-----------------| | http://localhost:3000 | Your app (Todo starter) | | http://localhost:3456 | API Playground |
4. Test the API
# Via the API server directly
curl -s -X POST http://localhost:3456/api/health \
-H 'Content-Type: application/json' -d '{}' | jq
# Or via the frontend proxy (same result, no CORS issues)
curl -s -X POST http://localhost:3000/api/todos/create \
-H 'Content-Type: application/json' \
-d '{"title":"Learn Clawfire"}' | jqDev Server Architecture
Clawfire runs a two-port dev server in a single process:
DevServer (single process)
├─ PageCompiler (compiles app/pages/ + app/components/ → HTML)
├─ Frontend Server (port 3000)
│ ├─ Serves compiled pages (app/pages/ → routes)
│ ├─ Serves public/ directory (static assets)
│ ├─ Auto-injects HMR script into HTML
│ ├─ Proxies /api/* → API server (no CORS)
│ └─ SPA fallback with partial page loading
│
└─ API Server (port 3456)
├─ API routes at /api/*
├─ Playground UI at /
└─ SSE for live reloadKey behaviors:
- HMR auto-injection — Every HTML response gets a
<script>tag injected automatically. You never write SSE code. - CSS hot replace — Edit a
.cssfile inpublic/and see changes instantly without page reload. - API proxy — Your frontend can call
fetch('/api/todos/list')— the frontend server proxies it to the API server. No CORS configuration needed. - SPA fallback — Unknown paths serve
index.html, supporting client-side routing. - Playground — Always available at the API server root. Auto-discovers routes, shows auth levels, generates example payloads.
Custom Ports
npx clawfire dev --port=4000 --api-port=5000Or in clawfire.config.ts:
dev: {
port: 4000,
apiPort: 5000,
}Project Structure
my-app/
app/
pages/ File-based page routing (frontend)
_layout.html Root layout (wraps all pages via <slot />)
_404.html 404 error page
index.html Home page (/)
about.html /about page
todos/
index.html /todos page
components/ Reusable HTML components
nav.html <c-nav /> navigation bar
footer.html <c-footer /> page footer
functions/
store.ts In-memory data store (works without Firebase)
routes/ API route handlers (file-based routing)
health.ts → POST /api/health
todos/
list.ts → POST /api/todos/list
create.ts → POST /api/todos/create
update.ts → POST /api/todos/update
delete.ts → POST /api/todos/delete
schemas/ Firestore model definitions
todo.ts
index.ts Firebase Functions entry point (for deploy)
public/ Static assets (CSS, images, fonts)
generated/ Auto-generated files (DO NOT EDIT)
api-client.ts Typed API client
manifest.json API manifest
dev.ts Dev server entry point
clawfire.config.ts Configuration
firebase.json Firebase config
firestore.rules Firestore security rules
firestore.indexes.json Firestore indexes
CLAUDE.md Project guide for Claude AICore Concepts
Define an API
Every API endpoint is a file in functions/routes/ that exports a defineAPI contract:
// functions/routes/products/list.ts
import { defineAPI, z } from "clawfire";
export default defineAPI({
input: z.object({
category: z.string().optional(),
limit: z.number().default(20),
}),
output: z.object({
products: z.array(z.object({
id: z.string(),
name: z.string(),
price: z.number(),
})),
hasMore: z.boolean(),
}),
meta: {
description: "List products",
auth: "public",
tags: ["products"],
},
handler: async (input, ctx) => {
return { products: [], hasMore: false };
},
});Rules:
- All APIs are POST only — no HTTP method routing
inputandoutputmust bez.object({})meta.descriptionis requiredhandlermust beasync- File path = API path:
functions/routes/products/list.ts→POST /api/products/list
Define a Model
Models define Firestore collections and auto-generate security rules:
// functions/schemas/product.ts
import { defineModel } from "clawfire";
export const Product = defineModel({
collection: "products",
fields: {
name: { type: "string", required: true },
price: { type: "number", required: true },
category: { type: "string", enum: ["electronics", "clothing"] },
},
timestamps: true,
rules: {
read: "public",
create: "role",
createRoles: ["admin"],
update: "authenticated",
delete: "role",
deleteRoles: ["admin"],
ownerField: "userId",
},
});Error Handling
import { Errors } from "clawfire";
throw Errors.notFound("Product not found"); // 404
throw Errors.validation("Invalid input", err); // 400
throw Errors.forbidden("No access"); // 403
throw Errors.unauthorized("Login required"); // 401
throw Errors.conflict("Already exists"); // 409
throw Errors.rateLimited("Too many requests"); // 429Response format:
// Success
{ "data": { "products": [...], "hasMore": false } }
// Error
{ "error": { "code": "NOT_FOUND", "message": "Product not found" } }Auth Levels
Every API endpoint declares an auth level in meta.auth:
| Level | Description | Header Required |
|-------|-------------|-----------------|
| public | No authentication | None |
| authenticated | Must be logged in | Authorization: Bearer <token> |
| role | Specific role required | Bearer token + role match |
| reauth | Recent login required (5 min) | Bearer token + fresh |
meta: {
description: "Delete user account",
auth: "reauth", // Must have re-authenticated within 5 minutes
}Configuration
All settings in clawfire.config.ts:
import { configureClawfire } from "clawfire";
export default configureClawfire({
firebase: {
apiKey: "...",
authDomain: "myapp.firebaseapp.com",
projectId: "my-project",
appId: "1:123:web:abc",
},
server: {
region: "us-central1",
cors: ["https://myapp.web.app"],
rateLimit: 100,
},
security: {
validateInput: true,
safeHeaders: true,
maskLogs: true,
},
playground: {
enabled: true,
},
dev: {
port: 3000, // Frontend server
apiPort: 3456, // API server + Playground
},
});Production Deployment
Firebase Functions Entry Point
// functions/index.ts
import * as admin from "firebase-admin";
import * as functions from "firebase-functions";
import { createRouter, createAdminDB, createSecurityMiddleware } from "clawfire/functions";
admin.initializeApp();
const db = createAdminDB(admin.firestore());
const router = createRouter({
auth: admin.auth(),
cors: ["https://myapp.web.app"],
middleware: createSecurityMiddleware(),
});
// Register routes
import listProducts from "./routes/products/list";
router.register("/products/list", listProducts);
export const api = functions.https.onRequest((req, res) => {
router.handleRequest(req as any, res as any);
});Auto-Generated Client
// In your frontend code
import { api, configureClient } from "./generated/api-client";
import { getAuth } from "firebase/auth";
configureClient("https://us-central1-myapp.cloudfunctions.net", async () => {
const user = getAuth().currentUser;
return user ? user.getIdToken() : null;
});
// Fully typed — autocomplete and compile-time checking
const result = await api.products.list({ category: "electronics", limit: 10 });CLI Reference
clawfire init # Initialize a new project (starter template)
clawfire dev # Start dev server (frontend + API + Playground)
clawfire dev --port=4000 # Custom frontend port
clawfire dev --api-port=5000 # Custom API port
clawfire codegen # Generate route imports
clawfire playground # Generate standalone playground HTML
clawfire rules # Info about rules generation
clawfire help # Show helpAI Skills (Claude Code)
When using Claude Code, these slash commands are available:
| Command | What It Does |
|---------|-------------|
| /clawfire-init | Initialize project, connect Firebase, set up config |
| /clawfire-model | Create/modify Firestore models → auto-generates rules + indexes |
| /clawfire-api | Create/modify API endpoints → auto-generates typed client |
| /clawfire-auth | Configure auth policies, roles, guards |
| /clawfire-deploy | Deploy to Firebase (explicit request only) |
| /clawfire-diagnose | Detect missing indexes, rule denials, permission issues |
Package Exports
| Import Path | Contents |
|-------------|----------|
| clawfire | defineAPI, defineModel, z, Errors, configureClawfire, ClawfireError |
| clawfire/functions | createRouter, createAdminDB, verifyToken, createSecurityMiddleware |
| clawfire/client | createClientAuth |
| clawfire/admin | generateFirestoreRules, generateFirestoreIndexes, setUserRole |
| clawfire/codegen | generateClientCode, discoverRoutes, generateRouteImports |
| clawfire/playground | generatePlaygroundHtml |
| clawfire/dev | DevServer, startDevServer, FileWatcher, PageCompiler |
Security Defaults
All security features are ON by default:
| Feature | Default | Description |
|---------|---------|-------------|
| Input Validation | ON | Zod schema validation on every request |
| CORS | Deny all | Must explicitly allow origins |
| Rate Limiting | 100 req/min/IP | Per-endpoint configurable |
| XSS Sanitization | ON | < > auto-escaped in string inputs |
| Safe Headers | ON | X-Frame-Options, X-Content-Type-Options |
| Log Masking | ON | password, token, secret fields masked |
Dev vs Production
| | Dev Server | Production (Firebase) |
|--|-----------|----------------------|
| Frontend | localhost:3000 (static + HMR) | Firebase Hosting |
| API | localhost:3456 | Firebase Functions |
| Playground | Always on at :3456 | Configurable |
| CORS | Allow all (*) | Configured origins only |
| Rate Limiting | Disabled | Enabled |
| Auth | Optional / mockable | Firebase Auth |
| Hot Reload | Yes (API + CSS + HTML) | N/A |
Documentation
Full documentation is in the docs/ directory:
- Getting Started — 5-minute quickstart
- API Routes —
defineAPI, file-based routing, handlers - Models —
defineModel, Firestore collections, rules - Dev Server — Two-port architecture, HMR, Playground
- Authentication — Auth levels, tokens, roles
- Security — Middleware, rate limiting, CORS, sanitization
- Configuration — All config options and defaults
- Client Codegen — Auto-generated typed API client
- Deployment — Firebase deploy workflow
- CLI Reference — All CLI commands and flags
- Architecture — How everything fits together
- API Reference — Full TypeScript API reference
Tech Stack
| Layer | Technology | |-------|-----------| | Database | Firestore | | Auth | Firebase Auth | | Hosting | Firebase Hosting | | Backend | Firebase Functions | | Schema | Zod | | Language | TypeScript |
This stack is fixed by design. Clawfire is opinionated — one way to do things, done well.
License
MIT
