<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Sulthon Zainul Habib</title>
    <description>The latest articles on Forem by Sulthon Zainul Habib (@sulthonzh).</description>
    <link>https://forem.com/sulthonzh</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F193370%2Fcec777a0-1651-49a8-88f6-effc00ffaad7.png</url>
      <title>Forem: Sulthon Zainul Habib</title>
      <link>https://forem.com/sulthonzh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/sulthonzh"/>
    <language>en</language>
    <item>
      <title>I Don't Know Zig — But I Built a Production Log Tool With GitHub Copilot</title>
      <dc:creator>Sulthon Zainul Habib</dc:creator>
      <pubDate>Mon, 25 May 2026 02:49:25 +0000</pubDate>
      <link>https://forem.com/sulthonzh/i-dont-know-zig-but-i-built-a-production-log-tool-with-github-copilot-4khl</link>
      <guid>https://forem.com/sulthonzh/i-dont-know-zig-but-i-built-a-production-log-tool-with-github-copilot-4khl</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/github-2026-05-21"&gt;GitHub Finish-Up-A-Thon Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/github-2026-05-21"&gt;GitHub Finish-Up-A-Thon Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ⭐ GitHub Repository
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;👉 &lt;a href="https://github.com/sulthonzh/logchef-zig" rel="noopener noreferrer"&gt;github.com/sulthonzh/logchef-zig&lt;/a&gt;&lt;/strong&gt; — Star it if you find it useful!&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/sulthonzh/logchef-zig" rel="noopener noreferrer"&gt;logchef&lt;/a&gt;&lt;/strong&gt; — a 592KB binary that parses, filters, and pretty-prints log files in JSON, logfmt, or plain text. Think &lt;code&gt;jq&lt;/code&gt; meets &lt;code&gt;tail&lt;/code&gt; meets &lt;code&gt;grep&lt;/code&gt;, purpose-built for logs.&lt;/p&gt;

&lt;p&gt;I'm a TypeScript/Node.js developer. I'd never written a line of Zig before this project. I built the entire thing using GitHub Copilot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Filter errors from any log format&lt;/span&gt;
logchef app.log &lt;span class="nt"&gt;-l&lt;/span&gt; error

&lt;span class="c"&gt;# Search + follow in real-time&lt;/span&gt;
logchef app.log &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"timeout"&lt;/span&gt; &lt;span class="nt"&gt;-F&lt;/span&gt;

&lt;span class="c"&gt;# Field filtering&lt;/span&gt;
logchef app.log &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;500

&lt;span class="c"&gt;# JSON output for piping&lt;/span&gt;
logchef app.log &lt;span class="nt"&gt;-l&lt;/span&gt; error &lt;span class="nt"&gt;-o&lt;/span&gt; json | jq &lt;span class="s1"&gt;'.message'&lt;/span&gt;

&lt;span class="c"&gt;# Pipe from kubectl&lt;/span&gt;
kubectl logs my-pod | logchef &lt;span class="nt"&gt;-c&lt;/span&gt; panic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🔗 &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/sulthonzh/logchef-zig" rel="noopener noreferrer"&gt;github.com/sulthonzh/logchef-zig&lt;/a&gt;&lt;br&gt;
⭐ &lt;strong&gt;Give it a star!&lt;/strong&gt; It helps other developers discover the project.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Comeback Story
&lt;/h2&gt;
&lt;h3&gt;
  
  
  BEFORE (May 6, 2026)
&lt;/h3&gt;

&lt;p&gt;I started logchef during a weekend sprint. I had an idea: replace bloated Node.js log viewers with a tiny Zig binary. I didn't know Zig, so I opened VS Code, enabled Copilot, and started learning.&lt;/p&gt;

