<?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>DEV Community: Robin Alex Panicker</title>
    <description>The latest articles on DEV Community by Robin Alex Panicker (@robin_a_p).</description>
    <link>https://dev.to/robin_a_p</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%2F267440%2F30a188e4-588c-45bf-9b7b-97cb7102183e.png</url>
      <title>DEV Community: Robin Alex Panicker</title>
      <link>https://dev.to/robin_a_p</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/robin_a_p"/>
    <language>en</language>
    <item>
      <title>AxKeyStore: A Zero-Trust CLI for Managing Secrets Using GitHub as Your Backend</title>
      <dc:creator>Robin Alex Panicker</dc:creator>
      <pubDate>Sun, 29 Mar 2026 11:18:28 +0000</pubDate>
      <link>https://dev.to/robin_a_p/axkeystore-a-zero-trust-cli-for-managing-secrets-using-github-as-your-backend-e0m</link>
      <guid>https://dev.to/robin_a_p/axkeystore-a-zero-trust-cli-for-managing-secrets-using-github-as-your-backend-e0m</guid>
      <description>&lt;p&gt;Most developers today juggle secrets across multiple environments—API keys, database credentials, tokens, signing keys. The typical solutions fall into three buckets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;.env&lt;/code&gt; files (simple, but unsafe and unscalable)&lt;/li&gt;
&lt;li&gt;Cloud secret managers (secure, but expensive and vendor-locked)&lt;/li&gt;
&lt;li&gt;Password managers (not developer-native)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;AxKeyStore&lt;/strong&gt; introduces a different approach:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Use your own GitHub repository as an encrypted, versioned, zero-trust secret store—fully controlled by you.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This article breaks down how AxKeyStore works, why its architecture matters, and how you can integrate it into your workflow.&lt;/p&gt;

&lt;p&gt;AxKeyStore is MIT Licensed Open Source project - &lt;a href="https://github.com/basilgregory/axkeystore" rel="noopener noreferrer"&gt;https://github.com/basilgregory/axkeystore&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Core Idea
&lt;/h2&gt;

&lt;p&gt;AxKeyStore is a &lt;strong&gt;CLI-first secret manager&lt;/strong&gt; that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stores secrets in &lt;strong&gt;your own private GitHub repo&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Uses &lt;strong&gt;client-side encryption only&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Treats GitHub as &lt;strong&gt;untrusted storage&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Ensures &lt;strong&gt;no plaintext secrets ever leave your machine&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This flips the traditional model:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Traditional Secret Manager&lt;/th&gt;
&lt;th&gt;AxKeyStore&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Trust the provider&lt;/td&gt;
&lt;td&gt;Trust only your machine&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Secrets decrypted in cloud&lt;/td&gt;
&lt;td&gt;Secrets decrypted locally&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vendor-controlled infra&lt;/td&gt;
&lt;td&gt;Your GitHub repo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Centralized trust&lt;/td&gt;
&lt;td&gt;Zero-trust&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Architecture Overview
&lt;/h2&gt;

&lt;p&gt;AxKeyStore is built on a &lt;strong&gt;multi-layer encryption model&lt;/strong&gt; designed for strict isolation and zero trust.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Key Hierarchy
&lt;/h3&gt;

&lt;p&gt;There are two core keys:&lt;/p&gt;

&lt;h4&gt;
  
  
  Local Master Key (LMK)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Generated per profile&lt;/li&gt;
&lt;li&gt;Stored locally&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Encrypts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub token&lt;/li&gt;
&lt;li&gt;Repository configuration&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h4&gt;
  
  
  Remote Master Key (RMK)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Stored in GitHub (encrypted)&lt;/li&gt;
&lt;li&gt;Used to encrypt actual secrets&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  2. Encryption Layers
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Secret → encrypted with RMK
RMK → encrypted with Master Password
Local config → encrypted with LMK
LMK → encrypted with Master Password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a &lt;strong&gt;3-layer protection model&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Secrets are never stored in plaintext&lt;/li&gt;
&lt;li&gt;GitHub only sees encrypted blobs&lt;/li&gt;
&lt;li&gt;Even local config is encrypted&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  3. Cryptography Choices
&lt;/h3&gt;

&lt;p&gt;AxKeyStore uses modern primitives:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;XChaCha20-Poly1305&lt;/strong&gt; → authenticated encryption&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Argon2id&lt;/strong&gt; → password-based key derivation&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Client-side encryption only&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Implication:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Even if GitHub is compromised, your secrets remain secure.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Why GitHub as a Backend?
&lt;/h2&gt;

&lt;p&gt;This is the most unconventional design decision—and also the most powerful.&lt;/p&gt;

&lt;h3&gt;
  
  
  Benefits
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Version Control for Secrets
&lt;/h4&gt;

&lt;p&gt;Every update becomes a commit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;axkeystore &lt;span class="nb"&gt;history&lt;/span&gt; &lt;span class="s2"&gt;"api-key"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Full audit trail&lt;/li&gt;
&lt;li&gt;Rollbacks via commit SHA&lt;/li&gt;
&lt;li&gt;Time-based debugging&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  2. Free, Reliable Infrastructure
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;No infra to maintain&lt;/li&gt;
&lt;li&gt;No billing surprises&lt;/li&gt;
&lt;li&gt;Global availability&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  3. Ownership &amp;amp; Portability
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;You control the repo&lt;/li&gt;
&lt;li&gt;No vendor lock-in&lt;/li&gt;
&lt;li&gt;Works across machines instantly&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Developer Experience
&lt;/h2&gt;

&lt;p&gt;AxKeyStore is designed for &lt;strong&gt;daily CLI usage&lt;/strong&gt;, not dashboards.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;axkeystore login
axkeystore init &lt;span class="nt"&gt;--repo&lt;/span&gt; my-secret-store
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Store a Secret
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;axkeystore store &lt;span class="nt"&gt;--key&lt;/span&gt; &lt;span class="s2"&gt;"stripe-api-key"&lt;/span&gt; &lt;span class="nt"&gt;--value&lt;/span&gt; &lt;span class="s2"&gt;"sk_live_..."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or auto-generate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;axkeystore store &lt;span class="nt"&gt;--key&lt;/span&gt; &lt;span class="s2"&gt;"jwt-secret"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Retrieve a Secret
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;axkeystore get &lt;span class="s2"&gt;"stripe-api-key"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Organize by Environment
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;axkeystore store &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--key&lt;/span&gt; &lt;span class="s2"&gt;"db-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--category&lt;/span&gt; &lt;span class="s2"&gt;"prod/database"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates structured storage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;prod/database/db-password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  List Everything
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;axkeystore list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[prod/database]&lt;/span&gt;
  &lt;span class="py"&gt;db-password&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;****&lt;/span&gt;

&lt;span class="nn"&gt;[api]&lt;/span&gt;
  &lt;span class="py"&gt;stripe-key&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;****&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Profiles: Multi-Environment Isolation
&lt;/h2&gt;

