<?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: Zakayo Thuku</title>
    <description>The latest articles on DEV Community by Zakayo Thuku (@zakayothuku).</description>
    <link>https://dev.to/zakayothuku</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F147879%2F2f901b5b-2eca-40a3-9ba8-f426ee9c54d6.png</url>
      <title>DEV Community: Zakayo Thuku</title>
      <link>https://dev.to/zakayothuku</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zakayothuku"/>
    <language>en</language>
    <item>
      <title>Web3 Chucker: In-App OkHttp JSON-RPC Inspector &amp; EVM Revert Decoder</title>
      <dc:creator>Zakayo Thuku</dc:creator>
      <pubDate>Mon, 31 Aug 2026 09:46:13 +0000</pubDate>
      <link>https://dev.to/zakayothuku/web3-chucker-in-app-okhttp-json-rpc-inspector-evm-revert-decoder-3pcj</link>
      <guid>https://dev.to/zakayothuku/web3-chucker-in-app-okhttp-json-rpc-inspector-evm-revert-decoder-3pcj</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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F072ax3wjs9mt6nvtx1wv.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F072ax3wjs9mt6nvtx1wv.jpg" alt="App Screenshot" width="768" height="1376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Building decentralized mobile applications (dApps) and crypto wallets on Android involves frequent JSON-RPC communications with Ethereum, Polygon, Arbitrum, or Solana RPC nodes (via Infura, Alchemy, or QuickNode).&lt;/p&gt;

