<?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: siyadhkc</title>
    <description>The latest articles on Forem by siyadhkc (@siyadhkc).</description>
    <link>https://forem.com/siyadhkc</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%2F3868439%2F5c0b2e2e-0a7c-406f-9d99-1d810624972c.png</url>
      <title>Forem: siyadhkc</title>
      <link>https://forem.com/siyadhkc</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/siyadhkc"/>
    <language>en</language>
    <item>
      <title>I built a JSON CLI tool with Bun and TypeScript — here's what actually happened</title>
      <dc:creator>siyadhkc</dc:creator>
      <pubDate>Mon, 11 May 2026 01:31:57 +0000</pubDate>
      <link>https://forem.com/siyadhkc/i-built-a-json-cli-tool-with-bun-and-typescript-heres-what-actually-happened-28ek</link>
      <guid>https://forem.com/siyadhkc/i-built-a-json-cli-tool-with-bun-and-typescript-heres-what-actually-happened-28ek</guid>
      <description>&lt;p&gt;I wanted a tool that could flatten JSON, filter it, colorize output, and fetch from a URL — all from&lt;br&gt;
the terminal. Something between &lt;code&gt;jq&lt;/code&gt; and &lt;code&gt;gron&lt;/code&gt; but with a cleaner, more intuitive API. So I built&lt;br&gt;
&lt;code&gt;jray&lt;/code&gt;. This is the honest post-mortem of how it went.&lt;/p&gt;



&lt;p&gt;GitHub: &lt;a href="https://github.com/siyadhkc/jray" rel="noopener noreferrer"&gt;github.com/siyadhkc/jray&lt;/a&gt;&lt;br&gt;
Website:&lt;a href="https://siyadhkc.github.io/Jray" rel="noopener noreferrer"&gt;siyadhkc.github.io/Jray&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Why I built it
&lt;/h2&gt;

&lt;p&gt;Every time I'm debugging an API response or poking around some nested config file, I reach for &lt;code&gt;jq&lt;/code&gt;.&lt;br&gt;
And every time, I spend the first five minutes googling the syntax again. &lt;code&gt;jq&lt;/code&gt; is powerful — genuinely&lt;br&gt;
— but it's its own language, and unless you're writing complex transformations daily, that overhead&lt;br&gt;
adds up.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gron&lt;/code&gt; is the other tool I kept coming back to. It flattens JSON into greppable dot-notation, which&lt;br&gt;
is exactly what you want when you're trying to find where a deeply nested key lives. But &lt;code&gt;gron&lt;/code&gt; is&lt;br&gt;
read-only. You can't filter and get structured output back. You can't fetch from a URL. The color&lt;br&gt;
situation is nonexistent.&lt;/p&gt;

&lt;p&gt;So I scoped out what I actually needed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Flatten JSON to dot-notation paths (&lt;code&gt;a.b.c = value&lt;/code&gt;) so I can see structure at a glance&lt;/li&gt;
&lt;li&gt;Filter by key pattern without learning a query language&lt;/li&gt;
&lt;li&gt;Fetch directly from a URL so I don't have to &lt;code&gt;curl | jray&lt;/code&gt; every time&lt;/li&gt;
&lt;li&gt;Color output by default on TTY&lt;/li&gt;
&lt;li&gt;Fast enough that it doesn't feel like overhead when I'm in the middle of something&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bun was the obvious runtime choice. Fast cold start, native TypeScript support, a built-in test&lt;br&gt;
runner, and &lt;code&gt;bun build --compile&lt;/code&gt; that bundles everything into a single self-contained binary. No&lt;br&gt;
Node.js version headaches, no separate install step for the runtime.&lt;/p&gt;


&lt;h2&gt;
  
  
  How it's structured
&lt;/h2&gt;