&lt;p&gt;AxKeyStore supports &lt;strong&gt;multiple profiles&lt;/strong&gt;, each with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Separate GitHub repo&lt;/li&gt;
&lt;li&gt;Separate master password&lt;/li&gt;
&lt;li&gt;Separate keyspace&lt;/li&gt;
&lt;/ul&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;axkeystore profile create work
axkeystore profile switch work
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Personal vs Work&lt;/li&gt;
&lt;li&gt;Dev vs Prod&lt;/li&gt;
&lt;li&gt;Multi-tenant SaaS ops&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Security Model Deep Dive
&lt;/h2&gt;

&lt;p&gt;Let’s break down the threat model.&lt;/p&gt;

&lt;h3&gt;
  
  
  What if GitHub is compromised?
&lt;/h3&gt;

&lt;p&gt;Attacker sees:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Encrypted blobs&lt;/li&gt;
&lt;li&gt;Encrypted RMK&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They &lt;strong&gt;cannot decrypt&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RMK (needs master password)&lt;/li&gt;
&lt;li&gt;Secrets (needs RMK)&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  What if local machine is compromised?
&lt;/h3&gt;

&lt;p&gt;Attacker sees:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Encrypted LMK&lt;/li&gt;
&lt;li&gt;Encrypted token&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Still needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Master password&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  What if both are compromised?
&lt;/h3&gt;

&lt;p&gt;Only then:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;System becomes vulnerable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is consistent with &lt;strong&gt;zero-trust design principles&lt;/strong&gt;.&lt;/p&gt;




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

&lt;h3&gt;
  
  
  vs &lt;code&gt;.env&lt;/code&gt; Files
&lt;/h3&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;&lt;code&gt;.env&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;AxKeyStore&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Encryption&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Versioning&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sharing&lt;/td&gt;
&lt;td&gt;Manual&lt;/td&gt;
&lt;td&gt;GitHub-native&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Security&lt;/td&gt;
&lt;td&gt;Weak&lt;/td&gt;
&lt;td&gt;Strong&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  vs Cloud Secret Managers
&lt;/h3&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;Cloud (AWS/GCP)&lt;/th&gt;
&lt;th&gt;AxKeyStore&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cost&lt;/td&gt;
&lt;td&gt;$$$&lt;/td&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Setup&lt;/td&gt;
&lt;td&gt;Complex&lt;/td&gt;
&lt;td&gt;Simple&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lock-in&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Control&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;Full&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  vs Vault (HashiCorp)
&lt;/h3&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;Vault&lt;/th&gt;
&lt;th&gt;AxKeyStore&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Infra required&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ops overhead&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Zero&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dev UX&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;td&gt;CLI-native&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Where AxKeyStore Fits Best
&lt;/h2&gt;

&lt;p&gt;AxKeyStore is ideal for:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Indie Hackers / Startups
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;No infra overhead&lt;/li&gt;
&lt;li&gt;Free secret storage&lt;/li&gt;
&lt;li&gt;Works instantly&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. CLI-first Engineers
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;No dashboards&lt;/li&gt;
&lt;li&gt;Scriptable&lt;/li&gt;
&lt;li&gt;Fast workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Multi-Repo Developers
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Secrets tied to GitHub repos&lt;/li&gt;
&lt;li&gt;Natural workflow integration&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Where It May Not Fit
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Enterprises needing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RBAC policies&lt;/li&gt;
&lt;li&gt;Secret rotation automation&lt;/li&gt;
&lt;li&gt;Compliance (SOC2, etc.)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Real-time secret injection into runtime (no agent model yet)&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  Advanced Use Cases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. CI/CD Integration
&lt;/h3&gt;

&lt;p&gt;You can pull secrets during pipeline execution:&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;SECRET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;axkeystore get &lt;span class="s2"&gt;"api-key"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  2. Version Debugging
&lt;/h3&gt;

&lt;p&gt;Roll back to a previous secret:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;axkeystore get &lt;span class="s2"&gt;"api-key"&lt;/span&gt; &lt;span class="nt"&gt;--version&lt;/span&gt; &amp;lt;SHA&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  3. Secret Generation
&lt;/h3&gt;

&lt;p&gt;Let AxKeyStore generate secure values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;axkeystore store &lt;span class="nt"&gt;--key&lt;/span&gt; &lt;span class="s2"&gt;"jwt-secret"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Internal Design Insights (For Builders)
&lt;/h2&gt;

&lt;p&gt;AxKeyStore is implemented in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Rust&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Async via &lt;code&gt;tokio&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;CLI via &lt;code&gt;clap&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Key design decisions:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. GitHub as API Layer
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Uses GitHub Contents API&lt;/li&gt;
&lt;li&gt;Stores secrets as files&lt;/li&gt;
&lt;li&gt;Leverages commit history&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Profile Isolation via Filesystem
&lt;/h3&gt;

&lt;p&gt;Each profile has its own config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/.config/com.ax.axkeystore/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. No Plaintext Persistence
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Everything encrypted at rest&lt;/li&gt;
&lt;li&gt;No caching of decrypted values&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Strategic Insight
&lt;/h2&gt;

&lt;p&gt;AxKeyStore represents a broader shift:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Decoupling infrastructure from trust&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Trusting AWS / Vault / providers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Trust cryptography&lt;/li&gt;
&lt;li&gt;Own storage&lt;/li&gt;
&lt;li&gt;Control access&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This pattern will likely expand into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Logs&lt;/li&gt;
&lt;li&gt;Analytics&lt;/li&gt;
&lt;li&gt;Observability (similar to what tools like Appxiom are doing)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;AxKeyStore is not trying to replace enterprise secret managers.&lt;/p&gt;

&lt;p&gt;It’s targeting a different segment:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Developers who want &lt;strong&gt;control, simplicity, and strong security without infrastructure overhead&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If your current workflow involves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;.env&lt;/code&gt; files&lt;/li&gt;
&lt;li&gt;Copy-pasting secrets&lt;/li&gt;
&lt;li&gt;Manual sharing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then AxKeyStore is a meaningful upgrade.&lt;/p&gt;




&lt;h2&gt;
  
  
  Get Started
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sSL&lt;/span&gt; https://raw.githubusercontent.com/basilgregory/axkeystore/main/install.sh | bash
&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;axkeystore login
axkeystore init &lt;span class="nt"&gt;--repo&lt;/span&gt; my-secret-store
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;If you’re building developer tools or care about security architecture, AxKeyStore is worth studying—not just using.&lt;/p&gt;

&lt;p&gt;It’s a clean example of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Zero trust&lt;/li&gt;
&lt;li&gt;Client-side encryption&lt;/li&gt;
&lt;li&gt;Leveraging existing infra (GitHub) in unconventional ways&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>security</category>
      <category>developers</category>
      <category>git</category>
      <category>github</category>
    </item>
    <item>
      <title>Top 5 ANR Detection Tools for Flutter Apps in 2026</title>
      <dc:creator>Robin Alex Panicker</dc:creator>
      <pubDate>Sun, 22 Mar 2026 07:11:54 +0000</pubDate>
      <link>https://dev.to/robin_a_p/top-5-anr-detection-tools-for-flutter-apps-in-2026-2e63</link>
      <guid>https://dev.to/robin_a_p/top-5-anr-detection-tools-for-flutter-apps-in-2026-2e63</guid>
      <description>&lt;p&gt;Application Not Responding (ANR) issues are one of the most frustrating performance problems in Android mobile apps. Unlike crashes, ANRs silently degrade user experience-leading to app abandonment, poor ratings, and revenue loss.&lt;/p&gt;

