# codehooks-js

The official JavaScript/TypeScript library for [Codehooks.io](https://codehooks.io) — the agent-native backend platform. A complete backend — API routes, NoSQL database, key-value store, worker queues, cron jobs, and static asset hosting — in a single import.

## Why Codehooks?

**Single Cohesive Library** – REST routes, NoSQL database, key-value store, queues, scheduled jobs, file storage, and real-time APIs. One library, one pattern, everything works together.

**Zero Infrastructure Assembly** – No AWS/GCP service configuration. No API Gateway + Lambda + DynamoDB + SQS wiring. Write code and deploy — the platform handles everything else.

**AI Agent Native** – The entire lifecycle is CLI-native. Any tool that can run shell commands — Claude Code, Cursor, Codex, Cline — can autonomously create, deploy, verify, and iterate on a production backend.

**Sub-5-Second Deploys** – Your agent can iterate 50 times in the time it takes other platforms to deploy once.

**Flat-Rate Pricing** – Unlimited compute included. No per-request fees, no surprise bills.

## Quick Start

Install the [Codehooks CLI](https://codehooks.io/docs/cli):

```shell
npm install -g codehooks
```

Create a new project and install the library:

```shell
codehooks create myproject
cd myproject
npm install codehooks-js
```

## AI Agent Setup

### Claude Code Plugin (Recommended)

```
/plugin marketplace add RestDB/codehooks-claude-plugin
/plugin install codehooks@codehooks
```

Then use `/codehooks:backend` to start building.

### Built-in AI Prompt

```bash
coho prompt                 # Display the Codehooks development prompt
coho prompt | pbcopy        # Copy to clipboard (macOS)
```

### MCP Server

For tools without terminal access (Claude Desktop, Cline, Zed): [codehooks-mcp-server](https://github.com/RestDB/codehooks-mcp-server). Always prefer the CLI when available.

## REST API Example

```javascript
import { app, Datastore } from 'codehooks-js';

// REST API routes
app.get('/hello', (req, res) => {
  res.json({ message: 'Hello World!' });
});

// Store and query data
app.post('/items', async (req, res) => {
  const conn = await Datastore.open();
  const result = await conn.insertOne('items', req.body);
  res.json(result);
});

// Auto-generate CRUD REST API for any collection
app.crudlify();

export default app.init();
```

## Webhook Handler Example

Handle incoming webhooks with signature verification and reliable background processing:

```javascript
import { app, datastore } from 'codehooks-js';
import crypto from 'crypto';

// Webhook endpoint with HMAC signature verification
app.post('/webhooks/incoming', async (req, res) => {
  const signature = req.headers['x-webhook-signature'];
  const secret = process.env.WEBHOOK_SECRET;

  // Use rawBody for signature verification (preserves exact bytes)
  const expectedSig = crypto
    .createHmac('sha256', secret)
    .update(req.rawBody)
    .digest('hex');

  if (signature !== expectedSig) {
    return res.status(401).json({ error: 'Invalid signature' });
  }

  // Store the webhook event
  const conn = await datastore.open();
  const event = await conn.insertOne('webhook_events', {
    payload: req.body,
    received: new Date()
  });

  // Queue for reliable background processing
  await conn.enqueue('processWebhook', { eventId: event._id });

  res.json({ received: true });
});

// Background worker with automatic retries
app.worker('processWebhook', async (req, res) => {
  const { eventId } = req.body.payload;
  const conn = await datastore.open();

  const event = await conn.getOne('webhook_events', eventId);
  console.log('Processing webhook:', event.payload);

  // Your processing logic here

  res.end();
});

export default app.init();
```

## TypeScript Support

Full TypeScript support with strong types:

```typescript
import { app, datastore, httpRequest, httpResponse } from 'codehooks-js';

app.post('/webhooks/github', async (req: httpRequest, res: httpResponse) => {
  const event = req.headers['x-github-event'];
  const payload = req.body;

  const conn = await datastore.open();
  await conn.insertOne('github_events', {
    event,
    payload,
    timestamp: new Date()
  });

  res.json({ status: 'ok' });
});

export default app.init();
```

## OpenAPI Documentation

Automatically generate interactive API documentation with Swagger UI:

```javascript
import { app } from 'codehooks-js';
import { z } from 'zod';

const userSchema = z.object({
  name: z.string().min(1).describe('User name'),
  email: z.string().email().describe('Email address'),
  role: z.enum(['admin', 'user']).default('user')
});

app.openapi({
  info: { title: 'My API', version: '1.0.0' }
});

app.crudlify({ users: userSchema });

export default app.init();
```

After deploying, visit `/docs` for Swagger UI or `/openapi.json` for the spec.

Supports **Zod**, **Yup**, and **JSON Schema** for validation and documentation. See [OpenAPI Documentation](https://codehooks.io/docs/openapi-swagger-docs) for details.

## Compile

When running the `coho compile` command, it will automatically create a `tsconfig.json` file in the project directory. The tsconfig file can be further adapted to your needs, the initial configuration is shown in the example below:

```json
{
  "files": ["./index.ts"],
  "compilerOptions": {
    "allowJs": true,
    "lib": ["ES6", "dom"]
  }
}
```

Any syntax or type error will be displayed accordingly from the compile command, for example:

```shell
$ coho compile

🤔 [tsl] ERROR in /Users/jane/projects/tsdemo/index.ts(9,9)
      TS2345: Argument of type '(req: httpRequest, res: httpResponse) => void' is not assignable to parameter of type 'string'.
```

Correcting the errors should ultimately show a successfull compile output, ready for deployment of your backend app.

```shell
$ coho compile

OK 🙌
```

Your backend application is now available at your project's endpoint URL. For example:

`https://myproject-ff00.codehooks.io/dev/*`

## Deploy

From the project directory run:

```shell
$ codehooks deploy
```

## What You Can Build

- **Webhook Handlers** – Receive and process webhooks from Stripe, Shopify, GitHub, Slack, Discord, Twilio, and any service. Built-in `request.rawBody` for signature verification.
- **REST APIs** – Express.js-like routing with `app.get()`, `app.post()`, etc. Full CRUD with `app.crudlify()`.
- **AI Agent Tool Backends** – Give your agents APIs they can call — store data, trigger workflows, query results.
- **Scheduled Automations** – Cron jobs that sync data, send digests, clean up records, or poll external APIs.
- **Multi-Step Workflows** – Chain API calls, queue tasks, and orchestrate services with the Workflow API. Automatic retries, state persistence, and error recovery.
- **SaaS Integrations** – Connect any service that sends webhooks. Process, transform, and route to where it matters.
- **Full-Stack Apps** – Deploy frontend and backend together in one package. React, static sites, or SPAs served alongside your API with zero extra config.

## Documentation

For complete documentation, visit [https://codehooks.io/docs](https://codehooks.io/docs).

For AI-optimized documentation, see [https://codehooks.io/llms.txt](https://codehooks.io/llms.txt).

## API

## Codehooks Class API Reference

The Codehooks class provides a comprehensive backend application framework with the following APIs:

### **HTTP Routing APIs**

- **`post(path, ...hook)`** - Register POST route handlers
- **`get(path, ...hook)`** - Register GET route handlers
- **`put(path, ...hook)`** - Register PUT route handlers
- **`patch(path, ...hook)`** - Register PATCH route handlers
- **`delete(path, ...hook)`** - Register DELETE route handlers
- **`all(path, ...hook)`** - Register handlers for all HTTP methods

### **Middleware & Authentication APIs**

- **`use(...hook)`** - Register global middleware (supports string paths, RegExp, or function)
- **`useRoute(route, ...hook)`** - Register route-specific middleware
- **`auth(path, ...hook)`** - Register authentication middleware for specific paths

### **Background Processing APIs**

- **`queue(topic, ...hook)`** - Register queue handlers for background processing
- **`worker(name, ...hook)`** - Register worker functions (also adds to queues for legacy support)
- **`job(cronExpression, ...hook)`** - Register scheduled cron jobs

### **Static File Serving APIs**

- **`static(options, hook)`** - Serve static files from source code directory
- **`storage(options, hook)`** - Serve files from blob storage directory

### **Template & Configuration APIs**

- **`set(key, val)`** - Set application configuration settings
- **`render(view, data, cb)`** - Render templates with data
- **`crudlify(schema, options)`** - Auto-generate CRUD REST API endpoints
- **`openapi(config, uiPath)`** - Enable OpenAPI/Swagger documentation at `/docs` and `/openapi.json`

### **Real-time Communication APIs**

- **`realtime(path, ...hook)`** - Set up server-sent events (SSE) channels for real-time communication

### **Workflow Management APIs**

- **`createWorkflow(name, description, steps, options)`** - Create and register a new workflow instance

### **Application Lifecycle APIs**

- **`init(hook)`** - Initialize the application and return manifest
- **`start(hook)`** - Alias for `init()` method

The Codehooks class serves as a comprehensive backend application framework that combines HTTP routing, background processing, real-time communication, and workflow management capabilities in a single, cohesive API.

## Datastore API Reference

The Datastore provides a unified interface for both NoSQL document storage and Key-Value operations. It supports MongoDB-like query syntax and provides streaming capabilities for large datasets.

### **Connection & Collection Management**

- **`open()`** - Connect to the Datastore and return the API interface
- **`collection(name)`** - Get a NoSQL collection by name for document operations

### **NoSQL Document Operations**

#### **Read Operations**

- **`getOne(collection, query)`** - Get a single document by ID or query
- **`findOne(collection, query)`** - Alias for getOne
- **`getMany(collection, query?, options?)`** - Get a stream of documents matching query
- **`find(collection, query?, options?)`** - Alias for getMany

#### **Write Operations**

- **`insertOne(collection, document)`** - Insert a new document into a collection
- **`updateOne(collection, query, document, updateOperators?, options?)`** - Update one document (patches existing data)
- **`updateMany(collection, query, document, updateOperators?)`** - Update multiple documents
- **`replaceOne(collection, query, document, options?)`** - Replace one document completely
- **`replaceMany(collection, query, document, options?)`** - Replace multiple documents

#### **Delete Operations**

- **`removeOne(collection, query)`** - Remove one document by ID or query
- **`removeMany(collection, query)`** - Remove multiple documents matching query

#### **Schema Management**

- **`createSchema(collection, schema)`** - Validate collection data against JSON-Schema
- **`setSchema(collection, schema)`** - Alias for createSchema
- **`removeSchema(collection)`** - Remove JSON-schema validation for collection
- **`getSchema(collection)`** - Get JSON-schema for collection

#### **Utility Operations**

- **`count(collection)`** - Count documents in a collection

### **Key-Value Operations**

#### **Basic Key-Value Operations**

- **`set(key, value, options?)`** - Set a key-value pair
- **`get(key, options?)`** - Get a value by key
- **`getAll(keyPattern, options?)`** - Get all key-value pairs matching pattern
- **`del(key, options?)`** - Delete a key-value pair
- **`delAll(keyPattern, options?)`** - Delete all key-value pairs matching pattern

#### **Numeric Operations**

- **`incr(key, value, options?)`** - Increment a numeric value
- **`decr(key, value, options?)`** - Decrement a numeric value

### **Queue Operations**

- **`enqueue(topic, document, options?)`** - Add a job to a queue for background processing
- **`enqueueFromQuery(collection, query, topic, options?)`** - Queue each item from a database query

### **DataStream Interface**

When using `getMany()` or `find()`, you get a DataStream object with these methods:

- **`on(event, callback)`** - Listen for data events (e.g., `'data'`, `'end'`)
- **`json(response)`** - Pipe data directly to HTTP response as JSON
- **`toArray()`** - Convert stream to array of objects
- **`forEach(callback)`** - Iterate over each object in the stream

### **Usage Examples**

```javascript
import { datastore } from 'codehooks-js';

// Connect to datastore
const conn = await datastore.open();

// NoSQL operations
const doc = await conn.insertOne('users', {
  name: 'John',
  email: 'john@example.com',
});
const user = await conn.getOne('users', { _id: doc._id });
const users = await conn.getMany('users', { active: true }).toArray();
await conn.updateOne('users', { _id: doc._id }, { lastLogin: new Date() });

// Key-Value operations
await conn.set('user:123:session', { token: 'abc123', expires: new Date() });
const session = await conn.get('user:123:session');
await conn.incr('visits', 1);

// Queue operations
await conn.enqueue('emailWorker', {
  to: 'user@example.com',
  template: 'welcome',
});
```

### **Query Syntax**

The Datastore supports MongoDB-like query syntax:

```javascript
// Simple equality
{
  status: 'active';
}

// Comparison operators
{
  age: {
    $gt: 18;
  }
}
{
  price: {
    $lte: 100;
  }
}

// Logical operators
{
  $and: [{ status: 'active' }, { age: { $gte: 18 } }];
}
{
  $or: [{ category: 'A' }, { category: 'B' }];
}

// Array operations
{
  tags: {
    $in: ['javascript', 'nodejs'];
  }
}
{
  tags: {
    $all: ['javascript', 'nodejs'];
  }
}

// Regular expressions
{
  name: {
    $regex: /john/i;
  }
}
```

### **Options**

Many operations accept an options object for additional configuration:

```javascript
// Upsert option for updates
await conn.updateOne(
  'users',
  { email: 'john@example.com' },
  { lastLogin: new Date() },
  {},
  { upsert: true }
);

// Key-Value options
await conn.set('key', 'value', { ttl: 3600000 }); // 1 hour TTL
```

### **Key Features:**

1. **Express-style routing** with support for all HTTP methods
2. **Middleware system** with global and route-specific middleware
3. **Background processing** with queues, workers, and scheduled jobs
4. **Static file serving** from both source and blob storage
5. **Real-time communication** via Server-Sent Events
6. **Workflow engine** for complex step-based applications
7. **Auto-generated CRUD APIs** with schema validation
8. **Datastore** with MongoDB-like query syntax, key-value operations, and queue management
9. **Security & Authentication** with JWKS support and custom auth middleware for secure API endpoints