&lt;p&gt;I kept the architecture intentionally flat. No frameworks, minimal dependencies. The core logic is&lt;br&gt;
split into focused modules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;flatten.ts&lt;/code&gt; — recursive flatten and unflatten. Takes a nested object and produces a map of
dot-notation paths to primitive values. Unflatten goes the other direction.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;filter.ts&lt;/code&gt; — glob-style pattern matching on the flattened keys. &lt;code&gt;user.*&lt;/code&gt; gives you everything
under &lt;code&gt;user&lt;/code&gt;, &lt;code&gt;**.id&lt;/code&gt; matches any &lt;code&gt;id&lt;/code&gt; at any depth.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;color.ts&lt;/code&gt; — ANSI color output. Keys in one color, values type-aware (strings, numbers, booleans
each get their own).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fetch.ts&lt;/code&gt; — thin wrapper around &lt;code&gt;Bun.fetch&lt;/code&gt; that handles the request, checks content type, and
pipes the response into the flatten pipeline.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cli.ts&lt;/code&gt; — argument parsing and wiring. Reads from stdin, a file path, or a URL depending on what
flags you pass.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The whole thing compiles down to a single binary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bun build ./src/cli.ts &lt;span class="nt"&gt;--compile&lt;/span&gt; &lt;span class="nt"&gt;--outfile&lt;/span&gt; jray
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No runtime dependency on Bun after that. You ship the binary, it works.&lt;/p&gt;




&lt;h2&gt;
  
  
  The problems I actually ran into
&lt;/h2&gt;

&lt;h3&gt;
  
  
  npm name conflict
&lt;/h3&gt;

&lt;p&gt;First thing I did after writing the initial working version was try to publish as &lt;code&gt;jray&lt;/code&gt;. Already&lt;br&gt;
taken — and not squatted. An actual published package with actual users. So I had to switch to a&lt;br&gt;
scoped package: &lt;code&gt;@siyadkc/jray&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That sounds like a small change but it cascades. The README, the install command in all the&lt;br&gt;
examples, the binary name in &lt;code&gt;package.json&lt;/code&gt;, the GitHub Actions publish step, the Dev.to article&lt;br&gt;
draft I'd already half-written — all of it needed updating. It also changes how users install it&lt;br&gt;
slightly, since scoped packages require the &lt;code&gt;@&lt;/code&gt; prefix. Not a dealbreaker, but check npm before you&lt;br&gt;
name your CLI.&lt;/p&gt;
&lt;h3&gt;
  
  
  Package size bloat
&lt;/h3&gt;

&lt;p&gt;My first publish was heavier than it needed to be. Bun's compiled binary includes the runtime,&lt;br&gt;
which is expected and fine. But the npm package itself had no &lt;code&gt;files&lt;/code&gt; field, so it was packaging&lt;br&gt;
everything — source maps, test files, the &lt;code&gt;node_modules&lt;/code&gt; from dev, local configs. None of that&lt;br&gt;
belongs in a published package.&lt;/p&gt;

&lt;p&gt;Fix was straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"files"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"dist/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"README.md"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That single field cut the published package weight significantly. Always define &lt;code&gt;files&lt;/code&gt;. The npm&lt;br&gt;
registry doesn't know what's dev and what's production unless you tell it.&lt;/p&gt;
&lt;h3&gt;
  
  
  Windows compatibility
&lt;/h3&gt;

&lt;p&gt;I had a &lt;code&gt;postinstall&lt;/code&gt; script that ran &lt;code&gt;chmod +x&lt;/code&gt; on the binary. Works perfectly on Linux and macOS.&lt;br&gt;
On Windows it throws and the install fails. I wrapped it in a try-catch and updated the docs to note&lt;br&gt;
that Windows users should either run the binary path directly or use WSL. Not the cleanest solution,&lt;br&gt;
but honest about the platform situation. Full Windows support is on the roadmap.&lt;/p&gt;
&lt;h3&gt;
  
  
  GitHub Actions for CI and publishing
&lt;/h3&gt;

&lt;p&gt;The pipeline itself wasn't complicated — install Bun, run tests, publish to npm on a version tag.&lt;br&gt;
But there's one specific thing that tripped me up: not using &lt;code&gt;--frozen-lockfile&lt;/code&gt; in CI.&lt;/p&gt;

&lt;p&gt;Without it, &lt;code&gt;bun install&lt;/code&gt; in CI can silently update the lockfile, which means your CI might be&lt;br&gt;
testing against different dependency versions than what you developed against. Always use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;oven-sh/setup-bun@v1&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;bun-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;latest&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bun install --frozen-lockfile&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bun test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Publishing to npm from Actions requires setting &lt;code&gt;NPM_TOKEN&lt;/code&gt; as a repository secret and passing it&lt;br&gt;
through to the publish step. Once that's wired, releases are a tag push away.&lt;/p&gt;




&lt;h2&gt;
  
  
  What it actually does
