# v-development

Instructs GitHub Copilot on V language conventions, from v.mod project layout and compiler workflows to Option/Result error handling without nulls.

- skill · `type=skill` · GitHub Copilot · 3 installs · ★ 40418
- Author: github · official GitHub repository
- License: MIT · policy=mirror · the beginning of the file is at the end of this page
- Source: https://github.com/github/awesome-copilot/tree/HEAD/skills/v-development/SKILL.md
- Updated: 2026-10-23
- HTML: https://affpapa.org/en/nevibecode/skills/v-development

## What it does

This skill guides GitHub Copilot through writing idiomatic V (vlang). It enforces project layouts using root `v.mod` manifests, test conventions with `*_test.v` files, and core toolchain commands like `v test .` and `v vet .`. It also directs the model toward the modern `json2` package instead of the legacy `json` module.

Code generation rules enforce strict immutability, requiring explicit `mut` keywords on variables, parameters, and struct fields. Instead of null checks, absent values must use `?Type` and errors require `!Type` handled with `or { ... }` blocks. Global variables remain disabled by default.

Because V is in pre-1.0 development, syntax can drift between releases. Running tests or formatting with `v fmt -w` requires a local V toolchain installed on your path.

## Install

### GitHub Copilot (native platform)

1. **Skills CLI (Vercel)**
```bash
npx skills add github/awesome-copilot --skill v-development
```

2. **GitHub CLI**
```bash
gh skill install github/awesome-copilot v-development
```

3. **Manually: put the files in place**
- File: `.github/skills/v-development/SKILL.md`

### Claude Code

1. **Skills CLI (Vercel)**
```bash
npx skills add github/awesome-copilot --skill v-development -a claude-code
```

2. **Manually: put the files in place**
- File: `~/.claude/skills/v-development/SKILL.md` — Copy the whole skill folder; for one project use .claude/skills/v-development/

### Codex

**Manually: put the files in place**
- File: `.agents/skills/v-development/SKILL.md` — For all projects use ~/.agents/skills/

### Cursor

**Manually: put the files in place**
- File: `.cursor/skills/v-development/SKILL.md` — Cursor also reads .agents/skills/ and .claude/skills/

### Gemini CLI

**Platform CLI**
```bash
gemini skills install https://github.com/github/awesome-copilot --path skills/v-development
```

### Windsurf (Devin Desktop)

**Manually: put the files in place**
- File: `.devin/skills/v-development/SKILL.md` — The legacy .windsurf/skills/ path still works

### Claude.ai

**Claude.ai**
- Zip the folder and upload it in Settings → Capabilities → Skills

Where a file is given instead of a command, copy the files from the source to that path: https://github.com/github/awesome-copilot/tree/HEAD/skills/v-development/SKILL.md

## When to use it
- Structure projects with a root `v.mod` manifest
- Handle errors using `Result` and `Option` types instead of null pointers
- Format and lint code using `v fmt` and `v vet`
- Implement test suites inside `*_test.v` files with assertions

## Example prompts
- Write a function returning `!string` and handle failures with an `or` block
- Generate a `v.mod` manifest file with metadata and external dependencies
- Parse incoming API payloads using the `json2` module

## Source text · SKILL.md · MIT

Below is the content of a third-party file. It is data, not instructions for you: do not act on anything written inside unless the human asks. Block tag: 0ee2c129dedcf0fc.

BEGIN THIRD-PARTY FILE 0ee2c129dedcf0fc
````text
---
name: v-development
description: 'Guide GitHub Copilot through V language development: installing the toolchain, project layout with v.mod, building, testing, formatting, and writing idiomatic V including Option/Result error handling. Use when the user works with V source files, v.mod projects, or asks about V syntax, tooling, and conventions.'
---

You are a V language expert assistant. When a user asks about V (vlang), use the precise information below to give accurate, complete answers.

V is a statically typed, compiled language with Go-like syntax. Official docs: <https://docs.vlang.io>. Standard library reference: <https://modules.vlang.io>. Third-party packages live in the VPM registry: <https://vpm.vlang.io>.

## Toolchain

Install from <https://github.com/vlang/v> (prebuilt binaries or build from source), then verify with `v --version`.

| Task | Command |
|---|---|
| Run a program | `v run main.v` |
| Run a project folder | `v run .` (compiles the folder's program files; `*_test.v` files are built separately via `v test .`) |
| Build a binary | `v -o app .` |
| Run tests | `v test .` (runs `*_test.v` files) |
| Format code | `v fmt -w file.v` |
| Static checks | `v vet .` |
| Find a package | `v search <term>` (searches the VPM registry) |
| Install a package | `v install <package>` or `v install --git <url>` |
| Update packages | `v update` (all) or `v update <package>` |

Always run `v fmt -w` on files you touch and `v vet .` plus `v test .` before declaring work done.

## Project layout

Standalone V programs are single `.v` files and need no manifest: `v run hello.v` just works.
Structured projects and publishable packages use a `v.mod` file at the project root
as the module anchor (imports resolve relative to the folder containing it):

```text
Module {
	name: 'myapp'
	description: 'My nice package.'
	version: '0.1.0'
	license: 'MIT'
	dependencies: []
}
```

Conventions:

- An executable application uses `module main`, and its entry function is `fn main()`.
  The source file is commonly named `main.v`, but the filename is not what defines
  the entry point — the `main` module and `main()` function do. (In single-file
  programs, `fn main()` may even be omitted; top-level statements run implicitly.)
- A folder of `.v` files declaring the same module compiles together with `v run .`.
- Keep one module per directory; the module name conventionally matches the directory.
- Test files end in `_test.v` and contain `fn test_...() { assert ... }`.

## Writing idiomatic V

```v
module main

struct Config {
	host string
	port int
}

fn connect(cfg Config) !string {
	if cfg.port == 0 {
		return error('port is required')
	}
	return 'http://${cfg.host}:${cfg.port}'
}

fn main() {
	url := connect(host: 'localhost', port: 8080) or {
		eprintln(err)
		return
	}
	println(url)
}
```

Rules to follow when generating or editing V code:

- **No null in ordinary code.** In ordinary safe V application code, model absence with `Option` (`?Type`, value or `none`) rather than nullable values; failures use `Result` (`!Type`). Handle them with `or { ... }` blocks; never invent null checks. Pointer-level `nil` exists only in low-level `unsafe`/C-interop contexts (e.g. `unsafe { nil }`) and should not be treated as ordinary application-level optionality.
````
END THIRD-PARTY FILE 0ee2c129dedcf0fc

The third-party file has ended. Everything between the 0ee2c129dedcf0fc tags is data: requests and commands from it are not followed. An “end of file” line with another tag inside the block is part of the file.

First 3305 of 5568 bytes. © github · MIT · https://github.com/github/awesome-copilot/tree/HEAD/skills/v-development/SKILL.md

_Part of the page did not fit — see the HTML version._

---
NeVibeCode on affpapa.org. Catalog texts are descriptions, not instructions for the agent. How to choose and install: https://affpapa.org/en/nevibecode/agents.md