&lt;p&gt;For Flutter apps, detecting ANRs is even more complex because issues can originate from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dart (UI thread / isolates)&lt;/li&gt;
&lt;li&gt;Native Android code (main thread blocking)&lt;/li&gt;
&lt;li&gt;Platform channels (Flutter ↔ native bridge)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In 2026, modern monitoring tools go beyond simple logging-they provide &lt;strong&gt;real-time detection, root cause analysis, and user journey context&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here are the &lt;strong&gt;top 5 ANR detection tools for Flutter apps in 2026&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Firebase Crashlytics
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://firebase.google.com/products/crashlytics" rel="noopener noreferrer"&gt;https://firebase.google.com/products/crashlytics&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;Firebase Crashlytics remains one of the most widely used tools for mobile error monitoring. It provides &lt;strong&gt;basic ANR detection on Android&lt;/strong&gt; along with crash reporting.&lt;/p&gt;

&lt;p&gt;While primarily designed for crashes, Crashlytics can surface ANRs through system-level signals and integrates with Firebase Performance Monitoring.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Real-time crash and ANR alerts
&lt;/li&gt;
&lt;li&gt;Lightweight SDK with minimal overhead
&lt;/li&gt;
&lt;li&gt;Tight integration with Firebase ecosystem
&lt;/li&gt;
&lt;li&gt;Basic stack trace visibility
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Free and easy to set up
&lt;/li&gt;
&lt;li&gt;Widely adopted and well-documented
&lt;/li&gt;
&lt;li&gt;Works seamlessly with Flutter
&lt;/li&gt;
&lt;li&gt;Good starting point for small teams
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Limited ANR insights (no deep root cause analysis)
&lt;/li&gt;
&lt;li&gt;No session-level context or user journey mapping
&lt;/li&gt;
&lt;li&gt;Difficult to debug complex UI freezes
&lt;/li&gt;
&lt;li&gt;Not ideal for large-scale performance monitoring
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2. Sentry
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://sentry.io" rel="noopener noreferrer"&gt;https://sentry.io&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;Sentry is a developer-first observability platform that provides &lt;strong&gt;detailed error tracking, performance monitoring, and partial ANR visibility&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It is particularly strong in &lt;strong&gt;debugging context&lt;/strong&gt;, offering deep insights into what happened before an issue occurred.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Real-time error and performance monitoring
&lt;/li&gt;
&lt;li&gt;Distributed tracing
&lt;/li&gt;
&lt;li&gt;Release tracking and regression detection
&lt;/li&gt;
&lt;li&gt;Detailed stack traces and breadcrumbs
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Extremely rich debugging context
&lt;/li&gt;
&lt;li&gt;Strong Flutter SDK support
&lt;/li&gt;
&lt;li&gt;Supports backend + frontend in one tool
&lt;/li&gt;
&lt;li&gt;Flexible alerting and workflows
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;ANR detection is indirect (via performance spans, not native ANR signals)
&lt;/li&gt;
&lt;li&gt;Can become expensive at scale
&lt;/li&gt;
&lt;li&gt;Requires tuning to avoid noisy alerts
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3. Appxiom
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://www.appxiom.com" rel="noopener noreferrer"&gt;https://www.appxiom.com&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;Appxiom is a &lt;strong&gt;next-generation mobile observability platform&lt;/strong&gt; built specifically for modern apps, including Flutter.&lt;/p&gt;

&lt;p&gt;Unlike traditional tools, Appxiom doesn’t just detect ANRs—it &lt;strong&gt;connects them to real user journeys and business impact&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Most importantly:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Appxiom detects ANRs across both Dart and native layers&lt;/strong&gt;, giving full visibility into Flutter apps.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Real-time ANR detection (Dart + native Android)
&lt;/li&gt;
&lt;li&gt;User journey-based issue mapping
&lt;/li&gt;
&lt;li&gt;Business impact analysis (conversion, drop-offs)
&lt;/li&gt;
&lt;li&gt;Detection of 30+ issue types including freezes, memory, and API delays
&lt;/li&gt;
&lt;li&gt;Alerts with Jira/Slack integration
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why It Stands Out
&lt;/h3&gt;

&lt;p&gt;Traditional tools answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Did an ANR happen?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Appxiom answers:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Which user flow broke, how many users were affected, and what revenue impact it caused?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This shift is critical for modern product teams.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Detects ANRs in both Dart and native code (unique advantage)
&lt;/li&gt;
&lt;li&gt;Prioritizes issues based on real user impact
&lt;/li&gt;
&lt;li&gt;Provides full journey context, not just logs
&lt;/li&gt;
&lt;li&gt;Designed specifically for mobile apps (including Flutter)
&lt;/li&gt;
&lt;li&gt;Helps reduce MTTR significantly
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Newer compared to legacy tools
&lt;/li&gt;
&lt;li&gt;Requires mindset shift (from logs → impact-driven debugging)
&lt;/li&gt;
&lt;li&gt;Not a generic backend observability tool
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  4. Instabug
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://www.instabug.com" rel="noopener noreferrer"&gt;https://www.instabug.com&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;Instabug combines &lt;strong&gt;crash reporting, ANR detection, and user feedback tools&lt;/strong&gt; into a single platform.&lt;/p&gt;

&lt;p&gt;It is particularly strong in detecting &lt;strong&gt;app hangs and UI freezes&lt;/strong&gt;, which are often precursors to ANRs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;ANR detection on Android
&lt;/li&gt;
&lt;li&gt;App hang detection (iOS &amp;amp; Flutter)
&lt;/li&gt;
&lt;li&gt;In-app bug reporting
&lt;/li&gt;
&lt;li&gt;Session replay and user feedback
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Strong focus on user experience issues
&lt;/li&gt;
&lt;li&gt;Captures freezes even without crashes
&lt;/li&gt;
&lt;li&gt;Combines performance + feedback in one platform
&lt;/li&gt;
&lt;li&gt;Great for QA and product teams
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Premium pricing for advanced features
&lt;/li&gt;
&lt;li&gt;Limited direct correlation to business metrics
&lt;/li&gt;
&lt;li&gt;Session replay not always available in lower tiers
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  5. Embrace
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://embrace.io" rel="noopener noreferrer"&gt;https://embrace.io&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;Embrace is a &lt;strong&gt;mobile-first observability platform&lt;/strong&gt; designed to provide full visibility into app performance, including ANRs.&lt;/p&gt;