&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;# Install&lt;/span&gt;
bun add &lt;span class="nt"&gt;-g&lt;/span&gt; @siyadkc/jray

&lt;span class="c"&gt;# Flatten JSON from stdin&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'{"user":{"name":"Eliot","age":24}}'&lt;/span&gt; | jray
&lt;span class="c"&gt;# user.name = "Eliot"&lt;/span&gt;
&lt;span class="c"&gt;# user.age = 24&lt;/span&gt;

&lt;span class="c"&gt;# Flatten a local file&lt;/span&gt;
jray data.json

&lt;span class="c"&gt;# Filter by key pattern&lt;/span&gt;
jray &lt;span class="nt"&gt;--filter&lt;/span&gt; &lt;span class="s2"&gt;"user.*"&lt;/span&gt; data.json
&lt;span class="c"&gt;# user.name = "Eliot"&lt;/span&gt;
&lt;span class="c"&gt;# user.age = 24&lt;/span&gt;

&lt;span class="c"&gt;# Fetch from a URL and flatten&lt;/span&gt;
jray &lt;span class="nt"&gt;--fetch&lt;/span&gt; https://api.example.com/users/1

&lt;span class="c"&gt;# Disable color (for piping into other tools)&lt;/span&gt;
jray &lt;span class="nt"&gt;--no-color&lt;/span&gt; data.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The filter uses glob-style matching against the full dot-path of each key. So &lt;code&gt;user.*&lt;/code&gt; matches one&lt;br&gt;
level under &lt;code&gt;user&lt;/code&gt;, while &lt;code&gt;**.id&lt;/code&gt; would match any &lt;code&gt;id&lt;/code&gt; at any depth in the document. It's&lt;br&gt;
intentionally simpler than jq's filter syntax — the goal is something you can remember without&lt;br&gt;
looking it up.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where it sits vs the competition
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;gron&lt;/code&gt; is the closest thing and the most direct comparison. It also flattens to dot-notation and&lt;br&gt;
it's what made me realize there was a gap to fill. But &lt;code&gt;gron&lt;/code&gt; has no color output, no URL fetching,&lt;br&gt;
and no NDJSON streaming support. &lt;code&gt;jray&lt;/code&gt; has all three.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;jq&lt;/code&gt; is in a different category. It's a transformation tool — you write expressions, you reshape&lt;br&gt;
data, you do complex operations. &lt;code&gt;jray&lt;/code&gt; is an inspection tool. You throw data at it and you&lt;br&gt;
understand the structure immediately. They're complementary more than they're competing.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;fx&lt;/code&gt; is another one that comes up. Interactive, powerful, but it's a TUI. If you're in a script or&lt;br&gt;
piping between tools, you don't want a TUI. &lt;code&gt;jray&lt;/code&gt; is designed to be pipeline-friendly from the&lt;br&gt;
start.&lt;/p&gt;

&lt;p&gt;The longer-term vision is broader than just JSON. Supporting YAML and TOML with the same flatten&lt;br&gt;
and filter interface makes it a universal structured-data CLI. There's also TOON (Token Oriented&lt;br&gt;
Object Notation), which is an emerging format that's genuinely useful for LLM developer workflows&lt;br&gt;
since it's optimized for tokenization. That's a real differentiator if the format gets traction.&lt;/p&gt;




&lt;h2&gt;
  
  
  The launch
&lt;/h2&gt;

&lt;p&gt;Published to npm, wrote this article, posted on X . Also shared in the Bun&lt;br&gt;
Discord since the community there is small enough that people actually read it.&lt;/p&gt;

&lt;p&gt;The GitHub Pages site is live. It's getting redesigned right now — moving toward a flatter, more&lt;br&gt;
minimal aesthetic with an interactive playground section where you can paste JSON directly in the&lt;br&gt;
browser and see the flatten and filter output in real time. No install required to try it. That&lt;br&gt;
single feature will probably do more for adoption than any amount of posting.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I'd do differently
&lt;/h2&gt;

&lt;p&gt;I'd define the &lt;code&gt;files&lt;/code&gt; field before the first publish, not after. I'd also check npm for name&lt;br&gt;
conflicts before I was emotionally attached to the name. And I'd set up the CI pipeline before&lt;br&gt;
the first push to &lt;code&gt;main&lt;/code&gt; so I wasn't debugging GitHub Actions at the same time I was trying to&lt;br&gt;
ship.&lt;/p&gt;