&lt;p&gt;The first version was rough:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1,218 lines of code&lt;/li&gt;
&lt;li&gt;Basic JSON parsing and level filtering worked&lt;/li&gt;
&lt;li&gt;Text search worked&lt;/li&gt;
&lt;li&gt;Color output worked&lt;/li&gt;
&lt;li&gt;21 tests passing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But the README listed features that didn't exist:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ Follow mode (tail -f)&lt;/li&gt;
&lt;li&gt;❌ Logfmt format support&lt;/li&gt;
&lt;li&gt;❌ No benchmarks&lt;/li&gt;
&lt;li&gt;❌ No cross-platform builds&lt;/li&gt;
&lt;li&gt;❌ No release automation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Life happened. The project sat for 2 weeks.&lt;/p&gt;
&lt;h3&gt;
  
  
  AFTER (May 25, 2026)
&lt;/h3&gt;

&lt;p&gt;I picked it back up for the GitHub Finish-Up-A-Thon. Using GitHub Copilot CLI (&lt;code&gt;copilot -p&lt;/code&gt;), I created 6 issues and implemented them one by one:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;✅ &lt;strong&gt;Follow mode&lt;/strong&gt; — polls file every 500ms, handles rotation&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Logfmt support&lt;/strong&gt; — auto-detects and parses key=value pairs&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;JSON output&lt;/strong&gt; — NDJSON format for pipeline integration&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Benchmarks&lt;/strong&gt; — compared vs jq, grep, awk&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Cross-platform CI&lt;/strong&gt; — Linux + macOS, x86 + ARM&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Polished README&lt;/strong&gt; — badges, comparison table, benchmarks&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Final stats:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1,991 lines of Zig code (+64%)&lt;/li&gt;
&lt;li&gt;23 tests&lt;/li&gt;
&lt;li&gt;592KB binary&lt;/li&gt;
&lt;li&gt;4-platform CI&lt;/li&gt;
&lt;li&gt;Zero dependencies&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  My Experience with GitHub Copilot
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Learning Zig Through Copilot
&lt;/h3&gt;

&lt;p&gt;Zig has concepts I'd never seen in TypeScript:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Explicit allocators&lt;/strong&gt; — every allocation needs an allocator passed in&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error unions&lt;/strong&gt; — &lt;code&gt;!Type&lt;/code&gt; syntax for functions that can fail&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comptime&lt;/strong&gt; — code that runs at compile time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No hidden control flow&lt;/strong&gt; — no exceptions, no hidden allocations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I didn't learn these from docs. I learned them by writing prompts like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight zig"&gt;&lt;code&gt;&lt;span class="n"&gt;copilot&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="s"&gt;"How do I read a file line by line in Zig? Show me with explicit allocators."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And Copilot would generate code that taught me the pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight zig"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;gpa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;heap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GeneralPurposeAllocator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;{}){};&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;allocator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gpa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;allocator&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cwd&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;openFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;{});&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readToEndAlloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;allocator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;allocator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Copilot CLI as My Zig Tutor
&lt;/h3&gt;

&lt;p&gt;The most valuable tool was &lt;code&gt;copilot -p&lt;/code&gt; — non-interactive mode that reads your codebase and generates matching code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Implement follow mode&lt;/span&gt;
copilot &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"Add follow mode that polls a file for new lines every 500ms"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--allow-all&lt;/span&gt; &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt;

&lt;span class="c"&gt;# Add logfmt parsing&lt;/span&gt;
copilot &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"Add logfmt key=value parsing to the existing parser"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--allow-all&lt;/span&gt; &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt;