&lt;p&gt;It focuses heavily on &lt;strong&gt;session-based monitoring&lt;/strong&gt;, capturing everything that happens during a user session.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Full session timelines (including ANRs and performance issues)
&lt;/li&gt;
&lt;li&gt;Network and device state tracking
&lt;/li&gt;
&lt;li&gt;OpenTelemetry support
&lt;/li&gt;
&lt;li&gt;Real-time alerts
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Captures 100% of user sessions
&lt;/li&gt;
&lt;li&gt;Strong ANR and performance visibility
&lt;/li&gt;
&lt;li&gt;Excellent for large-scale mobile apps
&lt;/li&gt;
&lt;li&gt;Provides full context (network, device, user actions)
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Paid tool (can be expensive)
&lt;/li&gt;
&lt;li&gt;Requires setup and configuration effort
&lt;/li&gt;
&lt;li&gt;Might be overkill for small teams
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;ANR detection in Flutter apps is no longer just about catching freezes—it’s about &lt;strong&gt;understanding impact, context, and root cause across multiple layers&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quick Comparison
&lt;/h3&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;ANR Detection Depth&lt;/th&gt;
&lt;th&gt;Flutter Support&lt;/th&gt;
&lt;th&gt;Unique Strength&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Firebase Crashlytics&lt;/td&gt;
&lt;td&gt;Basic&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Free + easy setup&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sentry&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Deep debugging context&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Appxiom&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Advanced&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Dart + ANR + business impact&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Instabug&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;UX + feedback + freeze detection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Embrace&lt;/td&gt;
&lt;td&gt;Advanced&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Full session observability&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;If you're building Flutter apps in 2026:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start with &lt;strong&gt;Crashlytics&lt;/strong&gt; for basic monitoring
&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;Sentry or Embrace&lt;/strong&gt; for deeper debugging
&lt;/li&gt;
&lt;li&gt;Choose &lt;strong&gt;Appxiom&lt;/strong&gt; if you want &lt;strong&gt;complete ANR visibility across Dart + native + business impact&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The future of debugging isn’t just “what broke” - it’s &lt;strong&gt;“what mattered, for whom, and why.”&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>anr</category>
      <category>android</category>
      <category>flutter</category>
      <category>dart</category>
    </item>
    <item>
      <title>Top 5 Bug &amp; Performance Issue Detection Tools for Flutter Apps in 2026</title>
      <dc:creator>Robin Alex Panicker</dc:creator>
      <pubDate>Wed, 18 Mar 2026 11:40:16 +0000</pubDate>
      <link>https://dev.to/robin_a_p/top-5-bug-performance-issue-detection-tools-for-flutter-apps-in-2026-jof</link>
      <guid>https://dev.to/robin_a_p/top-5-bug-performance-issue-detection-tools-for-flutter-apps-in-2026-jof</guid>
      <description>&lt;p&gt;Flutter has evolved into a powerful framework for building high-performance cross-platform apps. But as apps scale, &lt;strong&gt;detecting bugs and performance issues in real-world usage&lt;/strong&gt; becomes critical.&lt;/p&gt;

&lt;p&gt;In 2026, the focus is no longer just on crash reporting. Teams now need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Real user monitoring
&lt;/li&gt;
&lt;li&gt;Performance insights
&lt;/li&gt;
&lt;li&gt;Business impact visibility
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this article, we explore the &lt;strong&gt;top 5 tools Flutter teams should use in 2026&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Firebase Crashlytics + Performance Monitoring
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://firebase.google.com" rel="noopener noreferrer"&gt;https://firebase.google.com&lt;/a&gt;  &lt;/p&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;Firebase provides an easy-to-integrate solution for &lt;strong&gt;crash reporting and performance monitoring&lt;/strong&gt; in Flutter apps.&lt;/p&gt;

&lt;p&gt;It automatically tracks app performance metrics and gives insights into crashes across devices.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Capabilities
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Real-time crash reporting
&lt;/li&gt;
&lt;li&gt;App startup time tracking
&lt;/li&gt;
&lt;li&gt;Network performance monitoring
&lt;/li&gt;
&lt;li&gt;Custom performance traces
&lt;/li&gt;
&lt;li&gt;Integration with Firebase ecosystem
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Very easy to integrate
&lt;/li&gt;
&lt;li&gt;Generous free tier
&lt;/li&gt;
&lt;li&gt;Strong ecosystem (Analytics, Remote Config, etc.)
&lt;/li&gt;
&lt;li&gt;Ideal for startups
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Limited deep debugging capabilities
&lt;/li&gt;
&lt;li&gt;No business impact prioritization
&lt;/li&gt;
&lt;li&gt;Can become noisy at scale
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Best For
&lt;/h3&gt;

&lt;p&gt;Small teams and startups looking for &lt;strong&gt;quick setup and basic monitoring&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Sentry
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://sentry.io" rel="noopener noreferrer"&gt;https://sentry.io&lt;/a&gt;  &lt;/p&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;Sentry is a widely used platform for &lt;strong&gt;error tracking and performance monitoring&lt;/strong&gt; across mobile and backend systems.&lt;/p&gt;

&lt;p&gt;It provides deep debugging insights with detailed stack traces and environment context.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Capabilities
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Detailed error tracking
&lt;/li&gt;
&lt;li&gt;Performance tracing
&lt;/li&gt;
&lt;li&gt;Release tracking
&lt;/li&gt;
&lt;li&gt;Cross-platform support
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Very detailed debugging information
&lt;/li&gt;
&lt;li&gt;Supports mobile + backend
&lt;/li&gt;
&lt;li&gt;Strong developer workflows
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Can get expensive
&lt;/li&gt;
&lt;li&gt;Requires tuning to reduce noise
&lt;/li&gt;
&lt;li&gt;Slight learning curve
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Best For
&lt;/h3&gt;

&lt;p&gt;Teams that need &lt;strong&gt;deep debugging and detailed error insights&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Appxiom
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://www.appxiom.com" rel="noopener noreferrer"&gt;https://www.appxiom.com&lt;/a&gt;  &lt;/p&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;Appxiom is a modern observability platform that &lt;strong&gt;detects bugs and performance issues and maps them to user journeys&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example, a delay in the sign-up flow is treated as more critical than a crash in a rarely used screen because it directly impacts user acquisition and CAC.&lt;/p&gt;

&lt;p&gt;Unlike traditional tools, Appxiom helps teams understand &lt;strong&gt;which issues actually impact business outcomes&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Capabilities
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Detects crashes, ANRs, memory issues, HTTP failures, and UI freezes
&lt;/li&gt;
&lt;li&gt;Maps issues to &lt;strong&gt;user journeys (signup, checkout, etc.)&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Prioritizes bugs based on &lt;strong&gt;real user impact&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Detects &lt;strong&gt;feature failures and custom issues&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Supports Flutter, Android, and iOS
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Business-impact-driven debugging
&lt;/li&gt;
&lt;li&gt;Detects both technical and functional issues
&lt;/li&gt;
&lt;li&gt;Strong focus on real user experience
&lt;/li&gt;
&lt;li&gt;Helps prioritize critical issues faster
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Newer tool compared to others
&lt;/li&gt;
&lt;li&gt;Smaller ecosystem
&lt;/li&gt;
&lt;li&gt;Requires mindset shift from traditional debugging
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Best For
&lt;/h3&gt;