&lt;p&gt;The architecture decisions held up fine. Bun was the right call. The modular structure meant I&lt;br&gt;
could add &lt;code&gt;fetch.ts&lt;/code&gt; and &lt;code&gt;color.ts&lt;/code&gt; without touching the core flatten logic. That's about as much&lt;br&gt;
as you can ask from a first project's structure.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bun add &lt;span class="nt"&gt;-g&lt;/span&gt; @siyadkc/jray
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GitHub: &lt;a href="https://github.com/siyadhkc/jray" rel="noopener noreferrer"&gt;github.com/siyadhkc/jray&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you're working on something similar with Bun, or you have opinions on the filter API design,&lt;br&gt;
drop a comment. Always curious how other people are solving the same problems.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is my first article writing on this platform so if i made any narration mistake or anything feel free to tell me, i will improve my writing skill and the way of telling this&lt;br&gt;
-- let's get connected --&lt;/em&gt; &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>tutorial</category>
      <category>opensource</category>
      <category>cli</category>
    </item>
    <item>
      <title>From Hardware to Hacking: How Understanding Systems Changed My Approach to Security</title>
      <dc:creator>siyadhkc</dc:creator>
      <pubDate>Wed, 15 Apr 2026 15:56:13 +0000</pubDate>
      <link>https://forem.com/siyadhkc/from-hardware-to-hacking-how-understanding-systems-changed-my-approach-to-security-4dh4</link>
      <guid>https://forem.com/siyadhkc/from-hardware-to-hacking-how-understanding-systems-changed-my-approach-to-security-4dh4</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I didn’t start my journey in cybersecurity. I started with hardware and networking, learning how systems actually function at a low level — how machines communicate, how configurations impact behavior, and how failures happen.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Shift to Development
&lt;/h2&gt;

&lt;p&gt;Later, I moved into development, working with Python and full-stack technologies. Building applications helped me understand how software is structured, but it also revealed something important:&lt;/p&gt;

&lt;p&gt;Most applications are not built with security as a priority.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Turning Point
&lt;/h2&gt;

&lt;p&gt;This realization pushed me toward cybersecurity, specifically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Web application security&lt;/li&gt;
&lt;li&gt;API security&lt;/li&gt;
&lt;li&gt;Cloud platforms (AWS, Azure, GCP)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of just building systems, I began analyzing how they can be exploited.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Different Way of Thinking
&lt;/h2&gt;

&lt;p&gt;The biggest shift was in mindset:&lt;/p&gt;

&lt;p&gt;From:&lt;br&gt;
“How do I build this system?”&lt;/p&gt;

&lt;p&gt;To:&lt;br&gt;
“How can this system fail or be attacked?”&lt;/p&gt;

&lt;p&gt;This dual perspective — builder and attacker — is critical in modern cybersecurity.&lt;/p&gt;

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

&lt;p&gt;I’ll be sharing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Practical security insights&lt;/li&gt;
&lt;li&gt;Real-world learning experiences&lt;/li&gt;
&lt;li&gt;Breakdowns of vulnerabilities and misconfigurations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re interested in understanding systems deeply — not just building them, but also testing their limits — follow along.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>productivity</category>
      <category>tutorial</category>
      <category>career</category>
    </item>
    <item>
      <title>I built a modern alternative to gron using Bun and TypeScript</title>
      <dc:creator>siyadhkc</dc:creator>
      <pubDate>Sun, 12 Apr 2026 17:16:36 +0000</pubDate>
      <link>https://forem.com/siyadhkc/i-built-a-modern-alternative-to-gron-using-bun-and-typescript-3358</link>
      <guid>https://forem.com/siyadhkc/i-built-a-modern-alternative-to-gron-using-bun-and-typescript-3358</guid>
      <description>&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;Working with JSON in the terminal is painful. &lt;code&gt;jq&lt;/code&gt; is powerful &lt;br&gt;
but requires learning a whole query language. &lt;code&gt;grep&lt;/code&gt; works but &lt;br&gt;
matches values too — not just paths.&lt;/p&gt;

&lt;p&gt;For example if I search for "name" in my JSON:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;grep matches &lt;code&gt;json.user.name&lt;/code&gt; ✅ (correct)&lt;/li&gt;
&lt;li&gt;grep also matches &lt;code&gt;json.bio = "my name is Alice"&lt;/code&gt; ❌ (wrong)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I built &lt;strong&gt;jray&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  What jray does
&lt;/h2&gt;

