Community HubPublishing to the Hub

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:

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.

aerostack.json
{
  "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

FieldTypeRequiredDescription
namestringYesSlug-friendly name. Becomes the Hub URL: hub.aerostack.dev/functions/you/image-resizer
versionstringYesSemVer string, e.g. 1.0.0
descriptionstringYesShort description shown in search results
categorystringYesOne of: auth, payments, media, email, ai, database, utility, analytics, notifications, storage
languagestringYestypescript or javascript
runtimestringYescloudflare-worker (default)
licensestringYesSPDX identifier, e.g. MIT, Apache-2.0
tagsstring[]NoSearch keywords, max 10
entrypointstringYesPath to main source file relative to the function directory
routePathstringNoDefault HTTP route when installed, e.g. /api/image-resize
routeExportstringNoNamed export from your adapter, e.g. imageResizerRoute
npmDependenciesstring[]Nonpm packages the consumer must install
envVarsstring[]NoEnvironment variables the consumer must set
drizzleSchemabooleanNoSet 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.

index.ts
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.ts

Each 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: true makes the function live immediately. Set publish: false to 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

ErrorCauseFix
INVALID_CATEGORYCategory not in allowed listCheck spelling, use lowercase
MISSING_ENTRYPOINTEntrypoint file not foundVerify path is relative to the function directory
EMPTY_CODEEntrypoint file is emptyAdd at least one exported function
DUPLICATE_SLUGSlug exists under a different accountRename your function
UNAUTHORIZEDAPI key invalid or expiredRun aerostack login again
VERSION_CONFLICTVersion string already publishedBump 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.