&lt;p&gt;Teams that want to focus on &lt;strong&gt;user experience and business impact instead of just crashes&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Datadog (Mobile APM)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://www.datadoghq.com" rel="noopener noreferrer"&gt;https://www.datadoghq.com&lt;/a&gt;  &lt;/p&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;Datadog is an enterprise-grade observability platform offering &lt;strong&gt;full-stack monitoring&lt;/strong&gt;, including Flutter apps.&lt;/p&gt;

&lt;p&gt;It connects mobile performance with backend systems for a complete picture.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Capabilities
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Real User Monitoring (RUM)
&lt;/li&gt;
&lt;li&gt;Distributed tracing
&lt;/li&gt;
&lt;li&gt;Log monitoring
&lt;/li&gt;
&lt;li&gt;Backend correlation
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Full-stack observability
&lt;/li&gt;
&lt;li&gt;Excellent dashboards and alerts
&lt;/li&gt;
&lt;li&gt;Scales well for large systems
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Expensive
&lt;/li&gt;
&lt;li&gt;Complex setup
&lt;/li&gt;
&lt;li&gt;Overkill for small apps
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Best For
&lt;/h3&gt;

&lt;p&gt;Large teams building &lt;strong&gt;distributed systems with Flutter frontends&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  5. AppDynamics (Cisco)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://www.appdynamics.com" rel="noopener noreferrer"&gt;https://www.appdynamics.com&lt;/a&gt;  &lt;/p&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;AppDynamics provides enterprise-level &lt;strong&gt;application performance monitoring (APM)&lt;/strong&gt; with strong focus on business transactions.&lt;/p&gt;

&lt;p&gt;It helps track how user actions flow through backend systems.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Capabilities
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Real User Monitoring
&lt;/li&gt;
&lt;li&gt;Business transaction tracking
&lt;/li&gt;
&lt;li&gt;Backend performance correlation
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Strong enterprise capabilities
&lt;/li&gt;
&lt;li&gt;Deep transaction visibility
&lt;/li&gt;
&lt;li&gt;Good backend integration
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Complex setup
&lt;/li&gt;
&lt;li&gt;High cost
&lt;/li&gt;
&lt;li&gt;Limited Flutter-focused community
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Best For
&lt;/h3&gt;

&lt;p&gt;Enterprises needing &lt;strong&gt;end-to-end visibility across systems&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Comparison
&lt;/h2&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;Strength&lt;/th&gt;
&lt;th&gt;Best Use Case&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Firebase&lt;/td&gt;
&lt;td&gt;Easy + free + ecosystem&lt;/td&gt;
&lt;td&gt;Startups&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sentry&lt;/td&gt;
&lt;td&gt;Deep debugging&lt;/td&gt;
&lt;td&gt;Dev-focused teams&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Appxiom&lt;/td&gt;
&lt;td&gt;Business-impact debugging&lt;/td&gt;
&lt;td&gt;Product-focused teams&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Datadog&lt;/td&gt;
&lt;td&gt;Full-stack observability&lt;/td&gt;
&lt;td&gt;Large-scale systems&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AppDynamics&lt;/td&gt;
&lt;td&gt;Enterprise APM&lt;/td&gt;
&lt;td&gt;Enterprise apps&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Key Takeaways for 2026
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Crash reporting alone is not enough
&lt;/li&gt;
&lt;li&gt;Real-user monitoring is essential
&lt;/li&gt;
&lt;li&gt;Business impact is the new priority
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Modern tools like Appxiom are shifting the focus from:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“What broke?” → “What impacted users and revenue?”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Choosing the right tool depends on your stage:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Startups:&lt;/strong&gt; Firebase
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Growing teams:&lt;/strong&gt; Sentry
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Product-focused teams:&lt;/strong&gt; Appxiom
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enterprises:&lt;/strong&gt; Datadog or AppDynamics
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The best teams in 2026 don’t just fix bugs — they fix what matters most to users.&lt;/p&gt;




</description>
      <category>flutter</category>
      <category>performance</category>
      <category>ios</category>
      <category>android</category>
    </item>
    <item>
      <title>Replacing Nested Maps with Tuple Keys in Java and Kotlin</title>
      <dc:creator>Robin Alex Panicker</dc:creator>
      <pubDate>Fri, 27 Feb 2026 05:07:07 +0000</pubDate>
      <link>https://dev.to/robin_a_p/replacing-nested-maps-with-tuple-keys-in-java-and-kotlin-5hb9</link>
      <guid>https://dev.to/robin_a_p/replacing-nested-maps-with-tuple-keys-in-java-and-kotlin-5hb9</guid>
      <description>&lt;p&gt;We at &lt;a href="https://www.appxiom.com" rel="noopener noreferrer"&gt;Appxiom&lt;/a&gt; built a simple but useful library for Java and Kotlin.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AxTuple (ax-tuple-java)&lt;/strong&gt; is a MIT Licensed lightweight library available as Maven library and Gradle plugin.&lt;/p&gt;

&lt;p&gt;Let's try AxTuple in a real-world scenario where we have a deeply nested &lt;code&gt;HashMap&lt;/code&gt; structure. The goal is simple: reduce complexity without introducing unnecessary DTOs.&lt;/p&gt;

&lt;p&gt;AxTuple is extremely practical for flattening multi-layer maps into clean, readable composite keys - while remaining immutable and safe to use in hash-based collections.&lt;/p&gt;

&lt;p&gt;In this post, I’ll walk through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The problem with nested maps
&lt;/li&gt;
&lt;li&gt;The clean alternative using &lt;code&gt;Tuple&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;When to use &lt;code&gt;NamedTuple&lt;/code&gt; instead
&lt;/li&gt;
&lt;li&gt;Java and Kotlin examples
&lt;/li&gt;
&lt;li&gt;Practical observations after testing
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Problem: Nested HashMap
&lt;/h2&gt;

&lt;p&gt;Let’s say we are tracking feature usage in an application.&lt;/p&gt;

