netlify-access-control
Picks the right Netlify site-protection layer and disambiguates the three unrelated "auth" concepts users conflate — app-user…
Build and deploy a long-lived Node.js backend on Netlify Server (Early Access) from netlify/server/index.ts. Use this skill whenever someone wants to run an Express, Fastify, Hono or Koa app on Netlify as it is, add a backend or REST/GraphQL API that keeps database pools and
Claude Code
$ npx -y skills add netlify/context-and-tools --skill netlify-server --agent claude-code
Codex
$ npx skills add netlify/context-and-tools --skill netlify-server -a codex -y
Cursor
$ npx skills add netlify/context-and-tools --skill netlify-server -a cursor -y
Gemini CLI
$ npx skills add netlify/context-and-tools --skill netlify-server -a gemini-cli -y
GitHub Copilot
$ npx skills add netlify/context-and-tools --skill netlify-server -a github-copilot -y
OpenCode
$ npx skills add netlify/context-and-tools --skill netlify-server -a opencode -y
Windsurf
$ npx skills add netlify/context-and-tools --skill netlify-server -a windsurf -y
name: netlify-server description: Build and deploy a long-lived Node.js backend on Netlify Server (Early Access) from netlify/server/index.ts. Use this skill whenever someone wants to run an Express, Fastify, Hono or Koa app on Netlify as it is, add a backend or REST/GraphQL API that keeps database pools and caches warm, build real-time features such as chat, live dashboards or multiplayer with WebSockets or Server-Sent Events, or stream AI responses and run agent loops. It also covers background work after responding with waitUntil, startup and graceful shutdown hooks, load-aware health checks, edge caching of server responses, region/size/scale settings, local testing with netlify dev, reading server logs with netlify logs or log drains, and debugging a server that gets no requests, fails to start, drops database connections after a minute, or returns 429/500/501/502.
Early Access, so APIs may change. It is available on credit-based plans and on Enterprise plans with credits enabled. It requires **Node.js 24+** for both build and local dev, and **Netlify CLI 27.17.0+** for both local dev and deploys.
It is free during Early Access and intended for evaluation, experimentation, and low-volume production use. At GA it will bill credits for reserved memory (GB-hours) and active CPU (vCPU-hours). **Every request the server handles already counts toward the web requests meter.**
// ✅ netlify/server/index.ts — handler (same signature as Netlify Functions)
import type { Context, Config } from "@netlify/server";
export default async (req: Request, context: Context) =>
new Response(`Hello from ${context.geo.city ?? "somewhere"}`);
export const config: Config = { path: "/api/*" };// ✅ Fetchable app (Hono etc.): export as is export default app; // ✅ Node request listener: wrap it, do NOT call listen(). WebSockets work. export default createServer(handleRequest); // ✅ Framework that starts itself (Express/Fastify): listen on PORT within 10 s app.listen(process.env.PORT);
// ❌ export default (req, res) => {...} // two params = treated as a fetch handler, breaks
// ❌ export default expressApp // works, but WebSocket upgrades get 501
// ❌ server.close(() => process.exit(0)) // cuts off shutdown hooks and background work
// ❌ setInterval / fire-and-forget promise // invisible to Netlify; the instance can stop mid-workYou don't configure ports, add health endpoints, or install adapters. Install the package with `npm install @netlify/server`.
1. `PORT` is set. 2. The entry file is imported, running top-level code (top-level `await` is awaited). 3. `onStart` hooks run in order. 4. The default export is inspected.
Netlify uses the **first matching row** for the default export:
| Default export | Run as | WebSockets | |---|---|---| | `http.Server` without `listen()` | Requests sent to it | `upgrade` event (`ws`, Socket.IO) | | Object with `fetch` (Fetchable, e.g. Hono) | `fetch(request, context)` | `upgradeWebSocket` | | Express/Connect app, or a function with ≥3 params | Wrapped in its own HTTP server | **501** | | Any other function | `(request, context) => Response` | `upgradeWebSocket` | | Anything else / nothing | Waits for your code to listen | `upgrade` event |
> ⚠️ **Self-started servers must listen within 10 s after start hooks finish.** > - If your code starts several servers, the one on `process.env.PORT` wins. If none listens on it, the start fails. > - Reserved ports are `53` and `15000–15099`. > - Only Node.js HTTP servers are supported, not raw TCP.
Create shared resources such as a DB pool at top level so they are reused across requests.
> ⚠️ **Outbound connections are closed after 60 s without data in either direction.** TCP keepalives don't count. > - Set your pool's idle timeout **below 60 s** (e.g. `idleTimeoutMillis: 30_000`), or it hands out dead connections. > - Quiet connections such as Postgres `LISTEN` need traffic at least every 60 s (e.g. `SELECT 1`), or must reconnect on close. The symptom is `Connection terminated unexpectedly`.
// netlify/server/index.mjs — Express, self-started
import express from "express";
import { getContext } from "@netlify/server";
const app = express();
app.get("/api/hello", (req, res) => {
const { geo } = getContext();
res.json({ message: `Hello from ${geo.city ?? "somewhere"}` });
});
app.listen(process.env.PORT || 3000);// Fastify
const app = Fastify();
app.get("/api/hello", async () => ({ message: `Hello from ${getContext().geo.city ?? "somewhere"}` }));
await app.listen({ port: Number(process.env.PORT) || 3000 });export default async (req: Request, context: Context) => {
const order = await saveOrder(await req.json());
context.waitUntil(sendConfirmationEmail(order)); // keeps the instance alive until settled
return Response.json(order, { status: 201 });
};
// In frameworks: const { waitUntil } = getContext();How `waitUntil` behaves:
import { upgradeWebSocket } from "@netlify/server";
export default async (req: Request) => {
if (req.headers.get("upgrade") === "websocket") {
const { socket, response } = upgradeWebSocket(req, { idleTimeout: 30 }); // pings off unless set
socket.onmessage = (e) => socket.send(`Echo: ${e.data}`);
return response; // return as is
}
return new Response("Connect with a WebSocket client");
};###
Public Netlify skills for AI coding agents. Each skill is a focused, factual reference for a Netlify platform primitive — designed to help agents build correctly on Netlify without needing to search docs.
Picks the right Netlify site-protection layer and disambiguates the three unrelated "auth" concepts users conflate — app-user…
Run AI agent tasks remotely on Netlify using Claude, Codex, or Gemini. Use when the user wants to run an AI agent on their site,…
Use Netlify AI Gateway to call OpenAI, Anthropic Claude, Google Gemini, TypeSafe (Jev), or OpenRouter-hosted models…
Store and retrieve unstructured objects, files, and cache-like state on Netlify with the @netlify/blobs module. Use when…
Cache dynamic and static responses on Netlify's CDN from Functions, Edge Functions, and proxies. Use when you add caching or…
Configure Netlify builds and routing via netlify.toml, _redirects, and _headers. Use when setting a build command or publish…
Use this skill whenever the user mentions Horizon by name in a Laravel context. Covers the full Horizon lifecycle: installing…
Use when launching cloud VMs, Kubernetes pods, or Slurm jobs for GPU/TPU/CPU workloads, training or fine-tuning models on cloud…
Use this skill when the user mentions "pinme", or needs to upload files, store to IPFS, create/publish/deploy websites or…