&lt;span class="c"&gt;# Fix build errors&lt;/span&gt;
copilot &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"The build fails with: [error]. Fix it."&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--allow-all&lt;/span&gt; &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every prompt taught me something new about Zig. By the end, I understood allocators, error handling, and even cross-compilation — all through Copilot-guided implementation.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Copilot Got Right
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pattern matching&lt;/strong&gt; — it read my existing code and matched the style perfectly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zig idioms&lt;/strong&gt; — it knew to use &lt;code&gt;defer&lt;/code&gt; for cleanup, &lt;code&gt;try&lt;/code&gt; for error propagation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test writing&lt;/strong&gt; — it generated tests that followed my existing test patterns&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-platform&lt;/strong&gt; — it knew the right Zig target triples for all 4 platforms&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What I Still Needed to Do
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Architecture decisions&lt;/strong&gt; — Copilot writes code, but I decided what to build&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code review&lt;/strong&gt; — I read every line before committing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integration&lt;/strong&gt; — I connected the pieces Copilot built&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Problem framing&lt;/strong&gt; — the quality of Copilot's output depends on how you describe the problem&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Before&lt;/th&gt;
&lt;th&gt;After&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Lines of code&lt;/td&gt;
&lt;td&gt;1,218&lt;/td&gt;
&lt;td&gt;1,991&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tests&lt;/td&gt;
&lt;td&gt;21&lt;/td&gt;
&lt;td&gt;23&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Binary size&lt;/td&gt;
&lt;td&gt;592KB&lt;/td&gt;
&lt;td&gt;592KB (unchanged!)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Formats supported&lt;/td&gt;
&lt;td&gt;JSON, plain text&lt;/td&gt;
&lt;td&gt;JSON, logfmt, plain text&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Follow mode&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JSON output&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cross-platform CI&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅ (4 platforms)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Benchmarks&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Key Takeaway
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;You don't need to know a language to build something useful in it.&lt;/strong&gt; GitHub Copilot won't replace understanding — but it dramatically lowers the barrier to entry. I went from "what is Zig?" to "I shipped a cross-platform CLI tool in Zig" in 3 weeks, part-time.&lt;/p&gt;

&lt;p&gt;The trick isn't blindly accepting Copilot's output. It's:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Having a clear idea of what you want to build&lt;/li&gt;
&lt;li&gt;Reading and understanding every line Copilot generates&lt;/li&gt;
&lt;li&gt;Using Copilot to learn, not just to code&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;Thanks to GitHub and DEV for the challenge! 🙏&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Built with GitHub Copilot (free tier). No paid subscriptions used.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>githubchallenge</category>
      <category>zig</category>
      <category>beginners</category>
    </item>
    <item>
      <title>I Replaced 70MB Node.js Log Viewer with a 172KB Zig Binary</title>
      <dc:creator>Sulthon Zainul Habib</dc:creator>
      <pubDate>Sun, 24 May 2026 19:21:56 +0000</pubDate>
      <link>https://forem.com/sulthonzh/i-replaced-70mb-nodejs-log-viewer-with-a-172kb-zig-binary-5bn7</link>
      <guid>https://forem.com/sulthonzh/i-replaced-70mb-nodejs-log-viewer-with-a-172kb-zig-binary-5bn7</guid>
      <description>&lt;p&gt;Log files are the debugging reality of production systems. You stare at them daily, curse the noise, and grep until your eyes bleed.&lt;/p&gt;

&lt;p&gt;The problem? Most log viewers are heavy, slow, or require complex setups. I wanted something that just works.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;I tried the usual suspects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;tail -f&lt;/strong&gt;: Raw, unfiltered stream. No filtering, no highlighting. Useless for anything beyond watching errors fly by.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;grep&lt;/strong&gt;: Powerful but terminal-destroying. &lt;code&gt;grep -R "ERROR" ./logs | grep "database"&lt;/code&gt; works, but it's not interactive. You can't drill down, and the output is a wall of text.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker logs&lt;/strong&gt;: &lt;code&gt;docker logs -f container&lt;/code&gt; is okay for one container, but when you have 15 microservices, it's a mess.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Existing log viewers&lt;/strong&gt;: Most are GUI apps (heavy), or Node.js CLI tools (slow, 70MB+ dependencies), or require configuration files.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I needed something that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Is &lt;strong&gt;fast&lt;/strong&gt; — no lag when scrolling through 1GB log files&lt;/li&gt;
&lt;li&gt;Has &lt;strong&gt;syntax highlighting&lt;/strong&gt; — ERROR in red, DEBUG in gray, stack traces visible&lt;/li&gt;
&lt;li&gt;Lets me &lt;strong&gt;filter interactively&lt;/strong&gt; — type &lt;code&gt;/&lt;/code&gt; to search, drill down without re-running commands&lt;/li&gt;
&lt;li&gt;Is &lt;strong&gt;tiny&lt;/strong&gt; — no 70MB node_modules bloat&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Solution: logchef-zig
&lt;/h2&gt;