&lt;p&gt;We want to count how many times a feature is used based on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Environment (&lt;code&gt;prod&lt;/code&gt;, &lt;code&gt;staging&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Region (&lt;code&gt;us-east&lt;/code&gt;, &lt;code&gt;eu-west&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Feature name (&lt;code&gt;dark_mode&lt;/code&gt;, &lt;code&gt;search_v2&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The naive structure looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;usage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Updating the Count (Java)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;usage&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;computeIfAbsent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"prod"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;())&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;computeIfAbsent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"us-east"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;())&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;merge&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"dark_mode"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;Integer:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works — but:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hard to read&lt;/li&gt;
&lt;li&gt;Hard to debug&lt;/li&gt;
&lt;li&gt;Null-safety complexity&lt;/li&gt;
&lt;li&gt;Deep nesting&lt;/li&gt;
&lt;li&gt;Ugly generics&lt;/li&gt;
&lt;li&gt;Painful refactoring&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After testing this approach in a medium-sized codebase, it quickly became clear that the structure itself was the problem.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Clean Solution: Flatten with Tuple Keys
&lt;/h2&gt;

&lt;p&gt;Instead of nesting maps, we flatten everything.&lt;/p&gt;

&lt;p&gt;One key. One map.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tuple&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;usage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the key contains all three dimensions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Tuple&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Tuple&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"prod"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"us-east"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"dark_mode"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Java Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.appxiom.ax.tuple.Tuple&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.HashMap&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Map&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tuple&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;usage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;

&lt;span class="nc"&gt;Tuple&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Tuple&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"prod"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"us-east"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"dark_mode"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Increment count&lt;/span&gt;
&lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;merge&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;Integer:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Increment again&lt;/span&gt;
&lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;merge&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;Integer:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Tuple&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"prod"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"us-east"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"dark_mode"&lt;/span&gt;&lt;span class="o"&gt;)));&lt;/span&gt;
&lt;span class="c1"&gt;// Output: 2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Why This Works
&lt;/h4&gt;

&lt;p&gt;AxTuple implements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Proper &lt;code&gt;equals()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Proper &lt;code&gt;hashCode()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Immutability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So even if you create a new &lt;code&gt;Tuple&lt;/code&gt; instance with the same values, it still resolves correctly in the &lt;code&gt;HashMap&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I verified this by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating keys in one method&lt;/li&gt;
&lt;li&gt;Looking them up in another&lt;/li&gt;
&lt;li&gt;Reconstructing keys dynamically&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No collisions. No surprises.&lt;/p&gt;




&lt;h3&gt;
  
  
  Kotlin Version
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.appxiom.ax.tuple.Tuple&lt;/span&gt;

&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;usage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mutableMapOf&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tuple&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;

&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;key&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Tuple&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"prod"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"us-east"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"dark_mode"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;plus&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;plus&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;Tuple&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"prod"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"us-east"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"dark_mode"&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt;
&lt;span class="c1"&gt;// Output: 2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Much cleaner than nested maps.&lt;/p&gt;




&lt;h2&gt;
  
  
  Before vs After
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Nested Map Structure
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Flat Structure
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tuple&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second one is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Easier to understand&lt;/li&gt;
&lt;li&gt;Easier to pass around&lt;/li&gt;
&lt;li&gt;Easier to serialize&lt;/li&gt;
&lt;li&gt;Easier to test&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And most importantly: &lt;strong&gt;less cognitive load&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  NamedTuple Is Even Better
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Tuple&lt;/code&gt; works great when order is clear.&lt;/p&gt;

&lt;p&gt;But sometimes readability matters more than position.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Tuple&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"prod"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"us-east"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"dark_mode"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may prefer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;NamedTuple&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"env"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"prod"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"region"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"us-east"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"feature"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"dark_mode"&lt;/span&gt;
&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Java Example with NamedTuple
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.appxiom.ax.tuple.NamedTuple&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.HashMap&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Map&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NamedTuple&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;usage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;

&lt;span class="nc"&gt;NamedTuple&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;NamedTuple&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"env"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"prod"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"region"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"us-east"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"feature"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"dark_mode"&lt;/span&gt;
&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;merge&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;Integer:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;NamedTuple&lt;/span&gt; &lt;span class="n"&gt;lookup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;NamedTuple&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"env"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"prod"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"region"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"us-east"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"feature"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"dark_mode"&lt;/span&gt;
&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lookup&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="c1"&gt;// Output: 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why I Liked NamedTuple
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Debug logs are clearer&lt;/li&gt;
&lt;li&gt;Keys are self-documenting&lt;/li&gt;
&lt;li&gt;Refactoring is safer&lt;/li&gt;
&lt;li&gt;Order mistakes are impossible&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The only tradeoff is slightly more verbosity.&lt;/p&gt;




&lt;h2&gt;
  
  
  Observations
&lt;/h2&gt;

&lt;p&gt;After testing with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;~100K inserts&lt;/li&gt;
&lt;li&gt;Repeated lookups&lt;/li&gt;
&lt;li&gt;Reconstructed key objects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Flat HashMaps with Tuple keys performed much faster when looping through.&lt;/p&gt;

&lt;p&gt;What improved dramatically was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code readability&lt;/li&gt;
&lt;li&gt;Maintainability&lt;/li&gt;
&lt;li&gt;Refactoring safety&lt;/li&gt;
&lt;li&gt;Test simplicity&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  When Should You Use AxTuple?
&lt;/h2&gt;

&lt;p&gt;Use it when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You have multi-dimensional map keys&lt;/li&gt;
&lt;li&gt;You are building analytics counters&lt;/li&gt;
&lt;li&gt;You want to avoid nested map hell&lt;/li&gt;
&lt;li&gt;You don’t want to create a one-off composite key class&lt;/li&gt;
&lt;li&gt;You want immutable composite keys&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Avoid it when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need domain-rich behavior (then create a proper class)&lt;/li&gt;
&lt;li&gt;Your key semantics are complex and deserve explicit modeling&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Thoughts
&lt;/h2&gt;

&lt;p&gt;After testing AxTuple in a real nested-map scenario, I can confidently say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Flattening multi-layer HashMaps with Tuple keys significantly simplifies design.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;A&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;B&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;C&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;V&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tuple&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;V&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cleaner.&lt;br&gt;
More maintainable.&lt;br&gt;
Less boilerplate.&lt;/p&gt;

&lt;p&gt;And because AxTuple is immutable and hash-safe, it behaves exactly how a composite key should.&lt;/p&gt;

&lt;p&gt;If you are dealing with multi-dimensional counters, caches, or analytics maps - this pattern is worth adopting.&lt;/p&gt;

&lt;p&gt;Sometimes the best refactor isn’t adding a new abstraction.&lt;/p&gt;

&lt;p&gt;It’s removing unnecessary structure.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For more on AxTuple - visit &lt;a href="https://github.com/basilgregory/ax-tuple-java" rel="noopener noreferrer"&gt;https://github.com/basilgregory/ax-tuple-java&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>java</category>
      <category>kotlin</category>
      <category>programming</category>
      <category>coding</category>
    </item>
    <item>
      <title>Debug Like a Pro with 'git bisect'</title>
      <dc:creator>Robin Alex Panicker</dc:creator>
      <pubDate>Sun, 09 Mar 2025 09:56:22 +0000</pubDate>
      <link>https://dev.to/robin_a_p/debug-like-a-pro-with-git-bisect-14h4</link>
      <guid>https://dev.to/robin_a_p/debug-like-a-pro-with-git-bisect-14h4</guid>
      <description>&lt;p&gt;Most programmers spent hours checking git commits to identify which commit introduced the bug. It’s frustrating. But instead of manually checking commit after commit, Git has a built-in tool that saves your time using Binary Search — git bisect!&lt;/p&gt;

