<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>Patrick Jackson</title><description>Product Engineer — builder across product, software, and systems, with deep roots in mobile and Android.</description><link>https://patrickjackson.dev/</link><item><title>UI = f(state) Is Folklore. I&apos;m Betting on It Anyway.</title><link>https://patrickjackson.dev/blog/ui-equals-f-state/</link><guid isPermaLink="true">https://patrickjackson.dev/blog/ui-equals-f-state/</guid><description>Nobody official ever wrote the formula everyone quotes. But the shape keeps getting rediscovered independently, and the constraints it imposes are the whole product. My stance, the honest bear case, and what I still haven&apos;t proved.</description><pubDate>Thu, 23 Jul 2026 00:00:00 GMT</pubDate><category>redux</category><category>reduxkotlin</category></item><item><title>Kotlin Multiplatform Is a Dial, Not a Switch</title><link>https://patrickjackson.dev/blog/kotlin-multiplatform-is-a-dial/</link><guid isPermaLink="true">https://patrickjackson.dev/blog/kotlin-multiplatform-is-a-dial/</guid><description>Every other cross-platform framework makes you buy the whole runtime. KMP lets you choose how far up the stack you share, feature by feature. Here&apos;s the dial, what each detent costs, and who&apos;s actually paying for it.</description><pubDate>Wed, 22 Jul 2026 00:00:00 GMT</pubDate><category>kotlin-multiplatform</category></item><item><title>ReduxKotlin for Coding Agents</title><link>https://patrickjackson.dev/blog/reduxkotlin-for-coding-agents/</link><guid isPermaLink="true">https://patrickjackson.dev/blog/reduxkotlin-for-coding-agents/</guid><description>An agent that can&apos;t tell whether its change worked will loop, confidently, until your tokens run out. Most of the 1.0 cycle went into fixing that.</description><pubDate>Tue, 21 Jul 2026 00:00:00 GMT</pubDate><category>reduxkotlin</category></item><item><title>Screenshot Tests Where the Input Is State</title><link>https://patrickjackson.dev/blog/screenshot-tests-seeded-by-state/</link><guid isPermaLink="true">https://patrickjackson.dev/blog/screenshot-tests-seeded-by-state/</guid><description>rk snapshot renders real Compose screens from seeded store state and diffs them against goldens. Plus a semantics dump that catches what pixel diffing misses.</description><pubDate>Mon, 20 Jul 2026 00:00:00 GMT</pubDate><category>reduxkotlin</category></item><item><title>Redux DevTools, Outside the Browser</title><link>https://patrickjackson.dev/blog/redux-devtools-outside-the-browser/</link><guid isPermaLink="true">https://patrickjackson.dev/blog/redux-devtools-outside-the-browser/</guid><description>An in-app debug drawer, a desktop monitor with time travel, and a CLI that prints one JSON object per line: three surfaces over one instrumented store.</description><pubDate>Sun, 19 Jul 2026 00:00:00 GMT</pubDate><category>reduxkotlin</category></item><item><title>Surviving Rotation and Process Death</title><link>https://patrickjackson.dev/blog/surviving-rotation-and-process-death/</link><guid isPermaLink="true">https://patrickjackson.dev/blog/surviving-rotation-and-process-death/</guid><description>A singleton store survives rotation for free and dies with the process. StateSaver fixes that in four lines. Then there&apos;s the bug you hit after it works.</description><pubDate>Sat, 18 Jul 2026 00:00:00 GMT</pubDate><category>reduxkotlin</category></item><item><title>ReduxKotlin + Compose: Bind the Narrowest Slice</title><link>https://patrickjackson.dev/blog/reduxkotlin-and-compose/</link><guid isPermaLink="true">https://patrickjackson.dev/blog/reduxkotlin-and-compose/</guid><description>No provider, no CompositionLocal, no hooks. You pass the store as a parameter, and each component binds exactly the slice it renders. Then you prove it with a test.</description><pubDate>Fri, 17 Jul 2026 00:00:00 GMT</pubDate><category>reduxkotlin</category></item><item><title>Granular Subscriptions: Stop Diffing By Hand</title><link>https://patrickjackson.dev/blog/granular-subscriptions/</link><guid isPermaLink="true">https://patrickjackson.dev/blog/granular-subscriptions/</guid><description>store.subscribe fires on every dispatch, so everyone hand-rolls the same re-read-and-compare boilerplate. subscribeTo does the diffing and only calls back on change.</description><pubDate>Thu, 16 Jul 2026 00:00:00 GMT</pubDate><category>reduxkotlin</category></item><item><title>ConcurrentStore: Reads That Don&apos;t Wait</title><link>https://patrickjackson.dev/blog/concurrent-store/</link><guid isPermaLink="true">https://patrickjackson.dev/blog/concurrent-store/</guid><description>The thread-safe store I recommended in 2020 put a lock around every function, including getState. ConcurrentStore keeps writes serialized and makes reads lock-free.</description><pubDate>Wed, 15 Jul 2026 00:00:00 GMT</pubDate><category>reduxkotlin</category></item><item><title>One Store, Nine Targets</title><link>https://patrickjackson.dev/blog/one-store-nine-targets/</link><guid isPermaLink="true">https://patrickjackson.dev/blog/one-store-nine-targets/</guid><description>The exact KMP target matrix for ReduxKotlin 1.0: what every module supports, what got dropped, and the single platform shim the Redux layer actually needs.</description><pubDate>Tue, 14 Jul 2026 00:00:00 GMT</pubDate><category>reduxkotlin</category></item><item><title>ReduxKotlin 1.0</title><link>https://patrickjackson.dev/blog/reduxkotlin-1-0/</link><guid isPermaLink="true">https://patrickjackson.dev/blog/reduxkotlin-1-0/</guid><description>ReduxKotlin 1.0.0-alpha04 is on Maven Central. A concurrent store, granular subscriptions, Compose bindings, DevTools, and a CLI. Here is what changed, and why.</description><pubDate>Mon, 13 Jul 2026 00:00:00 GMT</pubDate><category>reduxkotlin</category></item><item><title>Building Shipyard: Agent Software Development</title><link>https://patrickjackson.dev/blog/building-shipyard-intro/</link><guid isPermaLink="true">https://patrickjackson.dev/blog/building-shipyard-intro/</guid><description>Kickoff for a series on Shipyard: building software with agents as first-class developers, not chat sidekicks.</description><pubDate>Sun, 12 Jul 2026 00:00:00 GMT</pubDate><category>shipyard</category></item><item><title>Publishing Multiplatform Kotlin Libraries</title><link>https://patrickjackson.dev/blog/publishing-multiplatform-kotlin-libraries/</link><guid isPermaLink="true">https://patrickjackson.dev/blog/publishing-multiplatform-kotlin-libraries/</guid><description>Publishing artifacts for multiplatform Kotlin is a bit more complicated than a JVM project. If you are supporting all of Kotlin&apos;s platforms, then need at least </description><pubDate>Mon, 26 Oct 2020 00:00:00 GMT</pubDate><category>kotlin-multiplatform</category></item><item><title>Certificate Pinning for Mobile Devs</title><link>https://patrickjackson.dev/blog/certificate-pinning-for-mobile-devs/</link><guid isPermaLink="true">https://patrickjackson.dev/blog/certificate-pinning-for-mobile-devs/</guid><description>Why? Pinning is needed to protect data going from your app to your backend. Without certificate pinning your users traffic may be intercepted by a Man-in-the-mi</description><pubDate>Fri, 21 Aug 2020 00:00:00 GMT</pubDate><category>Android</category><category>iOS</category><category>mobile</category><category>security</category></item><item><title>Redux on Multithreaded Platforms</title><link>https://patrickjackson.dev/blog/redux-on-multithreaded-platforms/</link><guid isPermaLink="true">https://patrickjackson.dev/blog/redux-on-multithreaded-platforms/</guid><description>Writing code with Redux for web really doesn&apos;t require consideration of threading and concurrent modification of variables. Given Javascript is single threaded </description><pubDate>Sat, 13 Jun 2020 00:00:00 GMT</pubDate><category>redux</category></item><item><title>Kadane&apos;s Algorithm</title><link>https://patrickjackson.dev/blog/kadanes-algorithm/</link><guid isPermaLink="true">https://patrickjackson.dev/blog/kadanes-algorithm/</guid><description>Computer science history is all about building upon the work that came before us – &quot;standing on the shoulders of giants&quot; as it goes. Kadane&apos;s Algorithm is no ex</description><pubDate>Tue, 18 Feb 2020 00:00:00 GMT</pubDate><category>Computer Science</category></item><item><title>&apos;Unsupported Kotlin Plugin version&apos; – Android Studio</title><link>https://patrickjackson.dev/blog/unsupported-kotlin-plugin-version-android-studio/</link><guid isPermaLink="true">https://patrickjackson.dev/blog/unsupported-kotlin-plugin-version-android-studio/</guid><description>If you run into this in Android Studio, you may need a gradle update. I&apos;ve ran into this while using Gradle v5.6.2 and Kotlin v1.3.61. I was also using the kotl</description><pubDate>Wed, 05 Feb 2020 00:00:00 GMT</pubDate><category>Android</category></item><item><title>Multiplatform: Apple AppStore Thoughts</title><link>https://patrickjackson.dev/blog/multiplatform-apple-appstore-thoughts/</link><guid isPermaLink="true">https://patrickjackson.dev/blog/multiplatform-apple-appstore-thoughts/</guid><description>Apple has always valued great user experience. Its App store is guarded by App store reviews with the authority to reject anything that does not meet its standa</description><pubDate>Sat, 25 Jan 2020 00:00:00 GMT</pubDate><category>opinion</category></item><item><title>Coroutine Delay</title><link>https://patrickjackson.dev/blog/coroutine-delay/</link><guid isPermaLink="true">https://patrickjackson.dev/blog/coroutine-delay/</guid><description>A common pattern is to delay execution of some code for a given amount of time. In Android and iOS there are several ways to do, such as the above snippet. How </description><pubDate>Tue, 03 Dec 2019 00:00:00 GMT</pubDate><category>kotlin-multiplatform</category></item><item><title>ReduxKotlin.org</title><link>https://patrickjackson.dev/blog/reduxkotlin-org/</link><guid isPermaLink="true">https://patrickjackson.dev/blog/reduxkotlin-org/</guid><description>Earlier this year I began work on ReduxKotlin.org – a port of the Javascript library Redux. This series of posts will describe the what, why, how, and the visio</description><pubDate>Sat, 30 Nov 2019 00:00:00 GMT</pubDate><category>redux</category><category>reduxkotlin</category></item><item><title>Html in TextViews</title><link>https://patrickjackson.dev/blog/html-in-textviews/</link><guid isPermaLink="true">https://patrickjackson.dev/blog/html-in-textviews/</guid><description>Using HTML in TextViews can be helpful for formatting, especially when displaying content retrieved from a server. For optimal layout and control a custom nativ</description><pubDate>Sat, 09 Nov 2019 00:00:00 GMT</pubDate><category>Android</category></item><item><title>Android Essentials: &lt;merge&gt; tag</title><link>https://patrickjackson.dev/blog/android-essentials-merge-tag/</link><guid isPermaLink="true">https://patrickjackson.dev/blog/android-essentials-merge-tag/</guid><description>When inflating a layout from XML for a custom view or in an &lt;include&gt; tag in a xml layout, the &lt;merge&gt; tag is essential. The merge tag does exactly that – it me</description><pubDate>Sun, 20 Oct 2019 00:00:00 GMT</pubDate><category>Android</category></item><item><title>Optimizing Android Build Time</title><link>https://patrickjackson.dev/blog/optimizing-build-time/</link><guid isPermaLink="true">https://patrickjackson.dev/blog/optimizing-build-time/</guid><description>Android developers get all the benefits of a nice statically compiled language, but that comes at a cost – build time. Compile times can add up quickly and be a</description><pubDate>Sat, 05 Oct 2019 00:00:00 GMT</pubDate><category>Android</category></item><item><title>toLowerCase() lint warnings</title><link>https://patrickjackson.dev/blog/tolowercase-lint-warnings/</link><guid isPermaLink="true">https://patrickjackson.dev/blog/tolowercase-lint-warnings/</guid><description>You may run across a lint warning in Java or Kotlin on when using String.toLowerCase(). &quot;Implicitly using the default locale is a common source of bugs: Use toL</description><pubDate>Thu, 12 Sep 2019 00:00:00 GMT</pubDate><category>Uncategorized</category></item></channel></rss>