base
Vovk.ts essentials — ALWAYS load first for any Vovk.ts task, including building a back end or API in a project that has vovk.config.* or .vovk-schema/.
Skill by finom
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/finom-base
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: documents, backend, productivity
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/base
What's inside
- Skill name
base- Description
- Vovk.ts essentials — ALWAYS load first for any Vovk.ts task, including building a back end or API in a project that has vovk.config.* or .vovk-schema/. Holds what a typical build needs, checked against vovk 4's code - project layout, a complete endpoint, how requests, validation and errors behave, status codes, a custom error format, CORS, and how to get the schema, the typed client and the OpenAPI document. The other vovk:* skills go deeper on one topic each; load them only for that topic.
- License
- MIT
- Instructions
- 186 lines in SKILL.md · view on GitHub
Files (1)
- SKILL.md
SKILL.md (first lines)
# Vovk.ts essentials
What a typical API build needs. Every fact here matches vovk 4.1's code: don't read `node_modules/vovk*` to check it (version, exports, CLI), and don't `WebFetch` vovk.dev. If something is missing, say so. The installed version is the `vovk` entry in `package.json` (`require('vovk/package.json')` throws: the file isn't exported); the `vovk` bin is in `node_modules/.bin`.
Deeper topics, one skill each: `procedure` (`.fn()`, content types, uploads, downloads, server actions), `decorators` (auth, `meta`, stacking), `segment` (several or static segments), `rpc` (client options, fetcher), `openapi` (`@operation`, Scalar), `jsonlines` (streaming), `tools` (AI tools, MCP), `config`, `init`, `bundle`, `mixins`, `multitenant`, `python`, `rust`.
## What `vovk` exports
- Values: `procedure`, `initSegment`, `get`, `post`, `put`, `patch`, `del`, `head`, `options`, `prefix`, `operation`, `createDecorator`, `HttpException`, `HttpStatus`, `HttpMethod`, `JSONLinesResponder`, `progressive`, `toDownloadResponse`, `controllersToStaticParams`, `multitenant`, `deriveTools`, `ToModelOutput`, `cloneControllerMetadata`.
- Types: `VovkRequest`, `VovkBody`, `VovkQuery`, `VovkParams`, `VovkInput`, `VovkOutput`, `VovkIteration`, `VovkReturnType`, `VovkYieldType`, `VovkConfig`, `VovkSchema`, and a few more for tools and streams.
- Other entry points: `vovk/fetcher` (`fetcher`, `createFetcher`), `vovk/create-rpc`, `vovk/create-validate-on-client`.
## Rules
- Node.js 24.15+ (or Bun 1.4+, Deno 2.9+), Next.js 15+ App Router, TypeScript 5.5+.
- Commit `.vovk-schema/`; the generated client dir (`src/client`) is gitignored and rebuilt by `prebuild`.
## Layout
- **Segment**: `src/app/api/[[...vovk]]/route.ts` serves `/api/*`. Create it once with `npx vovk new segment`.
- **Module**: `src/modules/<name>/<name>-controller.ts` and `<name>-service.ts`. `npx vovk new controller service <name> --empty` writes both and adds the controller to `route.ts`; writing them yourself and adding the controller to `controllers` works the same. `<name>` is camelCase (`userProfile`).
- **Controller**: static procedures with HTTP decorators. A procedure reads the validated input and calls the service.
- **Service**: business logic and data, plain typed arguments, never `req`.
```ts
// src/app/api/[[...vovk]]/route.ts
import { initSegment } from 'vovk';
import ArticleController from '../../../modules/article/article-controller';
const controllers = { ArticleRPC: ArticleController }; // the key is the client module name
export type Controllers = typeof controllers;
export const { GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS } = initSegment({ controllers });
```
## An endpoint
```ts
// src/modules/article/article-controller.ts
import { get, post, prefix, procedure, operation, HttpException, HttpStatus } from 'vovk';
import { NextResponse } from 'next/server';
import { z } from 'zod';
import ArticleService from './article-service';
const Article = z.object({ slug: z.string(), title: z.string() });
@prefix('articles')
export default class ArticleController {
@operation({ summary: 'List articles' })
@get() // GET /api/articles?limit=20
static list = procedure({
query: z.object({ limit: z.coerce.number().int().max(100).default(20) }),
output: z.object({ articles: z.array(Article) }),
}).handle(async ({ vovk }) => ArticleService.list(vovk.query()));
@operation({ summary: 'Get an article' })
@get('{slug}') // GET /api/articles/{slug}
static get = procedure({
params: z.object({ slug: z.string() }),
output: Article,
}).handle(async (_req, { slug }) => {
const article = ArticleService.find(slug);
if (!article) throw new HttpException(HttpStatus.NOT_FOUND, 'Article not found');
return article;
});
@operation({ summary: 'Create an article' })
@post() // POST /api/articles, 201
static create = procedure({
body: z.object({ title: z.string().min(1) }),
}).handle(async ({ vovk }) => NextResponse.json(ArticleService.create(await vovk.body()), { status: 201 }));
}
```
URL = `/api/<segment>/<@prefix>/<path>`, empty parts dropped. `{name}` in a path is a param. `@put`, `@patch`, `@del`, `@head`, `@options` work the same.
A path equal to a route with no params gets that route, whatever the order (`users/me` over `users/{id}`). If two routes with params match the same path, the request answers 500 `Conflicting routes found: …`.
`output` is optional. It checks the returned value and becomes the response schema in the OpenAPI document. Without it the client takes the handler's return type, including the body type of `NextResponse.json(…)`.
## Requests
- `await req.vovk.body()`, `req.vovk.query()`, `req.vovk.params()` return the validated input; the handler's second argument is the params. These also work under `.fn()`, where `req.json()` and `req.nextUrl` don't.
- Query values arrive as strings: use `z.coerce.number()`, `z.stringbool()` (not `z.coerce.boolean()`, which makes `"false"` true) or `z.enum`. Repeated keys (`tag=a&tag=b`) and `tag[]=a` give arrays, `filter[status]=open` gives objects, and a lone value for an array field becomes a one-item array.
- Headers and cookies: `headers()` / `cookies()` from `next/headers`, or `req.headers` over HTTP only.
- Validation takes any Standard Schema library that also gives JSON Schema: Zod 4 and ArkType as they are, Valibot wrapped in `toStandardJsonSchema()`.
## Responses
- A returned value is sent as JSON with status 200. `undefined` and `null` send `null`.
- A returned `Response` is sent as it is: `NextResponse.json(data, { status: 201 })` (from `next/server`, so the client keeps the body type), `new Response(null, { status: 204 })`, or with headers.
- With an `output` schema, return the data instead: the output check runs on the returned value, so a `Response` fails it with a 500. Set the status in a decorator, which gets the data after the check:
```ts
import { createDecorator } from 'vovk';
export const status = createDecorator(async (_req, next, code: number) => {
const data = await next();
return code === 204 ? new Response(null, { status: 204 }) : Response.json(data, { status: code });
});
// @post() @status(201) static create = procedure({ body, output }).handle(...)
```
- HEAD gets the GET route's status and headers, without a body.
## Errors
`throw new HttpException(HttpStatus.NOT_FOUND, 'Article not found', cause?)` answers with that status and this body (`cause` only when set):
```json
{ "statusCode": 404, "message": "Article not found", "isError": true, "cause": {} }
```
The generated client throws it again as `HttpException` with the same `statusCode`, `message` and `cause`.
`HttpStatus` names: `OK`, `CREATED`, `ACCEPTED`, `NO_CONTENT`, `BAD_REQUEST`, `UNAUTHORIZED`, `FORBIDDEN`, `NOT_FOUND`, `METHOD_NOT_ALLOWED`, `CONFLICT`, `GONE`, `PAYLOAD_TOO_LARGE`, `UNSUPPORTED_MEDIA_TYPE`, `UNPROCESSABLE_ENTITY`, `TOO_MANY_REQUESTS`, `INTERNAL_SERVER_ERROR`, `NOT_IMPLEMENTED`, `SERVICE_UNAVAILABLE`, and the other standard codes.
What vovk answers by itself, in the same body:From finom/vovk, MIT.
More from finom/vovk
- 0.664score
jsonlines
finom
Vovk.ts JSON Lines streaming — generator handlers (`function*`, `async function*`), the `iteration` validation option, `validateEachIteration`, the…
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
decorators
finom
Vovk.ts decorators — built-in (`@prefix`, `@operation`, `@get/@post/@put/@patch/@del`, `.auto()`) and custom via `createDecorator`.
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
config
finom
Vovk.ts configuration — vovk.config.{mjs,cjs,js} shape, every config key + default (rootEntry, schemaOutDir, libs, exposeConfigKeys, logLevel, devHttps…
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
multitenant
finom
Multi-tenant / multitenancy patterns in Vovk.ts — hosting multiple tenants from one Next.js app via subdomain routing.
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
bundle
finom
Vovk.ts `vovk bundle` CLI — packages composed TypeScript client as zero-dep publishable npm package.
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
tools
finom
Building LLM tools with Vovk.ts — `deriveTools()` (procedures → tools) returning a `StandardToolV0[]` array, standalone tools via the `standard-tool` package…
SkillAFreshness: A★ 54Claude Code +9 - 0.660score
rust
finom
The Vovk.ts Rust client — generating a typed Rust crate from a Vovk API with `vovk-rust`, the `rs` / `rsSrc` templates, the generated async call shape using…
SkillAFreshness: A★ 54Claude Code +9 - 0.660score
openapi
finom
Vovk.ts OpenAPI generation — how the OpenAPI 3.x spec is derived from procedures + validation schemas, the `@operation` decorator family (`@operation({...})`…
SkillAFreshness: A★ 54Claude Code +9 - 0.660score
procedure
finom
Vovk.ts procedures in depth (`base` already has a complete endpoint, validation, errors and status codes) — atomic unit of server-side logic in Vovk project.
SkillAFreshness: A★ 54Claude Code +9 - 0.660score
segment
finom
Vovk.ts segments in depth (`base` already covers the one root segment and its `route.ts`) — the unit of backend slicing in a Vovk project.
SkillAFreshness: A★ 54Claude Code +9 - 0.660score
init
finom
Initialize a backend — via Vovk.ts, a TypeScript-first RPC/API framework plugging into Next.js App Router, using official vovk-cli.
SkillAFreshness: A★ 54Claude Code +9 - 0.660score
mixins
finom
Vovk.ts OpenAPI mixins — importing third-party OpenAPI 3.x schemas as typed client modules that share the same call signature as native Vovk RPC modules.
SkillAFreshness: A★ 54Claude Code +9
Signals
- Stars
- 54
- Forks
- 0
- Open issues
- 0
- Last commit (this folder)
- Oct 20, 2026 (8 days ago)
- Last release
- Oct 22, 2026 (6 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/finom/vovk
- Website
- vovk.dev
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from finom
- 0.664score
multitenant
finom
Multi-tenant / multitenancy patterns in Vovk.ts — hosting multiple tenants from one Next.js app via subdomain routing.
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
bundle
finom
Vovk.ts `vovk bundle` CLI — packages composed TypeScript client as zero-dep publishable npm package.
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
decorators
finom
Vovk.ts decorators — built-in (`@prefix`, `@operation`, `@get/@post/@put/@patch/@del`, `.auto()`) and custom via `createDecorator`.
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
config
finom
Vovk.ts configuration — vovk.config.{mjs,cjs,js} shape, every config key + default (rootEntry, schemaOutDir, libs, exposeConfigKeys, logLevel, devHttps…
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
jsonlines
finom
Vovk.ts JSON Lines streaming — generator handlers (`function*`, `async function*`), the `iteration` validation option, `validateEachIteration`, the…
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
tools
finom
Building LLM tools with Vovk.ts — `deriveTools()` (procedures → tools) returning a `StandardToolV0[]` array, standalone tools via the `standard-tool` package…
SkillAFreshness: A★ 54Claude Code +9
Cite this page
base skill. Agent Mart. https://agentmart.dev/skills/finom-base (last updated 2026-10-24)