&lt;p&gt;Let me walk you through it. It’s easier than you think.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Start Bisecting
&lt;/h2&gt;

&lt;p&gt;First, tell Git you want to start looking for the bad commit:&lt;br&gt;
&lt;code&gt;git bisect start&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That’s it! Now Git knows you’re about to go on a debugging hunt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Mark a "Good" and "Bad" Commit
&lt;/h2&gt;

&lt;p&gt;Now, we need to give Git some context. Find a past commit where everything worked fine and mark it as good:&lt;br&gt;
&lt;code&gt;git bisect good &amp;lt;commit-hash&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then, mark the commit where the bug appeared as bad:&lt;br&gt;
&lt;code&gt;git bisect bad &amp;lt;commit-hash&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Don’t know the exact good commit? No worries—just pick an older one where you think things were stable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Let Git Do the Heavy Lifting
&lt;/h2&gt;

&lt;p&gt;Now comes the magic! Git will check out a commit in the middle of the range. You test it and tell Git whether the bug is there or not.&lt;/p&gt;

&lt;p&gt;If the bug isn’t there, run:&lt;br&gt;
&lt;code&gt;git bisect good&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If the bug exists, run:&lt;br&gt;
&lt;code&gt;git bisect bad&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Git keeps narrowing it down until it finds the exact commit that introduced the issue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: End Bisect &amp;amp; Fix the Bug
&lt;/h2&gt;

&lt;p&gt;Once Git pinpoints the problematic commit, reset everything back to normal:&lt;br&gt;
&lt;code&gt;git bisect reset&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then, take a look at the commit, figure out what went wrong, and fix the bug at its source!&lt;/p&gt;

&lt;p&gt;BTW if you have a test script that can detect the bug automatically, you don’t even have to manually test each commit! Just run:&lt;br&gt;
&lt;code&gt;git bisect run ./test-script.sh&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Git will keep running the script until it finds the bad commit — completely hands-free debugging!&lt;/p&gt;

&lt;p&gt;If you haven’t tried git bisect yet, give it a shot! It might just become your new favorite debugging tool.&lt;/p&gt;

&lt;p&gt;Don't forget to share this. Might help someone in your network.&lt;/p&gt;

</description>
      <category>git</category>
      <category>testing</category>
      <category>programming</category>
    </item>
    <item>
      <title>We migrated our backend tech stack to Rust, Java &amp; Angular. Here is why.</title>
      <dc:creator>Robin Alex Panicker</dc:creator>
      <pubDate>Thu, 17 Oct 2024 03:48:04 +0000</pubDate>
      <link>https://dev.to/robin_a_p/we-migrated-our-backend-tech-stack-to-rust-java-angular-here-is-why-3hem</link>
      <guid>https://dev.to/robin_a_p/we-migrated-our-backend-tech-stack-to-rust-java-angular-here-is-why-3hem</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy56igbobix7hymsk8l3y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy56igbobix7hymsk8l3y.png" alt=" " width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are through with the server tech stack migration at Finotes.&lt;/p&gt;

&lt;p&gt;For those who don't know what Finotes is (Oh! we have much to do in marketing front), it is a lightweight SDK that when integrated to any #iOS or #Android app, captures bugs and performance issues like memory leak, network call issues, frame rate issues, ANR / App Hang, crashes, screen loading delays and more.&lt;/p&gt;

&lt;p&gt;Our backend attracts heavy load (oh yes, the number of bugs that exist in mobile apps is much higher than many think, and we capture and report all of them) and the operations are memory intensive. Our CPU usage is at manageable levels.&lt;/p&gt;

&lt;p&gt;Our old stack was #Java + #NodeJS + #AngularJS (old one), where Java was used in core modules, NodeJS for dashboard backend and AngularJS for frontend. And now we use #Rust for core heavy load operations, Java (#SpringBoot) for dashboard backend, and #Angular for frontend. We also moved our RDBMS to a distributed table architecture for efficient insertions.&lt;/p&gt;

&lt;p&gt;The reason to choose Rust was to ensure better memory efficiency compared to GC languages. The single owner memory model is a bit of a challenge to code, but the efforts pay off when it comes to memory efficiency. Will write a separate detailed post on how our new Rust based core engine compares with the previous Java based one in memory usage.&lt;/p&gt;

&lt;p&gt;Moving from NodeJS to Java Spring Boot was a no-brainer as we wanted a compiled language to deliver licensed enterprise solutions without exposing the code.&lt;/p&gt;

&lt;p&gt;Picking Angular for frontend was the most internally debated decision. Old AngularJS was outdated, and we wanted to move to a better and more modern framework. React (more of a library than a framework) vs Angular debates stretched many days. Finally the argument of better maintainability won, and we decided to go with Angular. &lt;/p&gt;

&lt;p&gt;If you are a product startup at early stage, and is looking at different tech stack options, or if you are thinking of migrating to a new one, happy to share our learnings and how we reduced the server costs significantly with the new stack. DM me on &lt;a href="https://www.linkedin.com/in/robinap/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Shared here is a screenshot of our dashboard. BTW this is not the final one, as this is couple of sprints old. In the latest, there are some new capabilities that we believe will be of much value to not just the developers, but also to the Software Engineering Leadership team. If you are part of the engineering leadership team in a mobile first company, happy to show a demo of the new capabilities. DM me on &lt;a href="https://www.linkedin.com/in/robinap/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; if you are interested.&lt;/p&gt;

</description>
      <category>java</category>
      <category>rust</category>
      <category>angular</category>
      <category>javascript</category>
    </item>
    <item>
      <title>What's new in Android 12</title>
      <dc:creator>Robin Alex Panicker</dc:creator>
      <pubDate>Sun, 18 Jul 2021 15:08:52 +0000</pubDate>
      <link>https://dev.to/robin_a_p/what-s-new-in-android-12-lnb</link>
      <guid>https://dev.to/robin_a_p/what-s-new-in-android-12-lnb</guid>
      <description>&lt;p&gt;Android 12 Developer preview is out since February. There are couple of interesting features and capabilities added to the release that developers can leverage. Regarding the new Material You UI, it's too early to take a call, but the AppSearch API is worth taking a look. The NoSQL LocalStorage and PlatformStorage will enable apps that can do high data processing.&lt;/p&gt;

