Skip to content

Neon.Function reference

Source: src/Neon/CronEventSource.ts

Register a typed POST handler and create its tracked FunctionTrigger automatically. Provide CronEventSourceHttp on the Function initialization Effect. Handler failures remain non-success HTTP responses; delivery is not a native scheduled event or an exactly-once guarantee. Local development does not run a cron scheduler.

yield* Neon.CronEventSource("Nightly", { cron: "0 2 * * *" }, event => Effect.log(event.invocationId));

Source: src/Neon/CronEventSourceHttp.ts Kind: Layer · Provides: Neon.CronEventSource

Neon Function HTTP schedule dispatch and deployment wiring.

CronEventSourceHttp: Subscribe to a schedule

Section titled “CronEventSourceHttp: Subscribe to a schedule”
const application = Effect.gen(function* () {
yield* Neon.CronEventSource("Nightly", { cron: "0 2 * * *" }, event =>
Effect.log(event.invocationId),
);
return { fetch: Effect.succeed(HttpServerResponse.text("ok")) };
}).pipe(Effect.provide(Neon.CronEventSourceHttp));

Source: src/Neon/CustomDomain.ts

Register a branch-local custom Function domain without waiting for DNS. A registration does not prove HTTPS works. Publish a DNS-only CNAME, then verify the custom URL separately. Domains are not inherited by child branches.

const domain = yield* Neon.CustomDomain("Domain", { function: api, hostname: "api.example.com" });
// Publish domain.cnameTarget as a DNS-only CNAME for domain.hostname.

Source: src/Neon/Function.ts

Node.js 24 Fetch function, with native and Effect entrypoints.

Functions have public URLs. The functions:invoke credential scope does not establish a private invocation policy. Authenticate requests in your handler. Native same-branch database/storage credentials are injected by Neon; a typed read-only binding does not restrict the credentials available to the process. Explicit adoption takes ownership of user-defined environment names: existing keys omitted from env and bindings are removed. Values are write-only, so cached digests cannot detect out-of-band value drift.

Neon’s production host currently does not reliably propagate client disconnects to uncompressed response streams. An abandoned stream can retain its producer and request-scoped resources until it finishes. Prefer finite responses and application-bounded streams; do not rely on disconnect cleanup for long-lived streaming workloads until the upstream issue is resolved. Alchemy propagates abort and body-cancel signals when the host supplies them.

const api = yield* Neon.Function("Api", { branch, main: "./src/api.ts" });
export default class Api extends Neon.Function<Api>()(
"Api", { branch, main: import.meta.url },
Effect.succeed({ fetch: Effect.succeed(HttpServerResponse.text("ok")) }),
) {}
const site = yield* Neon.Function("Site", { branch, artifact: { directory: "./dist" } });

Source: src/Neon/FunctionTrigger.ts

Deliver scheduled or object-created events as HTTP POSTs to a Function. For Effect handlers, prefer BucketEventSource or CronEventSource: they create this resource and register its handler route together. Use FunctionTrigger directly for an existing native HTTP handler. Check the edge-attested header and validate the payload using decodeFunctionTriggerEvent. Invocation IDs support application idempotency; Alchemy does not promise exactly-once delivery or undocumented retries.

const nightly = yield* Neon.FunctionTrigger("Nightly", {
function: api, type: "schedule", schedule: { cron: "0 2 * * *" }, path: "/jobs/nightly",
});
yield* Neon.FunctionTrigger("Uploads", {
function: api, type: "storage_object_created",
storageObjectCreated: { bucket: uploads, prefix: "incoming/" }, path: "/jobs/upload",
});

Source: src/Neon/InvokeFunction.ts

Bind a public Function URL to any Alchemy runtime host.

const invoke = yield* Neon.InvokeFunction(api);
const response = yield* invoke.fetch("/private", { headers: { authorization: bearer } });

Source: src/Neon/InvokeFunctionHttp.ts Kind: Layer · Provides: Neon.InvokeFunction

URL-only HTTP client. Does not provision an invocation credential or private route.

const application = Effect.gen(function* () {
const api = yield* Neon.InvokeFunction(target);
return {
fetch: Effect.gen(function* () {
const response = yield* api.fetch("/health").pipe(Effect.orDie);
return HttpServerResponse.text(String(response.status));
}),
};
}).pipe(Effect.provide(Neon.InvokeFunctionHttp));