Publishing Functions via CLI
The CLI lets you publish a function from your terminal using the functions subcommand. You push source code to create a draft, then publish by ID to make it live. Point the CLI at a file (and optional aerostack.json in the same directory or project root); it creates a new draft on the Aerostack Hub each time you push.
Prerequisites
Section titled “Prerequisites”Before you publish:
- Installed the Aerostack CLI
- Logged in with
aerostack login(you’ll need your account API key from app.aerostack.dev/account/keys) - A function directory structured like the examples below
Function Structure
Section titled “Function Structure”Every publishable function lives in its own directory. The only required file is aerostack.json plus at least one source file.
Directorymy-image-resizer
- aerostack.json // Required — metadata and config
- index.ts // Required — your function logic
- schema.ts // Optional — Drizzle tables
- README.md // Recommended — shown on Hub
The aerostack.json file
Section titled “The aerostack.json file”This file defines your function’s identity, version, and capabilities. It is read by both the CLI and the Hub.
{ "name": "image-resizer", "version": "1.0.0", "description": "Resize and transform images on the edge using Cloudflare Workers.", "category": "media", "language": "typescript", "runtime": "cloudflare-worker", "license": "MIT", "tags": ["image", "media", "resize", "cdn"], "entrypoint": "index.ts", "routePath": "/api/image-resize", "routeExport": "imageResizerRoute", "npmDependencies": [], "envVars": ["IMAGE_MAX_WIDTH", "IMAGE_QUALITY"], "drizzleSchema": false}aerostack.json field reference
Section titled “aerostack.json field reference”| Field | Type | Required | Description |
|---|---|---|---|
name | string | ✅ | Slug-friendly name. Becomes the Hub URL: hub.aerostack.dev/functions/you/image-resizer |
version | string | ✅ | SemVer string e.g. 1.0.0 |
description | string | ✅ | Short description shown in search results |
category | string | ✅ | One of: auth, payments, media, email, ai, database, utility, analytics, notifications, storage |
language | string | ✅ | typescript or javascript |
runtime | string | ✅ | cloudflare-worker (default) |
license | string | ✅ | SPDX identifier e.g. MIT, Apache-2.0 |
tags | string[] | — | Search keywords, max 10 |
entrypoint | string | ✅ | Path to main source file relative to the function directory |
routePath | string | — | Default HTTP route when installed into a project, e.g. /api/image-resize |
routeExport | string | — | Named export from your adapter, e.g. imageResizerRoute |
npmDependencies | string[] | — | npm packages the consumer must install |
envVars | string[] | — | Environment variables the consumer must set |
drizzleSchema | boolean | — | Set true if you export a Drizzle table schema |
Writing Your Function
Section titled “Writing Your Function”Your index.ts should export a Hono route handler. This is the convention the CLI bundles and the Hub displays.
import { Hono } from 'hono';
export const imageResizerRoute = new Hono<{ Bindings: { DB: D1Database } }>();
imageResizerRoute.get('/resize', async (c) => { const url = c.req.query('url'); const width = parseInt(c.req.query('width') ?? '800');
if (!url) { return c.json({ error: 'url query param required' }, 400); }
// Your image resizing logic using Cloudflare Images API return c.json({ original: url, resized: `${url}?width=${width}&format=webp`, width, });});
imageResizerRoute.get('/health', (c) => c.json({ module: 'image-resizer', ok: true }));Publishing Steps
Section titled “Publishing Steps”-
Authenticate
Terminal window aerostack login# Prompts: Enter your API key: ac_secret_xxxx -
Push to create a draft
Terminal window aerostack functions push ./my-image-resizer/index.ts# Or from inside the function directory:aerostack functions push index.tsEach push creates a new draft function. The command outputs the function ID, slug, and a link to the Admin. Save the ID — you need it to publish from the CLI.
Example output:
Pushing function 'image-resizer' to Aerostack...Pushed successfully!Slug: image-resizerStatus: draftAdmin URL: https://app.aerostack.dev/functions/edit/<id> -
Publish the draft
Use the ID from the push output (or from My Functions in the Admin):
Terminal window aerostack functions publish <id>Alternatively, open the Admin URL from the push output, add a README and tags, and click Publish there. The function then appears on the Hub and can be installed with
aerostack functions install. -
Optional: Finalize in the Admin
After pushing, your function is a Draft. To add a full README and tags before going live:
- Go to the Admin URL from the push output (or Admin → My Functions)
- Open the draft and click Edit
- Add README, screenshots, and usage examples
- Click Publish — it goes live immediately
First-time vs updating
Section titled “First-time vs updating”- First time:
aerostack functions push [file]creates a new draft. Then runaerostack functions publish <id>or publish from the Admin. - Updating an existing function: Each
aerostack functions pushcreates a new draft (it does not update the same function by slug). To update an existing function:- Admin: Open the function in Admin → My Functions → Edit, change code/metadata, Save. Optionally publish again if you want a new version snapshot.
- CI: Use the GitHub Actions or GitLab CI workflow with
POST /api/community/functions/ci/publish; that endpoint upserts by slug (updates the same function).
Common Errors
Section titled “Common Errors”| Error | Cause | Fix |
|---|---|---|
INVALID_CATEGORY | Category not in allowed list | Check spelling and use lowercase |
MISSING_ENTRYPOINT | entrypoint file not found | Verify the path is relative to the function directory |
EMPTY_CODE | Entrypoint file is empty | Add at least one exported function |
DUPLICATE_SLUG | Slug already exists under a different account | Rename your function |
UNAUTHORIZED | API key invalid or expired | Run aerostack login again |
VERSION_CONFLICT | Version string already published | Bump version in aerostack.json |
Full Example Project
Section titled “Full Example Project”A minimal publishable function you can clone and modify:
git clone https://github.com/aerostack/example-functionscd example-functions/rate-limiteraerostack publish .