Skip to content

Version-gated language features

verikt uses a feature matrix to generate version-appropriate code. Instead of targeting the lowest common denominator, templates use feature flags to emit modern APIs when the target language version supports them.

  1. Detect version — verikt reads the language version from your project (language-specific, see below)
  2. Resolve features — the detected version is compared against features.yaml, producing a boolean map
  3. Inject into templates — templates access features via {{if .Features.<name>}}...{{end}}

How verikt detects the runtime version depends on the language:

  • Go — runs go env GOVERSION, or accepts an override via --set GoVersion=X.XX
  • TypeScript — runs node --version, or accepts an override via --set NodeVersion=XX

Each feature maps to the minimum Go version that introduced it. If your detected version is >= the since version, the feature is enabled.

FeatureDescriptionSince
slices_packagestdlib slices package (slices.SortFunc, slices.Contains)1.21
log_slogstdlib structured logging (log/slog)1.21
maps_packagestdlib maps package1.21
range_over_intfor i := range n syntax1.22
range_over_funcfor x := range func syntax (iterators)1.23
os_rootos.Root/os.OpenRoot for kernel-level path safety1.24
weak_pointersweak package for weak pointers1.24
os_root_fsos.Root implements fs.FS interface1.25
synctesttesting/synctest for concurrent test control1.25
generic_type_aliasesFully generic type aliases1.25

Templates use the .Features map to conditionally emit code:

{{if .Features.os_root}}
root, err := os.OpenRoot(dir)
{{else}}
f, err := os.Open(filepath.Join(dir, name))
{{end}}
{{if .Features.log_slog}}
import "log/slog"
{{else}}
import "log"
{{end}}

The feature matrix is a YAML file with a single features list:

features:
- name: slices_package
description: "stdlib slices package (slices.SortFunc, slices.Contains)"
since: "1.21"
FieldTypeDescription
namestringIdentifier used in templates as .Features.<name>
descriptionstringHuman-readable explanation of the feature
sincestringMinimum version that supports this feature

Node.js versions gate TypeScript-specific template behavior. The default Node version is 22 (current Active LTS). Override with --set NodeVersion=24.

FeatureDescriptionSince
native_tsStable native TypeScript (--strip-types enabled by default) — drops tsx dependency, uses node --watch24
es2024ES2024 target support (Object.groupBy, Promise.withResolvers, ArrayBuffer.transfer)24

What changes by Node version:

Template concernNode 20Node 22 (default)Node 24
tsconfig.json targetES2023ES2023ES2024
Dev servertsx watchtsx watchnode --watch (native)
tsx dependencyRequiredRequiredDropped
Dockerfile basenode:20-alpinenode:22-alpinenode:24-alpine
@types/node^20^22^24

When a new Go or Node.js version ships with relevant changes:

  1. Add an entry to the provider’s features.yaml
  2. Update any templates that should use the new feature with {{if .Features.<name>}}
  3. Optionally add conditional rules in capability manifests for file-level gating (see verikt.yaml reference)

No changes to the feature resolver are needed — it reads features.yaml dynamically.