Skip to content

Releases: rockorager/ziglint

v0.5.2

08 Feb 11:00
v0.5.2
74db04d

Choose a tag to compare

Performance Improvements

Module graph construction is now 3000x faster! 🚀

Dramatically improved module graph build performance through two key optimizations:

Before: ~1850ms to analyze build.zig (loading 308 modules from std with ZIR)
After: ~0.6ms to analyze build.zig (loading 2 modules without ZIR)

What changed:

  1. Disabled ZIR generation - ZIR was added proactively in v0.4.0 for future control flow analysis (issue #18), but no rules currently use it. Generating ZIR took 10-50ms per module.

  2. Skip recursing into std library - When linting user code like build.zig, we don't need to parse all 300+ modules from the standard library. Now we only load the root std.zig file.

Impact on real-world usage:

# Linting a single file that imports std
Before: ~2 seconds
After:  ~0.4 seconds (5x faster)

# Linting entire src/ directory
Before: Previously slow on large projects
After:  Dramatically faster startup and analysis

These optimizations can be easily reverted if control flow analysis is implemented in the future (see well-documented code comments in src/ModuleGraph.zig).

Technical Details

  • ZIR generation infrastructure remains in place and can be re-enabled by uncommenting documented code sections
  • Module graph now loads only user code + top-level std.zig instead of recursively parsing the entire standard library
  • All tests pass; linter functionality unchanged
  • Verified against GitHub history: ZIR added in commit 14bbe87 but never used by any rules

Installation

mise use github:rockorager/ziglint@v0.5.2

Or download pre-built binaries from the release assets.

v0.5.1

08 Feb 10:47
v0.5.1
1e4b8d9

Choose a tag to compare

Bug Fixes

Z011: Fixed deprecation detection in nested contexts

Previously, ziglint failed to detect deprecated function calls inside try expressions, catch blocks, and other nested AST contexts. This was due to incomplete AST traversal in the linter.

Fixed detection for:

  • std.meta.intToEnum() - deprecated in favor of @enumFromInt()
  • std.meta.TagPayloadByName() - deprecated in favor of TagPayload with @field()
  • std.enums.nameCast() - deprecated in favor of @enumFromInt(@intFromEnum())
  • std.unicode.utf8Decode() - deprecated in favor of utf8DecodeAssumeValid()
  • And many other deprecated functions that were previously missed

Technical details:

  • Fixed visitChildren() to recursively visit all child nodes for unhandled AST node types
  • Now catches deprecations in try expressions, catch blocks, and other complex contexts
  • Added test corpus to prevent regressions

Example - now detects:

pub fn main() !void {
    // Previously missed, now detected:
    _ = try std.meta.intToEnum(MyEnum, 1);
}

Code Quality

  • Fixed Z011 violation in ziglint's own codebase: replaced deprecated std.mem.trimLeft with std.mem.trimStart
  • Fixed Z007 violations: eliminated 20 duplicate ModuleGraph imports across test functions
  • Added test cases for deprecated functions we don't yet detect (marked as skipped for future work)

Improvements

  • Added --verbose flag with timing information for performance analysis
  • Added per-rule timing breakdown to verbose output
  • Improved verbose output with colors and rule summary
  • Better directory linting with verbose logging

Known Limitations

Detection still requires improvement for:

  • Deprecated methods on local variables (requires flow analysis)
  • Deprecated const values that aren't function calls

Installation

mise use github:rockorager/ziglint@v0.5.1

Or download pre-built binaries from the release assets.

v0.5.0

01 Feb 22:09
v0.5.0
3e1c909

Choose a tag to compare

What's New

Three new naming convention rules based on the official Zig Style Guide:

  • Z031: Avoid underscore prefix in identifiers - detects _like_this naming pattern
  • Z032: Acronyms should use standard casing - detects XMLParser (should be XmlParser)
  • Z033: Avoid redundant words in identifiers - detects "Value", "Data", "Context", "Manager", "State", "utils", "misc" (disabled by default)

Configuration

Z033 is disabled by default as it can be controversial. Enable it in .ziglint.zon:

.{
    .rules = .{
        .Z033 = .{ .enabled = true },
    },
}

Installation

mise use github:rockorager/ziglint

v0.4.1

31 Jan 20:37
v0.4.1
2f8246f

Choose a tag to compare

What's New

Bug Fixes

  • Z020: No longer flags @This() when passed as a function argument (e.g., testing.refAllDecls(@This()))

Installation

mise use github:rockorager/ziglint

v0.4.0

31 Jan 20:16
v0.4.0
978e2d3

Choose a tag to compare

What's New

New Rules

  • Z028: Inline @import should be assigned to a top-level const
  • Z030: deinit functions should set self.* = undefined

Bug Fixes

  • Z012: No longer flags pub types within the same enclosing struct as private
  • Z006: Allows camelCase function aliases (e.g., const foo = @import("std").debug.print)
  • Fixed directory traversal on Windows

Installation

mise use github:rockorager/ziglint

v0.3.0

30 Jan 20:11
v0.3.0
a0ca75e

Choose a tag to compare

What's New

New Lint Rules

  • Z023: Argument order lint rule - flags comptime value params that should come before runtime params
  • Z024: Line length lint rule with config file support (zlint.json)
  • Z025: No-catch-return rule - detects catch return patterns
  • Z026: Suppressed-errors rule - flags error suppression patterns
  • Z027: Flag instance access to container-level decls
  • Z029: Detect redundant @as in result-location contexts

Improvements

  • Z006: Recognize more type expressions as type aliases including primitive types and PascalCase labeled blocks
  • Z011: Improved deprecated stdlib function detection
  • TypeResolver: Add type-vs-instance resolution and function call return type resolution
  • --help and --version now exit with code 0

Documentation

  • Added comprehensive documentation for all linter rules in docs/rules/
  • Added executable documentation tests for linter rules
  • Added nix devShell for development

Build

  • Added aarch64-linux build target to CI and releases

Installation

mise use github:rockorager/ziglint

v0.2.2

25 Jan 11:29
69211ea

Choose a tag to compare

What's New

  • Z006: recognize primitive types as valid type aliases
  • Fix Z019 false positive for local structs in large functions
  • Fix Z019 false positive for structs in if/while/for bodies

Installation

mise use github:rockorager/ziglint

v0.2.1

25 Jan 03:06
f405db2

Choose a tag to compare

What's New

  • Build system now caches the lint step properly, skipping re-runs when source files are unchanged
  • Diagnostics output to stderr for proper build system integration

Installation

mise use github:rockorager/ziglint

v0.2.0

24 Jan 15:14
abd2898

Choose a tag to compare

What's New

New Rules

  • Z017: Flag redundant try in return statements (return try exprreturn expr)
  • Z018: Flag redundant @as when type is already known from context
  • Z019: @This() in named struct; use the type name instead
  • Z020: Inline @This(); assign to a constant first
  • Z021: File-struct @This() alias should match filename
  • Z022: @This() alias in anonymous/local struct should be Self

Improvements

  • Z006: Treat error set merges as type aliases
  • TypeResolver: Support aliased std imports
  • Fix Z017 message dim color leak
  • Fix addLint caching by using LazyPath

Removed Rules

  • Z008: Comment divider line rule (removed)

Installation

mise use github:rockorager/ziglint

Or download binaries from the release assets.

v0.1.0

23 Jan 04:25
0dd555c

Choose a tag to compare

What's New

  • Initial release of ziglint
  • Zig linting and style checks
  • Cross-platform support (macOS, Linux, Windows)

Installation

mise use github:rockorager/ziglint

Or download binaries from the release assets.