Best Practices, Idioms and Limitations
45.1 Idiomatic V
✅ Keep code simple. V favors one obvious way.
✅ Immutable by default. Use mut only where necessary.
✅ Handle every !T / ?T with or {}, propagation (!/?), or if guards. Don't panic in library code.
✅ Use sum types and exhaustive match for variants. Use interfaces for behavior.
✅ Use @[params] structs for many or optional parameters.
✅ Use pub deliberately. Keep module APIs small.
✅ Use snake_case names, tabs, and v fmt always.
✅ Use defer for cleanup. Use shared + lock or channels for concurrency.
✅ Write tests next to the code (_test.v). Use v vet in CI.
❌ Don't use unsafe unless needed. Document why when you do.
❌ Don't enable globals without strong reason.
❌ Don't rely on experimental features (autofree, native backend) for production without testing.
❌ Don't ignore compiler warnings. They become errors in -prod.
45.2 Known Limitations and Caveats (Pre-1.0)
The language and stdlib are still evolving: attribute syntax changed ([x] → @[x]), generics changed (<T> → [T]), vweb was replaced by veb, and go vs spawn semantics changed.
Autofree isn't production-ready. The default is the Boehm GC.
Compiler bugs and less mature tooling compared with Go/Rust. Smaller ecosystem.
Some advertised goals (e.g., complete absence of UB, full memory safety without a GC) are still in progress.
Pin a V commit or release for production builds, and test after v up.
45.3 Security Practices
Use ORM or parameterized SQL. Validate and sanitize input in veb handlers. Use TLS (net.mbedtls/OpenSSL). Keep -prod builds with bounds checks on. Avoid -no-bounds-checking for network-facing code. Use crypto.rand for secrets (not rand).