Publishing to the Hub
Share your work with the Aerostack community by publishing to the Hub. You can publish via the Admin dashboard, the CLI, GitHub Actions, or GitLab CI.
Prerequisites
Before you publish:
- Install the Aerostack CLI
- Log in with
aerostack login(you need an account key from app.aerostack.dev/account/keys)
Account Key vs Project Key — Publishing requires an account key (prefix ac_), not a project key. Project keys are scoped to a single project deployment.
Function structure
Every publishable function lives in its own directory with an aerostack.json config and at least one source file.
- Required -- metadata and config
- Required -- your function logic
- Recommended -- shown on the Hub
The aerostack.json config file
This file defines your function’s identity, version, and capabilities. It is read by the CLI, CI pipelines, 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
}Field reference
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Slug-friendly name. Becomes the Hub URL: hub.aerostack.dev/functions/you/image-resizer |
version | string | Yes | SemVer string, e.g. 1.0.0 |
description | string | Yes | Short description shown in search results |
category | string | Yes | One of: auth, payments, media, email, ai, database, utility, analytics, notifications, storage |
language | string | Yes | typescript or javascript |
runtime | string | Yes | cloudflare-worker (default) |
license | string | Yes | SPDX identifier, e.g. MIT, Apache-2.0 |
tags | string[] | No | Search keywords, max 10 |
entrypoint | string | Yes | Path to main source file relative to the function directory |
routePath | string | No | Default HTTP route when installed, e.g. /api/image-resize |
routeExport | string | No | Named export from your adapter, e.g. imageResizerRoute |
npmDependencies | string[] | No | npm packages the consumer must install |
envVars | string[] | No | Environment variables the consumer must set |
drizzleSchema | boolean | No | Set true if you export a Drizzle table schema |
Category is case-sensitive. Use all lowercase. The value must exactly match one of the supported categories, or publishing will be rejected.
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);
}
return c.json({
original: url,
resized: `${url}?width=${width}&format=webp`,
width,
});
});
imageResizerRoute.get('/health', (c) =>
c.json({ module: 'image-resizer', ok: true })
);Tip: separate logic from HTTP. For complex functions, put pure business logic in core.ts and keep the HTTP adapter in index.ts. This makes your function easier to test and easier for consumers to use without Hono.
Choose a publishing method
The CLI is the fastest way to publish. Push source code to create a draft, then publish by ID.
Push to create a draft
aerostack functions push ./my-function/index.tsEach push creates a new draft. The command outputs the function ID, slug, and a link to the Admin. Save the ID.
Example output:
Pushing function 'image-resizer' to Aerostack...
Pushed successfully!
Slug: image-resizer
Status: draft
Admin URL: https://app.aerostack.dev/functions/edit/<id>Publish the draft
aerostack functions publish <id>The function is now live on the Hub and can be installed with aerostack functions install.
(Optional) Finalize in the Admin
Before publishing, you can open the Admin URL from the push output to add a README, screenshots, and tags. Then click Publish from the Admin instead.
Updating an existing function via CLI
Each aerostack functions push creates a new draft — it does not update an existing function by slug. To update an existing function:
- Admin: Open the function in Admin and edit directly.
- CI: Use the GitHub Actions or GitLab CI workflow (below). The CI endpoint upserts by slug, so it updates the same function.
How CI publishing works
The CI endpoint (POST /api/community/functions/ci/publish) behaves differently from the CLI:
- Upserts by slug — If a function with the same name already exists under your account, it updates the code and metadata. Otherwise, it creates a new function.
publish: truemakes the function live immediately. Setpublish: falseto land as a draft for review.- Version snapshots are permanent — Every published version is preserved. Consumers who installed an earlier version can still reference it.
Bump the version before each publish. You cannot overwrite an existing published version. Update the version field in aerostack.json before publishing a new release.
Common errors
| Error | Cause | Fix |
|---|---|---|
INVALID_CATEGORY | Category not in allowed list | Check spelling, use lowercase |
MISSING_ENTRYPOINT | Entrypoint file not found | Verify path is relative to the function directory |
EMPTY_CODE | Entrypoint file is empty | Add at least one exported function |
DUPLICATE_SLUG | Slug 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 |
Version history
Every time you publish a new version, a code snapshot is stored. All past versions are preserved — consumers who installed an earlier version can still reference its code.
To release an update, bump the version field in aerostack.json and publish again. There is no way to overwrite a past version.
Reputation
Every time your function is installed (via aerostack functions install or the Hub), you earn Community Reputation. Higher reputation unlocks badges and better visibility in search results.