bun-http-server — скилл для Claude Code: HTTP-серверы на Bun
Скилл подсказывает агенту, как поднять HTTP-сервер через Bun.serve(): маршруты, разбор тела запроса, ответы, CORS.
npx skills add secondsky/claude-skills --skill bun-http-server -a claude-codeЧто делает bun-http-server
Скилл включается, когда вы просите агента написать сервер на Bun, добавить маршрут или разобрать тело запроса. Внутри — готовые шаблоны: базовый Bun.serve() с портом и fetch, чтение метода, пути и query-параметров через new URL(req.url), разбор JSON, form data, текста и ArrayBuffer.
Отдельный блок про маршрутизацию. Классический fetch(req) с ручным разбором URL работает и дальше, но с Bun 1.2 канонический способ — опция routes с динамическими параметрами в req.params. Советует использовать routes для нового кода, а fetch оставлять как запасной вариант для несовпавших путей.
Есть разделы про статику через Bun.file(), CORS с обработкой preflight, глобальный обработчик error и таблицу частых ошибок вроде EADDRINUSE или 413 Payload Too Large. Две вещи стоит держать в голове. Первая: тело запроса читается один раз, повторное чтение падает. Вторая: server.stop() в Bun 1.2 и новее возвращает промис, и без await соединения могут не дождаться завершения.
Какие задачи решает
- поднять HTTP-сервер на Bun с нуля
- добавить маршрут с динамическим параметром в пути
- разобрать JSON или form data из тела запроса
- отдать статический файл или поток в ответе
- настроить CORS и обработку preflight-запросов
Примеры запросов агенту
- Напиши сервер на Bun.serve с маршрутом /api/users и ответом в JSON
- Добавь в этот сервер маршрут /api/users/:id с параметром из req.params
- Почему падает чтение тела запроса второй раз и как это исправить?
Как установить bun-http-server
1Через Skills CLI (Vercel)
npx skills add secondsky/claude-skills --skill bun-http-server -a claude-code2Вручную: положить файлы
~/.claude/skills/bun-http-server/SKILL.mdПапка скилла целиком; для одного проекта — .claude/skills/bun-http-server/
1Через Skills CLI (Vercel)
npx skills add secondsky/claude-skills --skill bun-http-server -a codex2Вручную: положить файлы
.agents/skills/bun-http-server/SKILL.mdДля всех проектов — ~/.agents/skills/
1Через Skills CLI (Vercel)
npx skills add secondsky/claude-skills --skill bun-http-server -a cursor2Вручную: положить файлы
.cursor/skills/bun-http-server/SKILL.mdCursor читает и .agents/skills/, и .claude/skills/
1GitHub CLI
gh skill install secondsky/claude-skills bun-http-server2Вручную: положить файлы
.github/skills/bun-http-server/SKILL.md1Через Skills CLI (Vercel)
npx skills add secondsky/claude-skills --skill bun-http-server -a gemini-cli2Командой платформы
gemini skills install https://github.com/secondsky/claude-skills --path plugins/bun/skills/bun-http-serverВручную: положить файлы
.devin/skills/bun-http-server/SKILL.mdСтарый путь .windsurf/skills/ тоже читается
Через Skills CLI (Vercel)
npx skills add secondsky/claude-skills --skill bun-http-server -a opencodeClaude.ai
Упакуйте папку в zip и загрузите в Settings → Capabilities → Skills
По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов
Из того же набора89
Похожие
Рядом в теме «Бэкенд и API»
Всё по теме «Бэкенд и API» →Вопросы о bun-http-server
Как установить bun-http-server в Claude?
Выполните npx skills add secondsky/claude-skills --skill bun-http-server -a claude-code. После этого файл скилла лежит в ~/.claude/skills/bun-http-server/SKILL.md.
Что делает bun-http-server?
Даёт агенту шаблоны для HTTP-серверов на Bun: базовый Bun.serve(), разбор запросов и тел, типы ответов, маршрутизацию, статику и CORS.
Чем routes отличается от fetch в Bun.serve?
Опция routes появилась в Bun 1.2 и даёт карту маршрутов с параметрами в req.params. fetch остаётся запасным обработчиком для путей, которые не совпали ни с одним маршрутом.
Исходный текст
SKILL.md · MIT
---
name: bun-http-server
description: Use when building HTTP servers with Bun.serve, handling requests/responses, implementing routing, creating REST APIs, or configuring fetch handlers.
metadata:
version: "1.0.0"
license: MIT
---
# Bun HTTP Server
Bun has a built-in high-performance HTTP server via `Bun.serve()`.
## Quick Start
```typescript
const server = Bun.serve({
port: 3000,
fetch(req) {
return new Response("Hello World!");
},
});
console.log(`Server running at http://localhost:${server.port}`);
```
## Request Handling
```typescript
Bun.serve({
fetch(req) {
const url = new URL(req.url);
// Method
console.log(req.method); // GET, POST, etc.
// Path
console.log(url.pathname); // /api/users
// Query params
console.log(url.searchParams.get("id")); // ?id=123
// Headers
console.log(req.headers.get("Content-Type"));
return new Response("OK");
},
});
```
## Body Parsing
```typescript
Bun.serve({
async fetch(req) {
// JSON
const json = await req.json();
// Form data
const form = await req.formData();
// Text
const text = await req.text();
// ArrayBuffer
const buffer = await req.arrayBuffer();
// Blob
const blob = await req.blob();
return new Response("Received");
},
});
```
## Response Types
```typescript
Bun.serve({
fetch(req) {
const url = new URL(req.url);
switch (url.pathname) {
case "/json":
return Response.json({ message: "Hello" });
case "/html":
return new Response("<h1>Hello</h1>", {
headers: { "Content-Type": "text/html" },
});
case "/redirect":
return Response.redirect("/new-location", 302);
case "/file":
return new Response(Bun.file("./image.png"));
case "/stream":
return new Response(
new ReadableStream({
start(controller) {
controller.enqueue("chunk1");
controller.enqueue("chunk2");
controller.close();
},
})
);
default:
return new Response("Not Found", { status: 404 });
}
},
});
```
## Simple Routing
```typescript
Bun.serve({
fetch(req) {
const url = new URL(req.url);
const path = url.pathname;
const method = req.method;
// Static routes
if (method === "GET" && path === "/") {
return new Response("Home");
}
if (method === "GET" && path === "/api/users") {
return Response.json([{ id: 1, name: "Alice" }]);
}
// Dynamic routes
const userMatch = path.match(/^\/api\/users\/(\d+)$/);
if (method === "GET" && userMatch) {
const userId = userMatch[1];
return Response.json({ id: userId });
}
// 404
return new Response("Not Found", { status: 404 });
},
});
```
## Error Handling
```typescript
Bun.serve({
fetch(req) {
try {
// Handle request
throw new Error("Something went wrong");
} catch (error) {
return new Response(
JSON.stringify({ error: error.message }),
{
status: 500,
headers: { "Content-Type": "application/json" }
}
);
}
},
error(error) {
// Global error handler
return new Response(`Error: ${error.message}`, { status: 500 });
},
});
```
## Server Options
```typescript
const server = Bun.serve({
port: 3000, // Default: 3000
hostname: "0.0.0.0", // Default: "0.0.0.0"
development: true, // Pretty errors in browser
// TLS/HTTPS
tls: {
key: Bun.file("./key.pem"),
cert: Bun.file("./cert.pem"),
},
// Unix socket
unix: "/tmp/my-socket.sock",
// Max request body size (default 128MB)
maxRequestBodySize: 1024 * 1024 * 10, // 10MB
fetch(req) {
return new Response("OK");
},
});
```
## Server Methods
```typescript
const server = Bun.serve({ ... });
// Server info
console.log(server.port); // 3000
console.log(server.hostname); // "0.0.0.0"
console.log(server.url); // URL object
// Stop server (Bun 1.2+: returns a Promise — await it to flush in-flight
// requests; calling it without await may not drain connections).
await server.stop();
// Reload with new config
server.reload({
fetch(req) {
return new Response("Updated!");
},
});
// Pending requests count
console.log(server.pendingRequests);
```
## Routing with `routes` (Bun 1.2+)
The examples above use the classic `fetch(req)` handler with manual URL
parsing, which still works. As of Bun 1.2, the canonical way to declare
route maps is the `routes` option, with dynamic params available on
`req.params`:
```typescript
Bun.serve({
routes: {
"/api/users": {
GET: () => Response.json([{ id: 1, name: "Alice" }]),
POST: async (req) => Response.json(await req.json(), { status: 201 }),
},
"/api/users/:id": (req) => {
const { id } = req.params;
return Response.json({ id });
},
},
fetch(req) {
return new Response("Not Found", { status: 404 });
},
});
```
Use `routes` for new code; keep `fetch` as a fallback for unmatched paths.
## Static Files
```typescript
Bun.serve({
fetch(req) {
const url = new URL(req.url);
// Serve static files from public/
if (url.pathname.startsWith("/static/")) {
const filePath = `./public${url.pathname.replace("/static", "")}`;
const file = Bun.file(filePath);
if (await file.exists()) {
return new Response(file);
}
return new Response("Not Found", { status: 404 });
}
return new Response("API");
},
});
```
## CORS
```typescript
function corsHeaders() {
return {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization",
};
}
Bun.serve({
fetch(req) {
// Handle preflight
if (req.method === "OPTIONS") {
return new Response(null, { headers: corsHeaders() });
}
// Add CORS headers to response
return new Response("OK", { headers: corsHeaders() });
},
});
```
## Common Errors
| Error | Cause | Fix |
|-------|-------|-----|
| `EADDRINUSE` | Port in use | Use different port or kill process |
| `Cannot read body` | Body already consumed | Read body once only |
| `CORS error` | Missing headers | Add CORS headers |
| `413 Payload Too Large` | Body exceeds limit | Increase maxRequestBodySize |
## When to Load References
Load `references/tls-config.md` when:
- HTTPS/TLS setup
- Certificate configuration
- mTLS authentication
Load `references/streaming.md` when:
- Server-sent events
- Streaming responses
- Chunked transfer encoding
© secondsky · MIT · secondsky/claude-skills