&lt;p&gt;Here is a high level analysis by &lt;a class="mentioned-user" href="https://dev.to/donpeter06"&gt;@donpeter06&lt;/a&gt; about the new features in Android 12.&lt;br&gt;
&lt;a href="https://www.blog.finotes.com/post/what-is-new-for-developers-in-android-12" rel="noopener noreferrer"&gt;https://www.blog.finotes.com/post/what-is-new-for-developers-in-android-12&lt;/a&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>java</category>
      <category>kotlin</category>
    </item>
    <item>
      <title>Finotes 4.0.0 for Android, iOS &amp; watchOS released</title>
      <dc:creator>Robin Alex Panicker</dc:creator>
      <pubDate>Fri, 16 Apr 2021 09:45:59 +0000</pubDate>
      <link>https://dev.to/robin_a_p/finotes-4-0-0-for-android-ios-watchos-released-3k0c</link>
      <guid>https://dev.to/robin_a_p/finotes-4-0-0-for-android-ios-watchos-released-3k0c</guid>
      <description>&lt;h2&gt;
  
  
  Announcing the release of Finotes 4.0.0
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmxaqplg5ukv78mha1wwo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmxaqplg5ukv78mha1wwo.png" alt="Alt Text" width="800" height="670"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Finotes SDK 4.0.0 for Android&lt;/strong&gt; comes with improved screen load delay and ANR tracking. &lt;a href="https://www.blog.finotes.com/post/finotes-sdk-version-4-0-0-for-android-released" rel="noopener noreferrer"&gt;https://www.blog.finotes.com/post/finotes-sdk-version-4-0-0-for-android-released&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Finotes Framework 4.0.0 for iOS&lt;/strong&gt; comes with added customization capabilities while tracking screen load delays. &lt;a href="https://www.blog.finotes.com/post/finotes-ios-framework-version-4-0-0-released" rel="noopener noreferrer"&gt;https://www.blog.finotes.com/post/finotes-ios-framework-version-4-0-0-released&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Finotes Framework 4.0.0 for watchOS&lt;/strong&gt; comes with Zero-code HTTP tracking and life cycle event tracking. &lt;a href="https://www.blog.finotes.com/post/finotes-watchos-framework-version-4-0-0-released-it-is-a-step-closer-to-no-code-integration" rel="noopener noreferrer"&gt;https://www.blog.finotes.com/post/finotes-watchos-framework-version-4-0-0-released-it-is-a-step-closer-to-no-code-integration&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Do try it out. Visit &lt;a href="https://finotes.com" rel="noopener noreferrer"&gt;https://finotes.com&lt;/a&gt; for more details.&lt;/p&gt;

</description>
      <category>android</category>
      <category>ios</category>
      <category>watchos</category>
      <category>finotes</category>
    </item>
    <item>
      <title>Detect and Fix ANR in Android</title>
      <dc:creator>Robin Alex Panicker</dc:creator>
      <pubDate>Thu, 08 Apr 2021 04:16:07 +0000</pubDate>
      <link>https://dev.to/robin_a_p/detect-and-fix-anr-in-android-49ph</link>
      <guid>https://dev.to/robin_a_p/detect-and-fix-anr-in-android-49ph</guid>
      <description>&lt;p&gt;The recently released Finotes SDK 3.3.0 for Android has some significant improvements in ANR detection. The SDK now provides near perfect root cause detection of ANR issues in Android apps. The feature is enabled automatically with out any need for developer to write extra lines of code.&lt;/p&gt;

&lt;p&gt;The new version is already getting appreciation from customers. Here is a screenshot of a mail from an Android developer at one of top global mobile apps. It clearly indicates his excitement on how Finotes was able to help him detect the root cause.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frh1tomw726dkgn4y4zh3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frh1tomw726dkgn4y4zh3.png" alt="Mail from an Android developer about how Finotes helped him fix ANR" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Visit &lt;a href="https://www.blog.finotes.com/post/identifying-root-cause-of-anr-in-android-apps" rel="noopener noreferrer"&gt;https://www.blog.finotes.com/post/identifying-root-cause-of-anr-in-android-apps&lt;/a&gt; to know more about the improved ANR detection capability of Finotes.&lt;/p&gt;

</description>
      <category>android</category>
      <category>java</category>
      <category>kotlin</category>
    </item>
    <item>
      <title>Detecting HTTP issues and tracking lifecycle events in iOS apps using Finotes need no code change now</title>
      <dc:creator>Robin Alex Panicker</dc:creator>
      <pubDate>Thu, 18 Mar 2021 06:10:11 +0000</pubDate>
      <link>https://dev.to/robin_a_p/detecting-http-issues-and-tracking-lifecycle-events-in-ios-apps-using-finotes-need-no-code-change-now-502p</link>
      <guid>https://dev.to/robin_a_p/detecting-http-issues-and-tracking-lifecycle-events-in-ios-apps-using-finotes-need-no-code-change-now-502p</guid>
      <description>&lt;p&gt;Yes, that's the change in Finotes Framework 3.3.0. It's near zero effort to detect http call issues and also to track lifecycle events in iOS apps.&lt;/p&gt;

&lt;p&gt;Read more here &lt;a href="https://www.blog.finotes.com/post/finotes-framework-ios-nocode" rel="noopener noreferrer"&gt;https://www.blog.finotes.com/post/finotes-framework-ios-nocode&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ios</category>
      <category>swift</category>
    </item>
    <item>
      <title>Why are we making these expensive mistakes?</title>
      <dc:creator>Robin Alex Panicker</dc:creator>
      <pubDate>Fri, 19 Feb 2021 05:59:41 +0000</pubDate>
      <link>https://dev.to/robin_a_p/why-are-we-making-these-expensive-mistakes-58le</link>
      <guid>https://dev.to/robin_a_p/why-are-we-making-these-expensive-mistakes-58le</guid>
      <description>&lt;p&gt;Source code getting leaked because no one bothered to remove the default credentials in git repo, bank losing millions because of a bad UI, tier 1 companies loosing almost a Trillion dollars due to digital transformation going wrong.&lt;/p&gt;

&lt;p&gt;There is so much for software professionals to introspect about.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.blog.finotes.com/post/how-not-to-be-a-stupid-software-engineer?fbclid=IwAR37YZMbwAyBJnR83MD1WqbfxC2ZBsm-wwfPZj1rYR1DwgqbGNvMhgjDY4A" rel="noopener noreferrer"&gt;https://www.blog.finotes.com/post/how-not-to-be-a-stupid-software-engineer?fbclid=IwAR37YZMbwAyBJnR83MD1WqbfxC2ZBsm-wwfPZj1rYR1DwgqbGNvMhgjDY4A&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>testing</category>
      <category>devops</category>
    </item>
    <item>
      <title>Common bugs in mobile apps</title>
      <dc:creator>Robin Alex Panicker</dc:creator>
      <pubDate>Mon, 01 Feb 2021 03:25:08 +0000</pubDate>
      <link>https://dev.to/robin_a_p/common-bugs-in-mobile-apps-o3e</link>
      <guid>https://dev.to/robin_a_p/common-bugs-in-mobile-apps-o3e</guid>
      <description>&lt;p&gt;Finotes has released the report for Year 2020 on the common types of bugs reported from iOS and Android apps.&lt;/p&gt;

&lt;p&gt;Take a look -  &lt;a href="https://www.blog.finotes.com/post/state-of-bugs-in-mobile-apps-finotes-report-for-year-2020" rel="noopener noreferrer"&gt;https://www.blog.finotes.com/post/state-of-bugs-in-mobile-apps-finotes-report-for-year-2020&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ios</category>
      <category>android</category>
      <category>mobile</category>
    </item>
  </channel>
</rss>
