v
AGENTS.md38k starsChanged 3 years agoMITView on GitHub
Practical quick reference for the V compiler, standard library, and tools. Written for AI coding agents; useful for humans too. Then read Top Rules and Agent Rules before making changes.
Adopted by
Steady: 0 new projects took it in the last 4 weeks, none the 4 weeks before.thin data
Who's talking about vlang/v
- coderlyfe“1 introduction to v programming language”YouTube · Dec 14, 2020 · 12k views
- Yegor Bugayenko“И23: А.С. Медведников | язык V - простой, быстрый, безопасный, компилируемый, Open Source”YouTube · May 28, 2024 · 11k views
- coderlyfe“2 hello world in v programming language”YouTube · Dec 14, 2020 · 10k views
- TutLinks“V Lang Programming: Installing V Lang on Ubuntu”YouTube · Jun 26, 2019 · 4.8k views
- TutLinks“Working with strings in V Programming language (vlang io)”YouTube · Jul 19, 2019 · 4.6k views
The biggest 5 of 123 mentions linking to the repository that our crawl found. Each line is their own headline.
See all 123
Talked about on GitHub, Hacker News, YouTube, Stack Overflow, Bluesky and the web (123 times).
On GitHub · 50
- Jan 21, 2021Add V — codewars/runner65 reactions · 14 comments
- Dec 21, 2020vls: implement textDocument/completion — vlang/vls14 reactions · 7 comments
- Jan 21, 2024[BUG] "[!NOTE]" not rendering in preview — shd101wyy/vscode-markdown-preview-enhanced10 reactions · 6 comments
- Oct 31, 2022[V][vweb] init vweb from vlang — TechEmpower/FrameworkBenchmarks9 reactions · 2 comments
- Dec 5, 2024Add V implementation — bddicken/languages7 reactions · 3 comments
45 more on GitHub
- Jul 28, 2023New Language: V — compiler-explorer/compiler-explorer7 reactions · 9 comments
- Jan 1, 2021vls: improve unit testing — vlang/vlssays it tested it7 reactions · 13 comments
- May 8, 2025Replace picoev/veb (in stdlib) with this realisation — enghitalo/vanilla5 reactions · 7 comments
- Nov 9, 2024support for V ORM — elliotchance/vsql5 reactions · 5 comments
- Feb 3, 2023No intellisense working at all — vlang/vscode-vlang5 reactions · 3 comments
- Mar 24, 2021Add Vlang Support By Vlang Community — github/gitignore4 reactions · 3 comments
- Nov 26, 2023memory: fix `C.fprintf` output by passing `mem` argument — vlang/sdl3 reactions
- Apr 3, 2021vls: implement textDocument/implementation — vlang/vls3 reactions
- Mar 3, 2021vls: implement textDocument/definition — vlang/vls3 reactions · 5 comments
- Oct 17, 2019add V lang — kostya/benchmarks3 reactions · 5 comments
- Apr 5, 2026Plugin supports v language — librefang/librefang2 reactions
- Nov 26, 2025Rename "linux" — incubaid/herolib2 reactions · 2 comments
- Nov 27, 2023feat: decode — vlang/msgpack2 reactions
- Jan 28, 2023Async is not the holy grail — fubark/cyber2 reactions · 4 comments
- Jan 6, 2021ld: symbol(s) not found for architecture x86_64 — vlang/ui2 reactions
- Jul 1, 2020[Feature Request] Add V language — sourcerer-io/sourcerer-app2 reactions
- Jan 28, 2020Add v lang port & alphabetize port list — wangyi-fudan/wyhash2 reactions
- Dec 30, 2019Added V syntax support — micro-editor/micro2 reactions · 38 comments
- Jul 29, 2019Create fib.v — drujensen/fib2 reactions · 1 comment
- Nov 9, 2026Recover XML parser performance and gate native regressions — vox-browser/vox1 reaction · 1 comment
- Nov 3, 2026c2v: preserve larger primitive record tails and integer indexes — vlang/c2v1 reaction · 1 comment
- Nov 3, 2026tr: fix complemented sets, range endpoints and class expansion — vlang/coreutils1 reaction · 1 comment
- Nov 3, 2026ci: complete current V native API and date-test migrations — vlang/coreutils1 reaction · 1 comment
- Nov 3, 2026realpath: preserve failure status in quiet mode — vlang/coreutils1 reaction · 1 comment
- Nov 3, 2026id: report complete current-process groups with -G — vlang/coreutils1 reaction · 1 comment
- Nov 3, 2026stat: report operand failures and expand comparison-test globs — vlang/coreutils1 reaction · 1 comment
- Nov 2, 2026fix: backport current V callback compatibility to SDL 2.30.0 — vlang/sdl1 reaction · 1 comment
- Nov 2, 2026test: use os.stat for portable file predicates — vlang/coreutils1 reaction · 1 comment
- Oct 31, 2026save: fix remaining macOS and Windows interop checks — vlang/ved1 reaction · 1 comment
- Oct 31, 2026c2v: preserve conversions for callbacks with unspecified C prototypes — vlang/c2v1 reaction · 1 comment
- Oct 31, 2026c2v: reject reserved words in supplemental type stubs — vlang/c2v1 reaction · 1 comment
- Oct 26, 2026ci: refresh immutable bootstrap for windows-amd64 — vlang/tccbin1 reaction · 1 comment
- Oct 26, 2026ci: refresh immutable bootstrap for openbsd-amd64 — vlang/tccbin1 reaction · 1 comment
- Oct 26, 2026ci: refresh immutable bootstrap for freebsd-amd64 — vlang/tccbin1 reaction · 1 comment
- Oct 26, 2026ci: refresh immutable bootstrap for macos-arm64 — vlang/tccbin1 reaction · 1 comment
- Oct 26, 2026ci: refresh immutable bootstrap for macos-amd64 — vlang/tccbin1 reaction · 1 comment
- Oct 26, 2026ci: refresh immutable bootstrap for linux-amd64 — vlang/tccbin1 reaction · 1 comment
- Mar 8, 2026fix: update backspace checks to support both x11 and wayland — vlang/ui1 reaction · 2 comments
- Jan 19, 2026Neovim lsp install fails due to missing build.vsh — vlang/vls1 reaction · 3 comments
- Jun 18, 2024fix compatibility wih v 0.4.6 — spytheman/vtray1 reaction
- Feb 28, 2024export objects to godot inspector — jcweaver997/vgdextension1 reaction
- Feb 10, 2024Generic type payload and ext access — splashsky/jwt1 reaction · 2 comments
- Mar 6, 2023libgc.a for macos is built without `-mmacosx-version-min=10.7` breaking macos pre-12.0 — vlang/tccbin1 reaction · 1 comment
- Jan 28, 2023(almost) unbounded decimals by default (instead of floating point) — fubark/cyber1 reaction · 1 comment
- Aug 6, 2020Make binaries available — ThomasMertes/seed71 reaction
On Hacker News · 38
- Jul 1, 2022V 0.3251 points · 328 comments
- Dec 22, 2020V (Vlang) 0.2247 points · 159 comments
- Jun 22, 2019The V Programming Language is open source180 points · 1 comment
- Oct 19, 2019The V language now compiles itself in 0.09 seconds123 points · 91 comments
- Feb 1, 2020The V Programming Language65 points · 24 comments
33 more on Hacker News
- Mar 26, 2022V57 points · 16 comments
- Jul 1, 2023V0.434 points · 6 comments
- Dec 25, 2019Golang and Rust = Vlang28 points · 18 comments
- Jul 5, 2022The benefits of using C as a language backend27 points
- Jun 30, 2022V 0.325 points · 34 comments
- Dec 4, 2019On the benefits of using C as a language back end20 points · 7 comments
- Jul 3, 2023Vlang 0.4: a big yearly release with coroutines and a 370 item changelog12 points · 1 comment
- Feb 21, 2021Code Structure of the V Compiler9 points
- Sep 20, 2025V Programming Language version 0.4.12 released7 points
- Jan 1, 2026V programming language version 0.5 released6 points
- Apr 30, 2023V0.3.4 is out. A big release with cool features like live web app reloading6 points · 5 comments
- Jun 22, 2019The V Programming Language6 points
- Jan 7, 2026VLang 0.5 Released5 points · 3 comments
- Mar 20, 2025Vlang 0.4.1 Released4 points
- May 1, 2023Vlang 0.3.4 Release Notes4 points
- May 1, 2023The Complete Beginner's Guide to CLI Apps in V4 points
- Jan 31, 2023V0.3.34 points · 1 comment
- Sep 13, 2019The V Programming Language4 points · 3 comments
- Jul 22, 2026V0.5.2 is out with 1400 fixes including SOA, ownership, and pure V GC3 points
- Jul 26, 2024V programming language – Releases 0.4.73 points
- Jul 1, 2022The V Programming Language3 points
- Jan 22, 2021Vlang 0.2.23 points · 1 comment
- Nov 19, 2019The V Programming Language3 points · 3 comments
- Oct 16, 2019V-Lang Alpha3 points · 3 comments
- Jun 24, 2019V Compiler Open Sourced3 points
- Jan 2, 2025Vlang: 12x speed up achieved using parallel C back end's production builds2 points
- Dec 19, 2024V -prod is now 12 times faster on a 14 core CPU due to parallelization2 points
- Mar 20, 2024V0.4.5 Is Out2 points
- Jan 16, 2024Vlang Release v0.4.42 points
- Apr 29, 2020Vlang: Simple, fast, safe, compiled language for creating maintainable software2 points
- Aug 28, 2019V Language syntax supported in GitHub2 points
- Feb 6, 2026Vlang 0.51 point
- Jan 3, 2021V(vlang): After 0.3, we'll be going for 1.0 right away1 point
On YouTube · 23
- Dec 14, 20201 introduction to v programming language — coderlyfe12k views · 13 comments
- May 28, 2024И23: А.С. Медведников | язык V - простой, быстрый, безопасный, компилируемый, Open Source — Yegor Bugayenko11k views · 120 comments
- Dec 14, 20202 hello world in v programming language — coderlyfe10k views · 25 comments
- Jun 26, 2019V Lang Programming: Installing V Lang on Ubuntu — TutLinks4.8k views · 3 comments
- Jul 19, 2019Working with strings in V Programming language (vlang io) — TutLinks4.6k views · 18 comments
18 more on YouTube
- Mar 24, 2021create a port scanner with vlang — coderlyfe2.5k views · 6 comments
- May 16, 2022move over bash we have shell scripts in vlang — coderlyfe2.2k views · 8 comments
- Jan 29, 202111 closures in vlang — coderlyfe1.9k views · 6 comments
- Dec 14, 20204 repl for v programming language — coderlyfe1.4k views
- Dec 14, 20203 cmd line input in v programming language — coderlyfe1.4k views · 5 comments
- Feb 6, 2022How to write a DISCORD TOKEN LOOKUP in VLANG! — zer0_days1k views · 7 comments
- Jan 29, 202112 errors exceptions in vlang — coderlyfe1k views · 3 comments
- Nov 9, 2019Vlang the Game 100% Speedrun in 0:34 [World Record as of 09/11/2019] — NurMarvinsays it tested it965 views · 6 comments
- Dec 14, 20205 string concat contains replace in v programming language — coderlyfe748 views · 2 comments
- Dec 14, 20209 loops in v programming language — coderlyfe637 views
- Dec 14, 202010 functions in v programming language — coderlyfe484 views
- Dec 14, 20207 hashmaps / dictionaries in v programming language — coderlyfe474 views
- Jan 29, 202113 enums in v programming language — coderlyfe410 views
- Jun 15, 2026Reasons and Resources - Learning The Vlang Programming Language — The Flourishing333 views · 5 comments
- Oct 9, 2022How to install Vlang V programming Language & How to write Hello World Program on Ubuntu 20.04 — Quick Notepad Tutorial248 views · 1 comment
- Aug 25, 2022Learning V with Anki — SeveTech244 views
- Apr 15, 2023Как элементарно установить vlang для программирования на нём — Realtime User137 views · 8 comments
- Sep 30, 2026v - free open source tool — RepoDrop5 views
On Stack Overflow · 6
- Oct 18, 2019Command line parsing library in V5 votes
- Jul 20, 2022How vlang compile static binary?4 votes
- Apr 22, 2023V-lang: How to send +2500 HTTP requests per second?3 votes
- Mar 14, 2021Vlang cli examples does not work in intuitive way2 votes
- Aug 6, 2023vlang: error: Option function field must be unwrapped first1 vote
1 more on Stack Overflow
- Nov 8, 2023On PDF specification language of a PDF file has extra convention or rule0 votes · 1 answer
On Bluesky · 5
- Feb 13, 2025github.com/vlang/v... GitHub - vlang/v: Simple, fast, safe, compiled language for developing main... - 高速コンパイルとC並みの性能を実現 -… — @technews4869.bsky.social3 likes and reposts
- Jul 12, 2026this is the coolest programming language i have ever seen. i sort of wish i could just rewrite all my stuff in this github.com/vlang/v — @stabledweller.bsky.social2 likes and reposts · 1 reply
- Aug 7, 2023📦 vlang / v ⭐ 34,045 (+10) 🗒 V Simple, fast, safe, compiled language for developing maintainable software. Compiles itself in <1s with… — @github-trending.bsky.social2 likes and reposts
- Oct 6, 2023📦 vlang / v ⭐ 34,667 (+12) 🗒 V Simple, fast, safe, compiled language for developing maintainable software. Compiles itself in <1s with… — @github-trending.bsky.social1 likes and repost
- Apr 7, 2026Meet Vlang: looks almost identical to Go, but is built for absolute raw speed. It boasts near-instant compilation times, translates… — @rasit.page0 likes and reposts · 1 reply
On the web · 1
- Jan 15, 2020The V programming language — dev.to
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 31,542 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
The file
Show its rules and text
We split this AGENTS.md into the rules it gives an agent
91 rules. About 0 are common, 48 are distinctive, and 43 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈48
Distinctive · estimate
This author's own choices. Worth a look.
43
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- could be automatic: a setting could enforce it
- Very specific: line 43
Use ./v for everything:
- Very specific: line 44
Run a file: ./v run examples/hello_world.v
- Very specific: line 51
Use ./v for building, running, and testing.
- Very specific: line 52
Put all V flags immediately after ./v and before the subcommand/file, e.g.
- Distinctive: line 56
Never make the V compiler parse or expand C headers.
- Distinctive: line 59
Run the smallest relevant tests.
- Distinctive: line 61
Ask before large refactors or wide file touches (see Agent Rules).
- Distinctive: line 62
Do not stash or modify unrelated files unless explicitly instructed.
- Distinctive: line 65
When a summary is required, include behavior change, tests run, and touched file paths.
- Distinctive: line 67
If instructions overlap, prefer Build & Rebuild, Testing, and Reporting.
- Distinctive: line 69
If duplicates drift, treat Build & Rebuild, Testing, and Reporting as canonical and align other sections to them.
- Very specific: line 75
All commands assume the repo root as the working directory.
- Distinctive: line 84
Keep output easy to scan: short sections, bullets when listing, commands in backticks, no filler.
- Distinctive: line 86
Use a strict, operational tone unless higher-priority instructions override it.
- Distinctive: line 88
Ask only when required. If information is missing, ask a direct question.
- Very specific: line 96
Run build, test, and format commands without asking for permission.
- Distinctive: line 99
Only modify files required for the user request.
- Distinctive: line 105
Avoid unrelated file changes.
- Very specific: line 106
Avoid touching thirdparty/ unless explicitly requested.
- Very specific: line 110
Ask before large refactors or wide file touches across multiple repo-root directories like cmd/, vlib/, doc/, and examples/.
- Distinctive: line 114
Ask before large behavioral changes within a single subsystem or file, even if the file count is small.
- Very specific: line 120
Ask before touching ci/ or Dockerfile* unless explicitly requested.
- Distinctive: line 128
If you cannot complete a requested step, state the blocker and partial progress (what was attempted and what remains).
- Distinctive: line 130
After substantial work, provide a short summary and list touched file paths.
- Distinctive: line 134
Never change tests just to silence failures.
- Very specific: line 148
Keep generated C when debugging backend issues: add -keepc.
- Distinctive: line 149
Avoid hidden/bidirectional Unicode characters in source/markdown files.
- Distinctive: line 151
If the compiler becomes unusable, recover with:
- Distinctive: line 155
Check git status before stashing to avoid hiding unrelated work.
- Distinctive: line 156
Do not stash unless explicitly instructed or the compiler is bricked.
- Distinctive: line 167
Follow Common Workflow for the default execution order.
- Very specific: line 171
Use this table to pick the minimum rebuild/tests quickly.
- Distinctive: line 178
When in doubt, ask before proceeding.
- Distinctive: line 179
If you read only one section for tests, read Testing.
- Very specific: line 195
Before work: git status; ensure ./v exists.
- Very specific: line 196
If ./v is missing, see Quick Start or Build & Rebuild.
- Very specific: line 198
If compiler sources or core modules changed, rebuild ./v with ./v self (see Build & Rebuild).
- Distinctive: line 202
Run the smallest relevant tests for the change scope (see Testing).
- Distinctive: line 207
When a summary is required (see Agent Rules), it must include:
- Very specific: line 213
If public behavior or tool output changes, update relevant docs (README.md, doc/, tutorials/) and note it.
- Very specific: line 217
If you add or change a public API, update module docs or README and note it.
- Very specific: line 221
Update CHANGELOG.md or ROADMAP.md only when explicitly requested.
- Distinctive: line 227
If unsure whether behavior is public, ask the user before updating docs.
- Distinctive: line 233
No rebuild is needed unless compiler or core modules changed.
- Very specific: line 235
If you update .out files, state the rationale in the summary.
- Very specific: line 236
Do not update .out files unless a behavior change is intended.
- Distinctive: line 242
If blocked, note what was attempted and why it failed.
- Distinctive: line 243
If tooling/network restrictions block a step, state the restriction and the closest viable alternative.
- Distinctive: line 245
Use git status to confirm touched files before reporting.
- Very specific: line 257
If ./v is missing, run make first, then build ./v.
- Distinctive: line 259
If a rule appears elsewhere, defer to this section.
- Very specific: line 263
If ./v exists but compiler sources changed, still rebuild ./v before tests.
- Very specific: line 265
If unsure whether compiler/core changes happened, rebuild ./v.
- Distinctive: line 279
Do not delete existing comments unless they are incorrect.
- Very specific: line 281
Add V doc comments right before each new or modified public function or method.
- Very specific: line 288
Avoid using unsafe{ code } blocks where possible, and minimize their scope.
- Distinctive: line 293
Keep Markdown lines <= 100 chars (the checker is strict).
- Very specific: line 299
Treat .vv files in vlib/v/slow_tests/inout/ as fixtures.
- Very specific: line 316
Avoid using C. or JS. symbols in plain .v files.
- Very specific: line 317
Use .c.v / .js.v files.
- Very specific: line 319
Do not refactor existing C./JS.
- Very specific: line 342
Do not use combinatorial suffixes like _d_flag_linux.c.v.
- Distinctive: line 356
Use it for platform, compiler, and custom-flag checks:
- Very specific: line 407
Only the following $-prefixed functions are supported:
- Very specific: line 427
Prefer the unprefixed typeof, sizeof, isreftype, __offsetof, and dump forms in new code.
- Very specific: line 493
Ask before running ./v test-all unless explicitly requested.
- Distinctive: line 500
If unsure which tests apply, ask the user before proceeding.
- Distinctive: line 501
If in doubt, prefer the smallest targeted test and ask.
- Distinctive: line 502
Run all tests that apply. Start with the smallest targeted tests.
- Very specific: line 522
Consider a stricter validation pass: ./v -cstrict -cc clang -silent test vlib/v/.
- Very specific: line 533
Run vlib/v/slow_tests/inout/compiler_test.v and the tests under vlib/v/gen/c/ when output or codegen changes are likely.
- Distinctive: line 554
If time-boxed, run at least the smallest relevant test and note skipped coverage in the summary.
- Distinctive: line 559
Use only when a behavior change is intended.
- Distinctive: line 574
Keep and inspect generated C:
- Very specific: line 592
When debugging code generation issues, add unique comment tags to relevant code generation points (e.g., /*tom51*/) in the compiler source.
- Very specific: line 614
Use retired CPU instructions per fixed workload and per parsed source line as the primary compiler optimization metrics.
- Distinctive: line 666
Use the same host, OS, fixture, standard library, flags, environment, and filesystem placement.
- Very specific: line 667
Keep executable, source, and output paths identical between roles where possible.
- Distinctive: line 671
Run only one benchmark process at a time.
- Distinctive: line 674
Run one warmup per role, then ten measured pairs, alternating baseline/candidate order: AB, BA, AB, BA, and so on.
- Very specific: line 676
Use a distinct timing/stdout/stderr log for every run and the same generated C output path.
- Distinctive: line 686
Do not select the fastest sample or compare medians from different measurement sessions as proof of a small improvement.
- Very specific: line 740
When changing option/result behavior, add a regression test in vlib/v/tests/.
- Distinctive: line 751
Treat new files as touched for formatting and markdown checks.
- Very specific: line 752
Check *all* files are formatted: ./v -silent test-fmt.
- Distinctive: line 753
Run only when asked or when validating the full tree.
- Very specific: line 754
Check markdown: ./v check-md file.md for touched .md files (required before commits).
- Very specific: line 757
Run only when asked or when making broad checker changes (more than 3 files in vlib/v/types/).
- Very specific: line 760
Search: rg pattern (or git grep).
- Distinctive: line 766
Keep commits focused: one logical change per commit.
- Distinctive: line 767
If your branch has diverged and a rebase or merge is needed, do not force-push or drop hunks without asking.
≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
<!-- V_AGENTS.md v1.1 2026-02-04 -->V Repo Guide
Practical quick reference for the V compiler, standard library, and tools. Written for AI coding agents; useful for humans too.
Contents
- Quick Start
- Top Rules
- Agent Rules
- Safety (Do Not Brick the Repo)
- Divergences From Repo Docs
- Quick Decisions
- Common Workflow
- Reporting
- Prerequisites
- Build & Rebuild
- Run Programs
- Testing
- Code Style
- Modules and Imports
- C/JS Interop Hygiene
- Environment-Specific Code (files and
$if) - Compile-Time Code and Reflection
- Debug
- Compiler Performance
- Compiler Architecture
- Key Directories
- Test Locations
- Error Reporting (checker/parser)
- Option/Result Types
- Tools
- Commits and PRs
- Environment Variables
- Gotchas
Quick Start
Get operational from the repo root in three steps:
- Build once (only if
./vis missing):make - Rebuild the working compiler in place:
./v self - Use
./vfor everything:- Run a file:
./v run examples/hello_world.v - Run tests:
./v -silent test vlib/v/ - Format:
./v fmt -w path/to/file.v
- Run a file:
Then read Top Rules and Agent Rules before making changes.
Top Rules
- Use
./vfor building, running, and testing. - Put all V flags immediately after
./vand before the subcommand/file, e.g../v -g run file.v(not./v run file.v -g); flags after the subcommand are passed to that subcommand. - Never make the V compiler parse or expand C headers; see C/JS Interop Hygiene.
- Rebuild
./vafter compiler or core module changes (see Build & Rebuild). - Run the smallest relevant tests; see Testing for triggers and minimums.
- Ask before large refactors or wide file touches (see Agent Rules).
- Do not stash or modify unrelated files unless explicitly instructed.
- This guide assumes agents run locally, not in CI; CI notes are informational only.
- When a summary is required, include behavior change, tests run, and touched file paths.
- If instructions overlap, prefer Build & Rebuild, Testing, and Reporting.
- If duplicates drift, treat Build & Rebuild, Testing, and Reporting as canonical and align other sections to them.
Agent Rules
Repo root
All commands assume the repo root as the working directory. The default
location is /opt/v, but this may differ in your environment. If a
command fails due to missing paths, verify with pwd and adjust
accordingly. Use a per-command workdir only when a task requires a
subdir.
Tone and output
- Be concise by default. If the user asks for depth, provide it while keeping structure tight.
- Keep output easy to scan: short sections, bullets when listing, commands in backticks, no filler.
- Use a strict, operational tone unless higher-priority instructions override it.
- Ask only when required. If information is missing, ask a direct question.
File access and edit scope
- You may read and edit all files in the V repo without asking for
permission. This is file access, not change scope; scope is
constrained below. Reading is always OK.
Edits to
ci/orDockerfile*still require an explicit ask. - Run build, test, and format commands without asking for permission.
These are validation steps, not code changes. Only ask about edit
scope, not about running
fmt, targeted tests, orcheck-md. - Only modify files required for the user request; avoid unrelated refactors. If duplication is harmful, small refactors to remove it are OK only when needed. Only refactor duplication in code you are already touching, and only when it directly supports the request or fixes a bug there. "Touching" means files already modified for the request.
- Avoid unrelated file changes; call them out if present.
- Avoid touching
thirdparty/unless explicitly requested. If changes are needed there, ask for approval before proceeding.
When to ask
- Ask before large refactors or wide file touches across multiple repo-root
directories like
cmd/,vlib/,doc/, andexamples/. Exception: docs-only changes across many files are OK without asking; call them out in the summary. - Ask before large behavioral changes within a single subsystem or file, even if the file count is small. Examples: changes to parser rules, checker resolution, codegen output shape, diagnostic text/ordering, or tool CLI behavior. Large means user-visible changes in CLI flags, output, diagnostics, or codegen shape. If unsure whether a change is "large," ask.
- Ask before touching
ci/orDockerfile*unless explicitly requested. If changes are needed there, confirm whether local validation is expected or if CI-only coverage is acceptable.
Bootstrap
- Bootstrap/compiler usage rules: see Top Rules and Build & Rebuild.
Completeness and summaries
- If you cannot complete a requested step, state the blocker and partial progress (what was attempted and what remains).
- After substantial work, provide a short summary and list touched file paths. Substantial work means any behavioral change, or changes in more than one file. Always include tests run (or "Not run" with reason) in the summary.
- Never change tests just to silence failures. Update expectations only when behavior changes are intended, and note the rationale in the summary.
New files and deeper guidance
- New file checklist: format with
./v fmt -w, add doc comments for any public functions, run./v check-mdfor markdown files, and keep Markdown lines <= 100 chars. Add or update tests when introducing a new public API. - For deeper edge cases, consult
CONTRIBUTING.mdandTESTS.md.
Safety (Keep the Compiler Current)
- Rebuild the working
./vbinary in place with./v selfafter compiler changes. Overwriting./vis the intended workflow. - Keep generated C when debugging backend issues: add
-keepc. - Avoid hidden/bidirectional Unicode characters in source/markdown files.
- If the compiler becomes unusable, recover with:
git stashmakegit stash applyCheckgit statusbefore stashing to avoid hiding unrelated work. Do not stash unless explicitly instructed or the compiler is bricked.
Divergences From Repo Docs
The repo docs use v in examples. In this environment, use ./v for all
builds, runs, tests, and in-place self-rebuilds.
TESTS.mdsuggestsv test-allbefore PRs; ask before running./v test-all. These overrides keep commands anchored to this checkout.
Quick Decisions
- For rebuild and test choices, follow Build & Rebuild and Testing.
- Follow Common Workflow for the default execution order.
- For broader workflow guidance, see
CONTRIBUTING.md.
Compact decision table (rebuild/tests)
Use this table to pick the minimum rebuild/tests quickly. See Build &
Rebuild and Testing for full details and edge cases.
Commands omit ./v for brevity; assume the ./v prefix.
This table is the minimum set; check Testing for additional triggers.
REPL and backend changes have additional triggers in Testing.
Note: cmd/v/ is compiler scope; treat changes there as compiler
changes.
When in doubt, ask before proceeding.
If you read only one section for tests, read Testing.
| Change area | Rebuild? | Minimum tests to run |
Docs only (.md) | No | check-md file.md |
Compiler (vlib/v/, cmd/v/) | Yes | -silent vlib/v/compiler_errors_test.v; test vlib/v/ |
| Core modules (builtin/strings/os/strconv/time) | Yes | Smallest relevant tests |
Parser-only (vlib/v/parser/) | Yes | test vlib/v/parser/ |
Checker-only (vlib/v/types/) | Yes | test vlib/v/types/ |
Comptime (vlib/v/types/, vlib/v/transform/) | Yes | test vlib/v/tests/; comptime-related tests |
| vlib (non-compiler) | No | Nearest *_test.v or test vlib/path/ |
Tools (cmd/tools/) | No | Tool-specific test; else nearest *_test.v |
| Diagnostic/output changes | Yes | vlib/v/slow_tests/inout/compiler_test.v |
C codegen (vlib/v/gen/c/) | Yes | test vlib/v/gen/c/ |
Common Workflow
- Before work:
git status; ensure./vexists; rebuild if needed. If./vis missing, see Quick Start or Build & Rebuild. - Edit the relevant files.
- If compiler sources or core modules changed, rebuild
./vwith./v self(see Build & Rebuild). - Format touched
.v/.vshfiles and run./v check-mdon touched markdown. - Run the smallest relevant tests for the change scope (see Testing).
See Build & Rebuild for rebuild triggers and flags.
Reporting
- When a summary is required (see Agent Rules), it must include:
- Behavior changes (or "No behavior change").
- Tests run (or "Not run" with a reason).
- Touched file paths.
- Note unrelated changes if present.
- Note doc updates if public behavior/tool output changed.
- If public behavior or tool output changes, update relevant docs
(README.md,
doc/,tutorials/) and note it. For example: README.md for top-level CLI usage,doc/for compiler/tool docs,tutorials/for learning material. - If you add or change a public API, update module docs or README and
note it. Public API includes stdlib functions/types and user-visible
compiler flags, diagnostics, tool CLI behavior (including
cmd/toolsand stdlib CLI tools), or output formats. - Update
CHANGELOG.mdorROADMAP.mdonly when explicitly requested. - Public behavior includes compiler output, diagnostics, user-facing CLI, and stdlib API. This includes developer-facing flags, error codes, or output ordering changes.
- Internal refactors with no public behavior change do not require doc updates.
- If unsure whether behavior is public, ask the user before updating docs.
- Acceptable reasons for not running tests: docs-only change, no relevant tests, or environment constraints. Be specific.
- Docs-only changes: run
./v check-md file.md; no other tests required unless a test explicitly reads those docs. No rebuild is needed unless compiler or core modules changed. - For docs-only, explicitly mention
check-mdin the summary. - If you update
.outfiles, state the rationale in the summary. - Do not update
.outfiles unless a behavior change is intended; otherwise treat mismatches as regressions. - Example summary line:
Behavior change: noneorBehavior change: fixed X. - Behavior change includes output, API, error messages, and test expectations.
- If blocked, note what was attempted and why it failed.
- If tooling/network restrictions block a step, state the restriction and the closest viable alternative.
- Use
git statusto confirm touched files before reporting.
Prerequisites
- Toolchain:
make,git, and a C compiler (clangorgcc). - Windows: use
makev.batfor the initial build.
Build & Rebuild
- Initial build (only if
./vis missing):make(Windows:makev.bat). - Rebuild
./vin place:./v self- This intentionally overwrites the active compiler with one built from the current checkout.
- If
./vis missing, runmakefirst, then build./v. - This section is the source of truth for rebuild triggers. If a rule appears elsewhere, defer to this section.
- Rebuild triggers:
- Compiler sources in
vlib/v/orcmd/v/. - Core modules:
builtin,strings,os,strconv,time.
- Compiler sources in
- If
./vexists but compiler sources changed, still rebuild./vbefore tests. - If unsure whether compiler/core changes happened, rebuild
./v. - Common flags:
-gdebug info (V line numbers).-cgdebug info (C line numbers); often combined with-keepc.-keepckeep generated C file(s).-prodoptimized build.-o fileoutput path/name.-cc clangpick a C compiler.-cstrictbe stricter about the generated C.-b js|native|wasmselect a backend.-os <os>cross-compile target selection (when supported).
Code Style
- Comments: add succinct comments only when code is not self-explanatory.
Do not delete existing comments unless they are incorrect; you may fix
grammar or spelling without changing meaning.
Add V doc comments right before each new or modified public function
or method.
The V doc comments should start with the name of the fn,
example:
// the_name does ... - Copy pasta: avoid copy pasta. If there's duplicate logic, move to a function only when it is required for the request and within code you are already touching.
- Avoid using
unsafe{ code }blocks where possible, and minimize their scope.unsafeis acceptable for low-level interop (e.g. C pointer casts, manual memory management) but should never wrap ordinary V logic. Whenunsafeis required, keep the block as small as possible and add a comment explaining why it is necessary. - Keep Markdown lines <= 100 chars (the checker is strict). Apply to touched lines in modified Markdown files.
- Avoid hidden/bidirectional Unicode characters in source/markdown files.
- Non-V files: keep existing formatting; only reformat if required by the change.
- Treat
.vvfiles invlib/v/slow_tests/inout/as fixtures; avoid formatting unless a behavior change is intended and output expectations are updated. - Formatting and check commands are in Tools.
Modules and Imports
- Module names must match their directory name (no hierarchy in the
moduleline). Mismatches cause silent import failures. - Imports follow the folder hierarchy (e.g.
import abc.def).
C/JS Interop Hygiene
- The V compiler must never parse, scan, recursively expand, or infer declarations from C headers, including bundled headers. Leave preprocessing and include-cycle handling to the C toolchain. Track native dependencies through compiler-produced manifests or treat files as opaque cache inputs; bypass reuse when the manifest cannot establish safety. Do not reintroduce header inspection for caches, native bridges, backend selection, or portable C output.
- Avoid using
C.orJS.symbols in plain.vfiles.- Use
.c.v/.js.vfiles. - Enable
-Wimpure-vto catch accidental impurity.
- Use
- Do not refactor existing
C./JS.uses in.vfiles unless required. If you must change those lines, prefer moving the interop code to.c.v/.js.v. - For C interop, use correct
const_prefixes in C function redeclarations when needed (helps with-cstrictand C static analysis tooling).
Environment-Specific Code (files and $if)
V supports environment-specific file suffixes. Prefer them when the whole file is platform/backend specific.
Common patterns:
- Backend splits:
*.c.v(C backend),*.js.v(JS backend),*.native.v(native backend),*.wasm.v(WASM backend)
- OS splits:
*_windows.c.v,*_linux.c.v,*_nix.c.v, with*_default.c.vas fallback
- Flag splits:
*_d_customflag.vis included only with-d customflag*_notd_customflag.vis included only when that flag is NOT passed
Notes:
- Do not use combinatorial suffixes like
_d_flag_linux.c.v; use_d_flag.vplus$if linux {}inside the file. - For smaller platform differences, use compile-time
$ifblocks:$if windows { ... } $else { ... }
- See Compile-Time Code and Reflection for the full
$ifreference.
Compile-Time Code and Reflection
V uses $ as a prefix for compile-time (comptime) operations. These
are evaluated by the compiler, not at runtime. AI agents frequently
confuse comptime and runtime constructs; this section clarifies the
boundaries.
Compile-time $if
$if evaluates conditions at compile time. It is not a runtime if.
Use it for platform, compiler, and custom-flag checks:
$if windows { ... } $else $if linux { ... } $else { ... }$if debug { ... }(enabled by-gor-cg)$if prod { ... }(enabled by-prod)$if custom_flag ? { ... }(enabled by-d custom_flag)
Full list of builtin $if options: see the table at
https://docs.vlang.io/conditional-compilation.html.
Common mistakes:
- Using runtime
ifwhere$ifis needed for platform-specific code. Runtimeifwill fail to compile if it references platform-specific symbols;$ifexcludes the block entirely on non-matching platforms. - Forgetting the
?suffix for custom flags:$if myflag ? { ... }. Without?, the compiler treats it as a builtin option and silently ignores it.
Compile-time $for
$for iterates over type metadata at compile time. It works with:
StructType.fields- iterate struct fieldsStructType.methods- iterate struct methodsEnumType.values- iterate enum valuesStructType.attributes- iterate struct attributesSumType.variants- iterate sum type variantsmethod.params- iterate method parameters
Inside $for blocks, use $if to branch on field/method types:
fn main() {
$for field in MyStruct.fields {
$if field.typ is string {
println(field.name)
}
}
}Also works with generics: T.fields, param.fields where
fn gen[T](param T) {}.
Common mistakes:
- Using runtime
forto iterate struct fields. This does not work; V has no runtime reflection. Always use$for. - Calling
obj.$method()outside a$for m in Type.methodsblock. The$method()call is only valid inside a comptime method iteration. - Assuming comptime
$forproduces a runtime loop. It does not; the compiler unrolls it into concrete code for each field/method/variant.
Compile-time functions
Only the following $-prefixed functions are supported:
$embed_file('path')- embed a file's contents into the binary. Paths can be absolute, relative to the source file, or use pseudo variables like@VEXEROOTor@VMODROOT.$tmpl('path')- compile a V template file (used by veb).$env('VAR')- read an environment variable at compile time.$d('ident', default)- read a-d ident=valuecompile-time define, with a default fallback.$res('path')- embed a resource (Android).$compile_error('msg')- emit a compile-time error.$compile_warn('msg')- emit a compile-time warning.$pkgconfig('name')- query pkg-config at compile time.$typeof(expr)- compatibility alias fortypeof(expr).$sizeof(Type)- compatibility alias forsizeof(Type).$isreftype(expr)- compatibility alias forisreftype(expr).$__offsetof(Struct, field_name)- compatibility alias for__offsetof(Struct, field_name).$dump(expr)- compatibility alias fordump(expr).
Common mistakes:
- Prefer the unprefixed
typeof,sizeof,isreftype,__offsetof, anddumpforms in new code. Their$-prefixed compatibility aliases are also accepted. - Assuming
$embed_filereturns a string. It returns anEmbedFileDataobject; use.to_string()or.to_bytes(). - Using
$envwhere a runtimeos.getenvis appropriate, or vice versa.$envis baked in at compile time and cannot change at runtime.
Compile-time pseudo variables
These are @-prefixed identifiers substituted at compile time:
@FN- current function name.@METHOD-ReceiverType.MethodName.@MOD- current module name.@STRUCT- current struct name.@FILE,@DIR,@LINE,@COLUMN,@FILE_LINE- source location.@LOCATION- file, line, and current type+method; good for logging.@VEXE,@VEXEROOT- path to the V compiler and its directory.@VHASH,@VCURRENTHASH- compiler commit hashes.@VMOD_FILE,@VMODHASH,@VMODROOT- nearestv.modinfo.@BUILD_DATE,@BUILD_TIME,@BUILD_TIMESTAMP- build time (UTC). Override with theSOURCE_DATE_EPOCHenv var for reproducible builds.@OS,@CCOMPILER,@BACKEND,@PLATFORM- build environment.
Compile-time type groups
Comptime type groups combine multiple types into a higher-level type
for use in generic or comptime $if checks:
$int- all integer types$float- all float types$array- all array types$map- all map types$struct- all struct types$enum- all enum types$alias- all type aliases$sumtype- all sum types$function- all function types$interface- all interface types$option- all option types
Example: $if field.typ is $int { ... }
Comptime changes and testing
Comptime logic lives primarily in vlib/v/types/checker_comptime.v and
vlib/v/transform/comptime.v. Changes here require a rebuild of
./v and should be tested with ./v -silent test vlib/v/tests/ plus
any comptime-specific tests. See the decision table and Testing.
Run Programs
- Compile and run:
./v run file.v. - Just compile:
./v file.v(creates executable). - With debug info:
./v -g run file.v. - Debug run (C line numbers):
./v -keepc -cg run file.v. - Example:
./v run examples/hello_world.v.
Testing
Run:
- File (shows test output):
./v path/to/file_test.v. - File (test runner report only):
./v test path/to/file_test.v. - Dir:
./v -silent test path/to/dir/. - Dir with statistics/metrics:
./v -stats test path/to/dir/. - Compiler:
./v -silent vlib/v/compiler_errors_test.v. - Fix outputs (only when intended):
VAUTOFIX=1 ./v -silent vlib/v/compiler_errors_test.v. - All:
./v test-all. Ask before running./v test-allunless explicitly requested.
When:
- Rule of thumb: for localized changes, run the smallest relevant tests. If any trigger below matches, run the listed tests.
- Minimum tests listed are the floor, not the ceiling; add targeted tests for cross-cutting changes.
- If unsure which tests apply, ask the user before proceeding.
- If in doubt, prefer the smallest targeted test and ask.
- Run all tests that apply. Start with the smallest targeted tests; add slow tests as needed. Order does not matter.
- Compiler changes (
vlib/v/orcmd/v/): Run./v -silent vlib/v/compiler_errors_test.v,./v -silent test vlib/v/. - Parser-only changes (
vlib/v/parser/): Run./v -silent test vlib/v/parser/. - Checker-only changes (
vlib/v/types): Run./v -silent test vlib/v/types/. - vlib changes: Run nearest
*_test.vor./v -silent test vlib/path/. - Tool changes (
cmd/tools/): Run tool-specific tests. If none exist, run the smallest relevant*_test.vthat exercises the tool. Note:cmd/v/is compiler scope, not tools. Examples:cmd/tools/vfmt->cmd/tools/vfmt_test.vandvlib/v/gen/v/gen_test.v.cmd/tools/vdoc->cmd/tools/vdoc/vdoc_test.v. - Diagnostic/output changes:
Run
./v -silent vlib/v/slow_tests/inout/compiler_test.v. - C codegen changes: Run
./v -silent test vlib/v/gen/c/. Consider a stricter validation pass:./v -cstrict -cc clang -silent test vlib/v/. - REPL changes: Run
./v -silent vlib/v/slow_tests/repl/repl_test.v. - Broad refactors: Run
./v -silent test-all. - Backend-specific changes: run the smallest relevant tests for the
affected backend. JS/native/WASM backends are incomplete, so avoid
broad
-b <backend> test vlib/runs. Prefer targeted*_test.vfiles or small test dirs with-b js|native|wasm.
If time-constrained, prioritize
./v -silent vlib/v/compiler_errors_test.v and the smallest targeted tests.
Run vlib/v/slow_tests/inout/compiler_test.v and the tests under
vlib/v/gen/c/ when output or codegen changes are likely.
See TESTS.md for more guidance on test selection and output
expectations.
See CONTRIBUTING.md for broader workflow guidance.
Concrete triggers:
vlib/v/slow_tests/inout/compiler_test.vwhen error text or output formatting changes, or changes in checker/parser error reporting../v -silent test vlib/v/gen/c/for changes undervlib/v/gen/c/or C codegen output paths.
Types:
- Standard:
*_test.vfiles withtest_functions. - Output:
.vvsource +.outexpected output invlib/v/slow_tests/inout/. Example:./v -silent vlib/v/slow_tests/inout/compiler_test.v. vlib/v/tests/**may use.run.outexpectations; run with./v -silent test vlib/v/tests.
Docs-only guidance: see Reporting. If time-boxed, run at least the smallest relevant test and note skipped coverage in the summary.
Useful env variables and flags while testing
VAUTOFIX=1- Auto-update .out files when tests fail (run twice). Use only when a behavior change is intended.VTEST_ONLY=glob_pattern- Run only tests matching pattern.VTEST_HIDE_OK=1- Hide successful tests, show only failures../v -silent test path/to/dir/- Show only failed tests (if any), and a summary report.-cc tcccan speed test builds when TCC is available.- Output expectations: update
.outfiles only when behavior changes are intended; note the rationale in the summary.
Debug
- See what the C compiler is doing:
-showccprints the C compile command.-show-c-outputprints the C compiler output.
- Build a temporary compiler for debug flags:
./v -o ./w -d trace_checker cmd/v- Then run:
./w file.v
- Keep and inspect generated C:
-keepc -cgis the common combo.-printfn <name> -o file.cemits only the named C function to standard output. Thenameuses themodulename__fnnameformat (e.g.main__main). This flag can be repeated to print multiple functions. Methods/generics may use more complex C names; use-keepcto confirm exact symbols.
- Trace stages:
-d trace_scanner|trace_parser|trace_checker|trace_gen. These flags can help diagnose a problem when a stage stops earlier than expected. - Time stages:
-d time_parsing|time_checking. - V panics:
-keepc -g. - C segfaults:
-keepc -cg -cc clang. - JS/native/wasm: prefer small, focused test files with
-b js|native|wasmand-show-c-outputwhere applicable; avoid broad-b <backend> test vlib/. - Quick code location technique:
When debugging code generation issues, add unique comment tags to
relevant code generation points (e.g.,
/*tom51*/) in the compiler source. Rebuild and generate C code, then search the generated file for these tags to quickly map generated C code back to the exact compiler source location. This is especially useful when multiple code paths generate similar-looking output and you need to identify which path is actually used. Example:
Remember to remove these debug tags after fixing the issue.// In vlib/v/gen/c/stmt.v: g.write('builtin___option_ok/*tom51*/(&(${styp}[]) { ') // After rebuild, search generated C code for "tom51": // builtin___option_ok/*tom51*/(&(int[]) { ... });
Compiler Performance
For the fixed self-compilation benchmark, results, and agent regression policy, read vself_speed.md. Every compiler fix must preserve or improve that efficiency; investigate instruction-count regressions before merging.
Use retired CPU instructions per fixed workload and per parsed source line as the primary
compiler optimization metrics; lower is better. On macOS arm64,
/usr/bin/time -l reports instructions retired from hardware counters. Under matched conditions,
this is the most reliable local measure of compiler work: it is less sensitive than elapsed time to
CPU frequency and scheduling. Also retain elapsed time, cycles, and peak memory; fewer instructions
do not guarantee lower latency or memory use. Compare counts on the same machine and architecture.
The instruction counter is scoped to the measured process; unrelated processes do not add their instructions to it. An idle host is not required for instruction comparisons. Counts are dynamic, not a static property of the binary: synchronization, retries, and runtime paths can vary. Use serial paired measurements to check that variation. Record host load as context for elapsed time and cycles; use controlled load when making latency claims.
For instructions per line, divide by physical lines in the .v and .vh files actually parsed,
including builtins, imports, blank lines, and comments. Collect parsed .v lines plus
parsed .vh lines in a separate unmeasured -v run with the same input flags. Preserve that
inventory and verify that both compilers process the same files and line count. Keep the fixture
fixed: padding files or changing source complexity must not count as an optimization. Retain total
instructions alongside instructions/line; establish a new baseline when the fixture changes.
Instructions per second depends on hardware, scheduling, and instruction mix; do not use it as a
compiler-efficiency score. See vself_speed.md for the self-compilation fixture.
Build a production compiler outside the measured run, then measure compilation to C:
env -u VFLAGS -u VEXE VJOBS=1 SOURCE_DATE_EPOCH=0 V_MACOS_V3_NO_FALLBACK=1 \
./v -prod -cc clang self || exit 1
benchmark_out=$(mktemp -d "${TMPDIR:-/tmp}/v-perf.XXXXXX")
env -u VFLAGS -u VEXE VJOBS=1 SOURCE_DATE_EPOCH=0 V_MACOS_V3_NO_FALLBACK=1 \
/usr/bin/time -l -o "$benchmark_out/time.txt" \
./v -nocache -o "$benchmark_out/sha3.c" /absolute/path/to/sha3.v \
> "$benchmark_out/stdout.txt" 2> "$benchmark_out/stderr.txt"
benchmark_status=$?
printf '%s\n' "$benchmark_status" > "$benchmark_out/exit-status.txt"
cat "$benchmark_out/time.txt"Replace the source path with the fixed benchmark fixture. Read the integer on the
instructions retired line. The -prod above optimizes the compiler itself; the timed command uses
the normal input compilation mode. Keep input flags identical between baseline and candidate.
-o ...c includes parsing, checking, transforms, and C generation, while excluding the external C
compiler and execution of the generated program. -check-syntax measures a different workload;
label it separately and verify which stages that compiler version executes. -nocache disables
compiler caching; it does not flush the operating system's filesystem cache.
V_MACOS_V3_NO_FALLBACK=1 prevents silent legacy-compiler fallback when measuring V3 on macOS.
For a baseline/candidate comparison:
- Build both compilers with the same production build recipe and C toolchain. Verify correctness, diagnostics, and generated C before measuring. For a change intended to preserve output, require identical C, allowing only explicitly recorded build metadata differences. Validate generated C when changing the fixture or compiler representation; matching invalid C is not sufficient.
- Use the same host, OS, fixture, standard library, flags, environment, and filesystem placement.
Keep executable, source, and output paths identical between roles where possible; record any
remaining differences. Set
VJOBS=1andSOURCE_DATE_EPOCH=0, and disable tracing/profiling. Clear unintended compiler environment overrides, includingVFLAGSandVEXE; record the effective environment. Measure only successfully rebuilt compilers, never a stale binary. Run only one benchmark process at a time. Other builds or tests on the host do not invalidate process instruction counts; do not pause unrelated work or wait for an idle host. Record that elapsed time and cycles collected under uncontrolled load are contextual measurements. - Run one warmup per role, then ten measured pairs, alternating baseline/candidate order: AB, BA, AB, BA, and so on. Record all 22 runs, excluding both warmups from statistics. Use a distinct timing/stdout/stderr log for every run and the same generated C output path.
- Require exit status zero and exactly one positive
instructions retiredcounter in every sample. Preserve failed or incomplete runs, but do not report them as a completed comparison. If the counter is missing or zero, report it as unavailable; elapsed time is not an instruction count. - Report each role's median instructions/line and total instructions, the fixed parsed-line count, percentage change between medians, median paired instruction difference, and how many pairs made the candidate worse. Report memory and elapsed time alongside instructions. Retain all raw logs, exact commands/environment, compiler commits, binary hashes, fixture hashes, and output verification so the result can be reproduced.
Do not select the fastest sample or compare medians from different measurement sessions as proof of a small improvement. Investigate inconsistent pair results before accepting an optimization. For end-to-end build latency or parallel scaling, measure that workload separately with its intended worker count and external C compiler, and state that scope explicitly.
Compiler Architecture
The V compiler has the following stages, orchestrated by v.driver:
v.scanner -> v.parser/v.flat -> v.types -> v.transform ->
v.markused -> v.gen.c.
Additional backends and lowerings include FastC, WebAssembly, SSA, MIR,
instruction selection, and native ARM64 generation.
Key Directories
vlib/: Standard library (changes here can affect the compiler itself).cmd/v/v.v: Compiler entry.cmd/tools/: vfmt, vdoc, vup, vquest, etc.examples/: Example programs.thirdparty/: Bundled C libraries (tcc, mbedtls, sokol, etc.).vlib/v/: Compiler modules.- scanner/ - Tokenizer
- token/ - Token definitions
- parser/ - Produces a flat AST
- flat/ - Compact AST storage
- types/ - Name resolution and type checking
- transform/ - AST simplification
- markused/ - Dead code eliminator
- gen/c/ - C code generation (primary backend, known as cgen)
- gen/fastc/ - Scanner-to-C fast path
- gen/arm64/ - Native ARM64 backend
- gen/wasm/ - WebAssembly backend
Test Locations
vlib/v/tests/: Compiler feature tests (including comptime).vlib/v/slow_tests/: Output-matching and slow tests for the compiler.vlib/v/slow_tests/inout/- Output comparison tests (.vv + .out pairs)vlib/v/parser/tests/- Parser error testsvlib/v/checker/tests/- Checker error testsvlib/v/gen/c/- C codegen unit and integration testsexamples/compiletime/- Comptime usage examples (includingreflection.v)
Error Reporting (checker/parser)
Scanner and parser diagnostics carry v.token.Pos spans. Type-checker
diagnostics are collected by v.types.TypeChecker; shared diagnostic
formatting and message types live in vlib/v/errors/.
Option/Result Types
- Syntax:
?Type(optional, can be none) vs!Type(result, can error). - Common bugs: Unwrapping in if guards, struct init with option fields, ternaries with options.
- When changing option/result behavior, add a regression test in
vlib/v/tests/. - Tests: Search
vlib/v/tests/for option/result test files. - Pitfall: Options in ternaries, SQL statements, and fixed arrays need special handling in cgen.
Tools
- Note: if a rule overlaps with Testing, follow Testing.
- Format:
./v fmt -w <file>for touched.vand.vshfiles. Format only touched files unless explicitly asked to reformat broader scope. - Treat new files as touched for formatting and markdown checks.
- Check all files are formatted:
./v -silent test-fmt. Run only when asked or when validating the full tree. - Check markdown:
./v check-md file.mdfor touched.mdfiles (required before commits). - Code style checker:
./v vet vlib/vRun only when asked or when making broad checker changes (more than 3 files invlib/v/types/). - Module docs:
./v doc -readme -all -l module_name. - Search:
rg pattern(orgit grep); list files:rg --files. - Auto-format hook:
./v git-fmt-hook install.
Commits and PRs
- See
CONTRIBUTING.mdfor full commit message conventions and PR workflow. - Keep commits focused: one logical change per commit.
- If your branch has diverged and a rebase or merge is needed, do not
force-push or drop hunks without asking. State the conflict and let
the user decide the resolution strategy. When in doubt, prefer
git rebaseovergit mergefor a linear history, but always ask if the situation is ambiguous.
Environment Variables
- VFLAGS: Pass flags to all V invocations
(e.g.,
VFLAGS='-g' ./v test-all). - VEXE: Path to V compiler executable (useful in CI/scripts).
- TMPDIR: Controls where
.tmp.cfiles are written (V usesTMPDIR/v/). - SOURCE_DATE_EPOCH: Override build timestamp for reproducible builds
(affects
@BUILD_DATE,@BUILD_TIME,@BUILD_TIMESTAMP). - V2-specific:
V2CC,V2CFLAGS,V2VERBOSE(for v2 development).
Gotchas
- Core modules (
builtin,strings,os,strconv,time) can affect the compiler because it is a V program. Rebuild./vwhen they change. - Module names must match their directory name; mismatches cause silent import failures. See Modules and Imports.
- Some V programs and tools hardcode
os.execute('v ...')in their source. The./vworkflow does not protect against these; if you encounter unexpected behavior from such calls, check whether the code is invoking the systemvinstead of./vand adjust accordingly. - Stale
./vcan cause confusing failures; rebuild if behavior seems off. - Output tests require exact matches; whitespace changes break tests.
- Formatting reminders: follow Code Style for
fmtandcheck-md. - C compilation errors? Check generated C with
-keepc(creates/tmp/*.tmp.c; see also TMPDIR in Environment Variables). - Compile-time code (
$if,$for,$embed_file, etc.) is a common source of AI mistakes. See Compile-Time Code and Reflection for correct usage and pitfalls. - Broken compiler? See Safety for the recovery sequence.
- Consult
CONTRIBUTING.mdandTESTS.mdfor:- New tests or test infra changes.
- Output tests or
.outupdates. - Broad refactors or compiler-wide changes.
- Unsure which slow test runner applies to your change.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