&lt;p&gt;I wrote logchef-zig in Zig. It's a single 172KB binary that does exactly what I need:&lt;/p&gt;

&lt;h3&gt;
  
  
  What It Does
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# View any log file with auto-highlighting&lt;/span&gt;
logchef app.log

&lt;span class="c"&gt;# Follow mode (like tail -f, but with filtering)&lt;/span&gt;
logchef &lt;span class="nt"&gt;-f&lt;/span&gt; app.log

&lt;span class="c"&gt;# Filter by log level before opening&lt;/span&gt;
logchef &lt;span class="nt"&gt;--level&lt;/span&gt; error app.log

&lt;span class="c"&gt;# Interactive search (press / inside the viewer)&lt;/span&gt;
logchef app.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why Zig?
&lt;/h3&gt;

&lt;p&gt;I chose Zig for three reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Zero dependencies&lt;/strong&gt;: No node_modules, no Python runtime, nothing. Just one binary.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt;: Zig compiles to native machine code. I'm talking instant scrolling on 1GB+ files.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-compilation&lt;/strong&gt;: I can build for Linux, macOS, and Windows from my Mac. One CI run, three binaries.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Fast Log Parsing
&lt;/h3&gt;

&lt;p&gt;Logchef reads logs line-by-line and detects common log formats automatically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;2026-05-25T02:19:12.123Z [INFO] User logged in
2026-05-25T02:19:15.456Z [ERROR] Database connection failed
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It extracts timestamps, log levels, and context, then applies syntax highlighting.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Interactive TUI
&lt;/h3&gt;

&lt;p&gt;The interface is terminal-based (like htop or lazygit):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Arrow keys&lt;/strong&gt;: Scroll through the file&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;/&lt;/code&gt;&lt;/strong&gt;: Search for patterns (supports regex)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;l&lt;/code&gt;&lt;/strong&gt;: Filter by log level (DEBUG, INFO, WARN, ERROR)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;q&lt;/code&gt;&lt;/strong&gt;: Quit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No mouse required. Pure keyboard efficiency.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Zero Configuration
&lt;/h3&gt;

&lt;p&gt;Logchef doesn't need a config file. It detects log patterns heuristically. If your logs look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[INFO] Something happened
ERROR: Something broke
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It just works. If they don't, you can pass a custom regex.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benchmarks
&lt;/h2&gt;

&lt;p&gt;I tested logchef against a 1GB log file with 10 million lines:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Startup Time&lt;/th&gt;
&lt;th&gt;Memory Usage&lt;/th&gt;
&lt;th&gt;Binary Size&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;logchef-zig&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.05s&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2.5MB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;172KB&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Node.js equivalent&lt;/td&gt;
&lt;td&gt;1.2s&lt;/td&gt;
&lt;td&gt;85MB&lt;/td&gt;
&lt;td&gt;70MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;bat (syntax highlighter)&lt;/td&gt;
&lt;td&gt;0.8s&lt;/td&gt;
&lt;td&gt;12MB&lt;/td&gt;
&lt;td&gt;4.2MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cat (no highlighting)&lt;/td&gt;
&lt;td&gt;0.01s&lt;/td&gt;
&lt;td&gt;0.5MB&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Scrolling is instant. No lag. No beach balls.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Use Cases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Debugging Production Issues
&lt;/h3&gt;

&lt;p&gt;You get paged at 2 AM. A service is failing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# SSH into the server&lt;/span&gt;
ssh production-server

&lt;span class="c"&gt;# Start following the logs&lt;/span&gt;
logchef &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/app/app.log

&lt;span class="c"&gt;# Press `/` and type "ERROR" to filter only errors&lt;/span&gt;
&lt;span class="c"&gt;# Press `l` to switch to error-only view&lt;/span&gt;
&lt;span class="c"&gt;# Use arrow keys to scroll through the error context&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You find the root cause in 30 seconds instead of 10 minutes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Local Development
&lt;/h3&gt;

&lt;p&gt;You're running a dev server and want to see errors only:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Run your server in background&lt;/span&gt;
npm run dev &amp;amp;