&lt;p&gt;Debugging failed transactions is notoriously difficult when raw JSON-RPC responses only return opaque 4-byte revert signatures (&lt;code&gt;0x08c379a0&lt;/code&gt;) or generic &lt;code&gt;execution reverted&lt;/code&gt; messages without clear parameter decoding.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;web3-chucker&lt;/code&gt;&lt;/strong&gt; extends OkHttp to inspect, parse, and decode Web3 JSON-RPC transactions and smart contract revert errors directly on-device.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏗️ Architecture: JSON-RPC Parsing &amp;amp; Revert Lookup Engine
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Method-Aware RPC Filtering:&lt;/strong&gt; Automatically tags and filters JSON-RPC methods (&lt;code&gt;eth_sendRawTransaction&lt;/code&gt;, &lt;code&gt;eth_call&lt;/code&gt;, &lt;code&gt;eth_estimateGas&lt;/code&gt;, &lt;code&gt;personal_sign&lt;/code&gt;, &lt;code&gt;solana_sendTransaction&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;4-Byte Revert Decoder:&lt;/strong&gt; Translates opaque error selectors (e.g. &lt;code&gt;0x4e487b71&lt;/code&gt; -&amp;gt; &lt;code&gt;Panic(uint256)&lt;/code&gt;) into human-readable contract revert reasons.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Latency &amp;amp; Gas Tracking:&lt;/strong&gt; Measures round-trip RPC execution latency and flags gas estimation spikes.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🛠️ Step-by-Step Implementation Guide
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Add Gradle Dependency
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;dependencies&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Debug builds: full JSON-RPC inspector &amp;amp; overlay UI&lt;/span&gt;
    &lt;span class="nf"&gt;debugImplementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"io.github.zakayothuku:web3-chucker:1.0.0"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// Release builds: zero-overhead no-op artifact&lt;/span&gt;
    &lt;span class="nf"&gt;releaseImplementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"io.github.zakayothuku:web3-chucker-noop:1.0.0"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Configure Web3ChuckerInterceptor with OkHttp
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;okHttpClient&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OkHttpClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Builder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addInterceptor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nc"&gt;Web3ChuckerInterceptor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;applicationContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;maxContentLength&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;250_000L&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;decodeReverts&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;// Provide client to Web3j or custom RPC client&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;web3j&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Web3j&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://mainnet.infura.io/v3/YOUR_KEY"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;okHttpClient&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Attach Floating Overlay
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Composable&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;WalletApp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;modifier&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Modifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fillMaxSize&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;WalletNavHost&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BuildConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DEBUG&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;Web3ChuckerOverlay&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;👉 &lt;strong&gt;GitHub Repository:&lt;/strong&gt; &lt;a href="https://github.com/zakayothuku/web3-chucker" rel="noopener noreferrer"&gt;github.com/zakayothuku/web3-chucker&lt;/a&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>web3</category>
      <category>ethereum</category>
      <category>solana</category>
    </item>
    <item>
      <title>Compose Room Inspector: In-App SQLite &amp; Room DB Browser with Jetpack Compose Overlay</title>
      <dc:creator>Zakayo Thuku</dc:creator>
      <pubDate>Mon, 31 Aug 2026 09:45:36 +0000</pubDate>
      <link>https://dev.to/zakayothuku/compose-room-inspector-in-app-sqlite-room-db-browser-with-jetpack-compose-overlay-3ac9</link>
      <guid>https://dev.to/zakayothuku/compose-room-inspector-in-app-sqlite-room-db-browser-with-jetpack-compose-overlay-3ac9</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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxgsty18rzxs3zwbuqs1s.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxgsty18rzxs3zwbuqs1s.jpg" alt="App Screenshot" width="768" height="1376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Debugging local database state on Android often requires tethering the device to Android Studio to use the App Inspection tab. However, when QA engineers or developers are testing in the field, verifying whether an offline sync job or local caching mutation wrote the correct database records is impossible without desktop access.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;compose-room-inspector&lt;/code&gt;&lt;/strong&gt; is an on-device SQLite &amp;amp; Room database inspector featuring live table browsing, schema introspection, and an interactive raw SQL console with query timing.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏗️ Architecture &amp;amp; Security Model
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Zero Schema Boilerplate:&lt;/strong&gt; Automatically introspects all tables, column types, and primary key (&lt;code&gt;🔑&lt;/code&gt;) constraints at runtime using SQLite pragmas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2D Virtualized Grid:&lt;/strong&gt; Horizontally and vertically scrollable table viewer with sticky column headers and real-time column search.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SQL Console with Execution Profiling:&lt;/strong&gt; Execute ad-hoc queries with an execution time badge (e.g. &lt;code&gt;⚡ 14 ms&lt;/code&gt;) to verify query efficiency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1-Tap Export:&lt;/strong&gt; Copy table records as structured CSV or JSON to the clipboard for bug reports.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🛠️ Step-by-Step Implementation Guide
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Add Gradle Dependency
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;dependencies&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Debug builds: in-app SQLite &amp;amp; Room inspector overlay&lt;/span&gt;
    &lt;span class="nf"&gt;debugImplementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"io.github.zakayothuku:compose-room-inspector:1.0.0"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// Release builds: zero-overhead no-op artifact&lt;/span&gt;
    &lt;span class="nf"&gt;releaseImplementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"io.github.zakayothuku:compose-room-inspector-noop:1.0.0"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Register Your Database Instance
&lt;/h3&gt;

&lt;p&gt;In your Application class or Dependency Injection module:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Provides&lt;/span&gt;
&lt;span class="nd"&gt;@Singleton&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;provideAppDatabase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@ApplicationContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;AppDatabase&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;database&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;databaseBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nc"&gt;AppDatabase&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;java&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"app_commerce.db"&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;// Register database with the inspector in debug builds&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BuildConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DEBUG&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;ComposeRoomInspector&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Commerce DB"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;database&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;openHelper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;writableDatabase&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;database&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Display the Inspector Overlay
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Composable&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;AppRoot&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;modifier&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Modifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fillMaxSize&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;MainNavigation&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BuildConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DEBUG&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;ComposeRoomInspectorOverlay&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;👉 &lt;strong&gt;GitHub Repository:&lt;/strong&gt; &lt;a href="https://github.com/zakayothuku/compose-room-inspector" rel="noopener noreferrer"&gt;github.com/zakayothuku/compose-room-inspector&lt;/a&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>kotlin</category>
      <category>sqlite</category>
      <category>jetpackcompose</category>
    </item>
    <item>
      <title>Compose Chaos Proxy: On-Device Network Latency &amp; HTTP Chaos Simulator for Android</title>
      <dc:creator>Zakayo Thuku</dc:creator>
      <pubDate>Mon, 31 Aug 2026 09:44:50 +0000</pubDate>
      <link>https://dev.to/zakayothuku/compose-chaos-proxy-on-device-network-latency-http-chaos-simulator-for-android-56gc</link>
      <guid>https://dev.to/zakayothuku/compose-chaos-proxy-on-device-network-latency-http-chaos-simulator-for-android-56gc</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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff1fp701noft49ai8bxul.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff1fp701noft49ai8bxul.jpg" alt="App Screenshot" width="768" height="1376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Modern mobile applications must gracefully handle harsh real-world network conditions — from spotty subway tunnels and high-latency 3G networks to expired OAuth tokens (401) and server outages (500/503).&lt;/p&gt;

&lt;p&gt;Traditionally, testing these states required desktop proxy tools like Charles Proxy, Proxyman, or mitmproxy, involving Wi-Fi proxy configurations and installing custom root SSL certificates on test devices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;compose-chaos-proxy&lt;/code&gt;&lt;/strong&gt; eliminates the desktop proxy requirement by providing an on-device network chaos engine with a floating Jetpack Compose control overlay.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏗️ Architecture: OkHttp Interceptor + Dynamic Rule Engine
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Seamless OkHttp Integration:&lt;/strong&gt; Plugs directly into your existing &lt;code&gt;OkHttpClient&lt;/code&gt; pipeline.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Granular URL Regex Filtering:&lt;/strong&gt; Target specific endpoints (e.g., &lt;code&gt;/api/v1/checkout.*&lt;/code&gt; or &lt;code&gt;/auth/refresh&lt;/code&gt;) without affecting analytics or image loading.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configurable Failure Rates:&lt;/strong&gt; Simulate flaky connections by failing a percentage of requests (e.g. 25% failure probability).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom JSON Mock Payloads:&lt;/strong&gt; Return custom error JSON responses matching your backend error schemas.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🛠️ Step-by-Step Implementation Guide
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Add Gradle Dependency
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;dependencies&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Debug builds: on-device network chaos simulator &amp;amp; UI overlay&lt;/span&gt;
    &lt;span class="nf"&gt;debugImplementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"io.github.zakayothuku:compose-chaos-proxy:1.0.0"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// Release builds: zero-overhead no-op artifact&lt;/span&gt;
    &lt;span class="nf"&gt;releaseImplementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"io.github.zakayothuku:compose-chaos-proxy-noop:1.0.0"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Attach Interceptor to OkHttpClient
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;okHttpClient&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OkHttpClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Builder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addInterceptor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ComposeChaosInterceptor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;applicationContext&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connectTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;TimeUnit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SECONDS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;TimeUnit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SECONDS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Add the Floating Chaos Control Overlay
&lt;/h3&gt;

&lt;p&gt;Add &lt;code&gt;ComposeChaosOverlay&lt;/code&gt; to your root Composable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Composable&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;RootApp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;modifier&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Modifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fillMaxSize&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;AppContent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="c1"&gt;// Draggable floating chaos control trigger&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BuildConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DEBUG&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;ComposeChaosOverlay&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧪 Real-World QA &amp;amp; Testing Scenarios
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Testing Token Expiry (401 Unauthorized):&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Inject a 401 error rule on &lt;code&gt;/api/v1/user/profile&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Verify that your &lt;code&gt;Authenticator&lt;/code&gt; or refresh token interceptor automatically triggers a refresh and replays the original request seamlessly.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testing Optimistic UI Rollbacks:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Inject a 500 Internal Server Error rule on &lt;code&gt;"Like Tweet"&lt;/code&gt; or &lt;code&gt;"Add to Cart"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Verify that your UI immediately updates optimistically, catches the 500 failure, reverts the UI state, and shows a friendly snackbar.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testing Slow 3G Connections:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Inject a 3000ms latency rule on product search queries.&lt;/li&gt;
&lt;li&gt;Verify that shimmer loading placeholders display correctly without layout shifts.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;👉 &lt;strong&gt;GitHub Repository:&lt;/strong&gt; &lt;a href="https://github.com/zakayothuku/compose-chaos-proxy" rel="noopener noreferrer"&gt;github.com/zakayothuku/compose-chaos-proxy&lt;/a&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>kotlin</category>
      <category>testing</category>
      <category>jetpackcompose</category>
    </item>
    <item>
      <title>Compose Recomposition Highlighter: On-Device Visual Recomposition Heatmap for Android</title>
      <dc:creator>Zakayo Thuku</dc:creator>
      <pubDate>Mon, 31 Aug 2026 09:44:49 +0000</pubDate>
      <link>https://dev.to/zakayothuku/compose-recomposition-highlighter-on-device-visual-recomposition-heatmap-for-android-3nkk</link>
      <guid>https://dev.to/zakayothuku/compose-recomposition-highlighter-on-device-visual-recomposition-heatmap-for-android-3nkk</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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft9jukj2cw4e11x70d7bv.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft9jukj2cw4e11x70d7bv.jpg" alt="App Screenshot" width="768" height="1376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In Jetpack Compose, the declarative UI paradigm simplifies state synchronization, but unintentional recomposition cascades remain one of the primary causes of UI micro-stutters (jank) and battery drain.&lt;/p&gt;

&lt;p&gt;While the desktop Android Studio Layout Inspector provides recomposition counts, diagnosing performance regressions on physical devices in real-world conditions (without being tethered to a workstation over USB) has historically been challenging.&lt;/p&gt;

&lt;p&gt;To solve this, we built &lt;strong&gt;&lt;code&gt;compose-recomposition-highlighter&lt;/code&gt;&lt;/strong&gt; — an open-source, on-device visual performance auditor for Jetpack Compose.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏗️ Architectural Overview &amp;amp; How It Works
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;compose-recomposition-highlighter&lt;/code&gt; operates through a lightweight modifier and a thread-safe recomposition registry:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Draw-Phase Tracking:&lt;/strong&gt; Uses &lt;code&gt;Modifier.drawWithCache&lt;/code&gt; to read and increment render passes during the draw phase, ensuring the tracking itself does not trigger additional recomposition loops.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic Heatmap Mapping:&lt;/strong&gt; Maps the render frequency to a high-contrast color gradient:

&lt;ul&gt;
&lt;li&gt;🟢 &lt;strong&gt;Green (1–2x):&lt;/strong&gt; Healthy, expected recomposition.&lt;/li&gt;
&lt;li&gt;🟡 &lt;strong&gt;Yellow (3–5x):&lt;/strong&gt; Moderate activity.&lt;/li&gt;
&lt;li&gt;🟠 &lt;strong&gt;Orange (6–9x):&lt;/strong&gt; High recomposition rate.&lt;/li&gt;
&lt;li&gt;🔴 &lt;strong&gt;Red (10x+):&lt;/strong&gt; Severe hotspot / infinite recomposition alert.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hotspot Velocity Metrics:&lt;/strong&gt; Calculates velocity (&lt;code&gt;recomps/sec&lt;/code&gt;) to help you spot runaway loops immediately.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🛠️ Step-by-Step Implementation Guide
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Add Gradle Dependency
&lt;/h3&gt;

&lt;p&gt;Add the library from Maven Central using &lt;code&gt;debugImplementation&lt;/code&gt; so it is automatically stripped from release builds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;dependencies&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Debug builds: full highlighter engine + UI overlay&lt;/span&gt;
    &lt;span class="nf"&gt;debugImplementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"io.github.zakayothuku:compose-recomposition-highlighter:1.0.0"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// Release builds: zero-overhead no-op artifact&lt;/span&gt;
    &lt;span class="nf"&gt;releaseImplementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"io.github.zakayothuku:compose-recomposition-highlighter-noop:1.0.0"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Attach the Modifier to Target Composables
&lt;/h3&gt;

&lt;p&gt;Attach &lt;code&gt;.recompositionHighlighter()&lt;/code&gt; to any composable you want to monitor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Composable&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;UserProfileCard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;UserUiModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;onFollowClick&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Unit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;modifier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Modifier&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Modifier&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Card&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;modifier&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;modifier&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fillMaxWidth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recompositionHighlighter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"UserProfileCard"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;modifier&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Modifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dp&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;style&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MaterialTheme&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;typography&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;titleMedium&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bio&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;style&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MaterialTheme&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;typography&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bodyMedium&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;onClick&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;onFollowClick&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isFollowing&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="s"&gt;"Following"&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="s"&gt;"Follow"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Mount the Floating Performance HUD
&lt;/h3&gt;

&lt;p&gt;In your root application screen or navigation host, wrap your content with &lt;code&gt;ComposeRecompositionOverlay&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Composable&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;MainAppScreen&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;modifier&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Modifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fillMaxSize&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// App Navigation &amp;amp; Screens&lt;/span&gt;
        &lt;span class="nc"&gt;AppNavigationGraph&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="c1"&gt;// Floating Draggable On-Device Recomposition Monitor&lt;/span&gt;
        &lt;span class="nc"&gt;ComposeRecompositionOverlay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;enabled&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BuildConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DEBUG&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;showCountBadges&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;warningThreshold&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;criticalThreshold&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔍 Common Jetpack Compose Traps You Will Catch
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Unstable Lambda Parameters:&lt;/strong&gt; Passing non-memoized lambdas (e.g. &lt;code&gt;{ viewModel.doSomething(item.id) }&lt;/code&gt;) inside &lt;code&gt;LazyColumn&lt;/code&gt; items causing whole-list invalidations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Un-remembered Derived Computations:&lt;/strong&gt; Calculating heavy sorted lists or date formats directly inside the composable body without &lt;code&gt;remember { ... }&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Over-Observing StateFlows:&lt;/strong&gt; Observing a coarse-grained UI state object when a composable only needs a single primitive boolean.&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;👉 &lt;strong&gt;GitHub Repository:&lt;/strong&gt; &lt;a href="https://github.com/zakayothuku/compose-recomposition-highlighter" rel="noopener noreferrer"&gt;github.com/zakayothuku/compose-recomposition-highlighter&lt;/a&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>kotlin</category>
      <category>jetpackcompose</category>
      <category>performance</category>
    </item>
  </channel>
</rss>