&lt;p&gt;jray flattens any JSON into one line per value:&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="nv"&gt;$ &lt;/span&gt;jray data.json
json.organization.name &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Acme Corporation"&lt;/span&gt;
json.users[0].name &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Alice Pemberton"&lt;/span&gt;
json.users[0].role &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"admin"&lt;/span&gt;
json.users[0].active &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;true
&lt;/span&gt;json.billing.plan &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"enterprise"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can grep it, awk it, pipe it — using tools you already know.&lt;/p&gt;

&lt;h2&gt;
  
  
  Four commands that cover everything
&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;# Flatten with color output&lt;/span&gt;
jray data.json

&lt;span class="c"&gt;# Fetch a URL directly — no curl needed&lt;/span&gt;
jray https://jsonplaceholder.typicode.com/users/1

&lt;span class="c"&gt;# Filter by path only (never matches values)&lt;/span&gt;
jray data.json &lt;span class="nt"&gt;--filter&lt;/span&gt; &lt;span class="s2"&gt;"billing"&lt;/span&gt;

&lt;span class="c"&gt;# Extract any subtree as clean JSON&lt;/span&gt;
jray data.json &lt;span class="nt"&gt;--select&lt;/span&gt; &lt;span class="s2"&gt;"billing"&lt;/span&gt;

&lt;span class="c"&gt;# Print just the values&lt;/span&gt;
jray data.json &lt;span class="nt"&gt;--values&lt;/span&gt;

&lt;span class="c"&gt;# Reconstruct original JSON&lt;/span&gt;
jray data.json | jray &lt;span class="nt"&gt;--ungron&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The comparison with existing tools
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;jray&lt;/th&gt;
&lt;th&gt;jq&lt;/th&gt;
&lt;th&gt;gron&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Flatten to lines&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reconstruct JSON&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Filter by path&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extract subtree&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fetch from URLs&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Color output&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No query language&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TypeScript / modern&lt;/td&gt;
&lt;td&gt;✅&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;
  
  
  What I learned building it
&lt;/h2&gt;

&lt;p&gt;This was my first open source CLI tool. Key lessons:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Separate your CLI from your logic&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;cli.ts&lt;/code&gt; handles only I/O — reading files, printing output.&lt;br&gt;
&lt;code&gt;flatten.ts&lt;/code&gt;, &lt;code&gt;filter.ts&lt;/code&gt; etc. know nothing about terminals.&lt;br&gt;
This makes everything testable in isolation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Use &lt;code&gt;unknown&lt;/code&gt; not &lt;code&gt;any&lt;/code&gt; in TypeScript&lt;/strong&gt;&lt;br&gt;
JSON is dynamic but that doesn't mean &lt;code&gt;any&lt;/code&gt;. Using &lt;code&gt;unknown&lt;/code&gt; &lt;br&gt;
forces you to check types before using values — much safer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Recursive functions are perfect for JSON&lt;/strong&gt;&lt;br&gt;
JSON is a tree. Walking a tree with recursion is the &lt;br&gt;
cleanest pattern — each call handles one node and &lt;br&gt;
delegates children back to itself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Bun is genuinely fast and simple&lt;/strong&gt;&lt;br&gt;
Native TypeScript, built-in fetch, fast startup. &lt;br&gt;
For a CLI tool, Bun is a great choice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. The README matters as much as the code&lt;/strong&gt;&lt;br&gt;
Nobody uses a tool they can't understand in 30 seconds.&lt;br&gt;
Writing clear examples with real output is as important &lt;br&gt;
as writing the code itself.&lt;/p&gt;
&lt;h2&gt;
  
  
  Install and try it
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @siyadkc/jray
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jray https://jsonplaceholder.typicode.com/users/1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GitHub: &lt;a href="https://github.com/siyadhkc/Jray" rel="noopener noreferrer"&gt;github.com/siyadhkc/Jray&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;for more info Website: &lt;a href="https://siyadhkc.github.io/Jray/" rel="noopener noreferrer"&gt;https://siyadhkc.github.io/Jray/&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;This is my first open source tool. Feedback on the code &lt;br&gt;
quality is very welcome — especially from experienced &lt;br&gt;
TypeScript developers!&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>bunjs</category>
      <category>opensource</category>
      <category>cli</category>
    </item>
  </channel>
</rss>