&lt;span class="c"&gt;# Follow logs, error-only&lt;/span&gt;
logchef &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nt"&gt;--level&lt;/span&gt; error logs/combined.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  CI/CD Debugging
&lt;/h3&gt;

&lt;p&gt;Your CI pipeline failed. You download the log artifact:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# CI artifact downloaded to build.log&lt;/span&gt;
logchef build.log

&lt;span class="c"&gt;# Search for the first error&lt;/span&gt;
/ ERROR

&lt;span class="c"&gt;# Jump to that line, scroll to see context&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;macOS / Linux (Homebrew):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;sulthonzh/tap/logchef
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Manual download:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Download from GitHub Releases&lt;/span&gt;
wget https://github.com/sulthonzh/logchef-zig/releases/latest/download/logchef-macos-arm64
&lt;span class="nb"&gt;chmod&lt;/span&gt; +x logchef-macos-arm64
&lt;span class="nb"&gt;mv &lt;/span&gt;logchef-macos-arm64 /usr/local/bin/logchef
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;From source:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Requires Zig 0.13+&lt;/span&gt;
git clone https://github.com/sulthonzh/logchef-zig.git
&lt;span class="nb"&gt;cd &lt;/span&gt;logchef-zig
zig build &lt;span class="nt"&gt;-Doptimize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ReleaseSafe
zig build &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Basic Usage
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# View a log file&lt;/span&gt;
logchef app.log

&lt;span class="c"&gt;# Follow mode (live updates)&lt;/span&gt;
logchef &lt;span class="nt"&gt;-f&lt;/span&gt; app.log

&lt;span class="c"&gt;# Filter by log level&lt;/span&gt;
logchef &lt;span class="nt"&gt;--level&lt;/span&gt; error app.log
logchef &lt;span class="nt"&gt;--level&lt;/span&gt; debug app.log

