К основному содержанию
скилл CX Codex

bun-http-server — скилл для Claude Code: HTTP-серверы на Bun

Скилл подсказывает агенту, как поднять HTTP-сервер через Bun.serve(): маршруты, разбор тела запроса, ответы, CORS.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add secondsky/claude-skills --skill bun-http-server -a claude-code
Открыть на GitHub

Что делает 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-code

2Вручную: положить файлы

~/.claude/skills/bun-http-server/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/bun-http-server/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Из того же набора89

bun-test-coverage Скилл для работы с покрытием тестов в Bun: флаг --coverage, отчёты lcov, пороги и запуск в CI. Пригодится, когда тесты уже есть, а процент покрытия надо видеть и держать. CX Codex +1 403установок bun-workers Скилл подсказывает агенту, как запускать Web Workers и worker_threads в Bun: параллельные задачи, пул воркеров, обмен сообщениями. CX Codex +1 402установок dependency-upgrade Помогает обновлять зависимости без риска: настраивает карантин для новых версий, блокирует postinstall-скрипты и ведёт обновления поэтапно. CX Codex +1 404установок nuxt-server Скилл для серверной разработки на Nuxt 4 с Nitro: API-роуты, middleware, базы данных и WebSocket. Пригодится, когда бэкенд живёт внутри Nuxt-проекта. CX Codex +1 401установок bun-cloudflare-workers Скилл для сборки и деплоя Cloudflare Workers на Bun: подсказывает структуру проекта, биндинги KV, D1, R2 и Durable Objects. CX Codex +1 402установок mobile-offline-support Скилл для офлайн-первого подхода в мобильных приложениях: локальное хранилище, очередь синхронизации, разрешение конфликтов. CX Codex +1 398установок api-versioning-strategy Помогает выбрать способ версионирования API и провести старую версию до отключения без сюрпризов для клиентов. CX Codex +1 399установок bun-hot-reloading Скилл подсказывает агенту, как настроить горячую перезагрузку в Bun: режимы --watch и --hot, HMR и перезапуск HTTP-сервера. CX Codex +1 395установок

Похожие

bun-runtime affaan-m Скилл объясняет агенту, когда брать Bun вместо Node, и даёт команды для установки, тестов и деплоя на Vercel. CX Codex +1 4 700установок bun-development sickn33 Скилл помогает вести JavaScript и TypeScript-разработку на Bun: создавать проекты, переносить код с Node.js и разбирать проблемы рантайма. CX Codex +1 2 800установок convex-http-actions waynesutton Добавляет HTTP-эндпоинты в convex/http.ts: приём вебхуков с проверкой подписи, REST-маршруты, CORS, стриминг и загрузка файлов. CX Codex +1 2 700установок bun brianlovin Переключает агента на среду Bun вместо привычных Node.js и npm. Настраивает команды запуска, встроенные базы данных и сервер без внешних пакетов. CX Codex +1 2 800установок flutter-use-http-package flutter Скилл помогает добавить в Flutter-приложение запросы к REST API через пакет http и обработать JSON-ответ. Пригодится для загрузки и отправки данных. CX Codex +1 36 100установок extension-http-outcalls caffeinelabs Скилл для HTTP-запросов из бэкенд-канистры к внешним API. Следит, чтобы каждый запрос был ограничен на стороне провайдера. CX Codex +1 28 100установок

Рядом в теме «Бэкенд и 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

Смотрите также

Спонсоры проекта

Компании, которые помогают держать аналитику открытой