&lt;span class="c"&gt;# Search inside the viewer (press /)&lt;/span&gt;
logchef app.log
&lt;span class="c"&gt;# Press /, type pattern, enter&lt;/span&gt;
&lt;span class="c"&gt;# Use n/N for next/previous match&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;I'm planning:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Custom log format parsing (via CLI flags)&lt;/li&gt;
&lt;li&gt;Log aggregation (multiple files at once)&lt;/li&gt;
&lt;li&gt;Time-range filtering (&lt;code&gt;logchef --from "2h ago" --to "now" app.log&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But even in its current form, logchef-zig has replaced grep and tail for me.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/sulthonzh/logchef-zig" rel="noopener noreferrer"&gt;https://github.com/sulthonzh/logchef-zig&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Install: &lt;code&gt;brew install sulthonzh/tap/logchef&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Built with Zig. No dependencies. Just logs.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>zig</category>
      <category>performance</category>
      <category>cli</category>
      <category>devtools</category>
    </item>
    <item>
      <title>I Turned npm outdated into a CI Gate — Here's How</title>
      <dc:creator>Sulthon Zainul Habib</dc:creator>
      <pubDate>Sun, 24 May 2026 17:20:15 +0000</pubDate>
      <link>https://forem.com/sulthonzh/i-turned-npm-outdated-into-a-ci-gate-heres-how-h0o</link>
      <guid>https://forem.com/sulthonzh/i-turned-npm-outdated-into-a-ci-gate-heres-how-h0o</guid>
      <description>&lt;p&gt;You run &lt;code&gt;npm outdated&lt;/code&gt; and see a list of stale packages. But your CI doesn't care. It passes anyway. Dependencies drift until something explodes in production. There's no built-in way to fail the build when versions drift too far.## The Problem&lt;code&gt;npm outdated&lt;/code&gt; lists outdated dependencies, but:- No exit codes — CI cannot gate builds on the result- No threshold configuration — you can't say "fail if &amp;gt;2 minors behind"- No distinction between prod and dev dependencies in many workflows- Manual updates become a fire drill instead of a controlled processA typical scenario: Your team wants to stay current with security patches, but you can't update everything. You need a rule: "No production dependency more than 2 minor versions behind latest." &lt;code&gt;npm outdated&lt;/code&gt; can't enforce that.## The SolutionI built &lt;code&gt;npm-outdated-check&lt;/code&gt; to turn &lt;code&gt;npm outdated&lt;/code&gt; into a first-class CI citizen with:- Semantic version thresholding (major/minor/patch drift limits)- Meaningful exit codes (0 = pass, 1 = violation, 2 = config error, 3 = network error)- Configurable via CLI flags or a &lt;code&gt;.npm-outdated-check.json&lt;/code&gt; config file- Production/dev dependency filtering- Multiple output formats (text, table, JSON)## How It WorksThe tool reads your &lt;code&gt;package.json&lt;/code&gt;, queries the npm registry for each dependency, calculates the semantic version difference, and flags anything that exceeds your thresholds.Key implementation details:1. &lt;strong&gt;Registry fetching&lt;/strong&gt;: Hit the npm registry endpoint for each package and extract the &lt;code&gt;dist-tags.latest&lt;/code&gt; version2. &lt;strong&gt;Semver diff&lt;/strong&gt;: Use &lt;code&gt;semver&lt;/code&gt; to parse &lt;code&gt;coerce(current)&lt;/code&gt; and &lt;code&gt;parse(latest)&lt;/code&gt;, then compute &lt;code&gt;major/minor/patch&lt;/code&gt; differences3. &lt;strong&gt;Violation logic&lt;/strong&gt;: A package violates if any diff exceeds its configured &lt;code&gt;maxMajor&lt;/code&gt;/&lt;code&gt;maxMinor&lt;/code&gt;/&lt;code&gt;maxPatch&lt;/code&gt;4. &lt;strong&gt;Exit codes&lt;/strong&gt;: CI reads the exit code and fails the build when violations existSample threshold calculation:&lt;br&gt;
&lt;br&gt;
&lt;code&gt;typescriptconst majorDiff = latest.major - current.major;const minorDiff = latest.minor - current.minor;const patchDiff = latest.patch - current.patch;const isViolation =  majorDiff &amp;gt; config.maxMajor ||  minorDiff &amp;gt; config.minorDiff ||  patchDiff &amp;gt; config.maxPatch;&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting StartedInstall globally or as a dev dependency:
&lt;/h2&gt;

&lt;p&gt;&lt;br&gt;
&lt;code&gt;bashnpm install -D npm-outdated-check&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
Run it in CI with sensible defaults (major=0, minor=2, patch=5):&lt;br&gt;
&lt;br&gt;
&lt;code&gt;bashnpx npm-outdated-check&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
Add it to GitHub Actions:&lt;br&gt;
&lt;br&gt;
&lt;code&gt;yamlname: Dependency Checkon: [push, pull_request]jobs:  outdated-check:    runs-on: ubuntu-latest    steps:      - uses: actions/checkout@v4      - uses: actions/setup-node@v4        with:          node-version: '18'      - run: npm install      - run: npx npm-outdated-check --max-minor 3&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
If a dependency is 4 minor versions behind, CI fails and you get notified.## Why This Matters- &lt;strong&gt;Controlled updates&lt;/strong&gt;: Set thresholds to avoid surprise breaking changes- &lt;strong&gt;Security posture&lt;/strong&gt;: Enforce staying within N patch versions of latest- &lt;strong&gt;Team consistency&lt;/strong&gt;: Config rules checked automatically in CI- &lt;strong&gt;Zero config&lt;/strong&gt;: Works out of the box with smart defaults## What's NextRoadmap items include:- Configurable notification channels (Slack, email)- Automated PR generation for outdated packages- Support for Yarn and pnpm lockfiles- Monorepo workspace awareness## Links- GitHub: &lt;a href="https://github.com/sulthonzh/npm-outdated-check-" rel="noopener noreferrer"&gt;https://github.com/sulthonzh/npm-outdated-check-&lt;/a&gt; Try it: &lt;code&gt;npm install -D npm-outdated-check&lt;/code&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>ci</category>
      <category>devtools</category>
    </item>
  </channel>
</rss>
