<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Posts on Observe and Report</title><link>https://jeremyckahn.github.io/posts/</link><description>Recent content in Posts on Observe and Report</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><copyright>[Jeremy Kahn](https://github.com/jeremyckahn/)</copyright><lastBuildDate>Tue, 01 Sep 2026 17:03:00 -0500</lastBuildDate><atom:link href="https://jeremyckahn.github.io/posts/index.xml" rel="self" type="application/rss+xml"/><item><title>Where the Agentic Winds Blow: Moving at Machine Speed</title><link>https://jeremyckahn.github.io/posts/moving-at-machine-speed/</link><pubDate>Tue, 01 Sep 2026 17:03:00 -0500</pubDate><guid>https://jeremyckahn.github.io/posts/moving-at-machine-speed/</guid><description>Software engineering is in a weird place right now. On the one hand, we have AI tools that can generate good-enough code faster than anyone can read it. On the other hand, we commit ourselves to reviewing all code that is produced so we can maintain quality. This is obviously unsustainable and it isn&amp;rsquo;t working well.
At least one of these two things is true: We&amp;rsquo;re not building as fast as we can, or we are lying to ourselves and each other about the effectiveness of manual code review.</description><content:encoded><![CDATA[<p>Software engineering is in a weird place right now. On the one hand, we have AI tools that can generate good-enough code faster than anyone can read it. On the other hand, we commit ourselves to reviewing all code that is produced so we can maintain quality. This is obviously unsustainable and it isn&rsquo;t working well.</p>
<p>At least one of these two things is true: We&rsquo;re not building as fast as we can, or we are lying to ourselves and each other about the effectiveness of manual code review.</p>
<p>&ldquo;Careful&rdquo; and &ldquo;fast&rdquo; are opposite ends of a spectrum. Different organizations will need to bias towards one end or the other, but both can&rsquo;t be optimized for at the same time. Choosing either one is valid, but one is all you get. It seems that most tech companies prioritize velocity. Setting aside any feelings and value judgments about that choice, it&rsquo;s how business works and we will accept it as a given for now.</p>
<p>I won&rsquo;t bury the lede: If you want to move as fast as AI lets you, you have to stop reviewing every line of code it generates. That&rsquo;s not to say you can&rsquo;t or shouldn&rsquo;t read <em>any</em> of the code, but you have to be selective with where you spend your time and energy. To focus on everything is to focus on nothing, so you either have to pick your battles or take on the entire army with a wiffle bat and hope for the best.</p>
<p>You could choose to dismiss this idea out of hand and stop reading here. Careful, thorough code review may be nonnegotiable for you, and that&rsquo;s okay. But you then need to accept that you&rsquo;re not going much faster with AI than you would without it, and you are therefore likely wasting money on it. If you hold yourself to the code review practices of old, AI isn&rsquo;t accelerating your dev process terribly much. Instead, it&rsquo;s just shifting your development bottleneck from code generation to code review.</p>
<p>Actually unlocking the efficiency gains of AI requires rethinking the whole SDLC, not just handing your team Claude Code licenses and calling it a day. Code review is still necessary, but why does it need to be humans doing it? LLMs have gotten as good at reviewing code as they are at producing it, so the symmetric solution is to leverage review agents to balance out the code generation agents. Yes this increases your AI spend, but it&rsquo;s necessary to unlock the meaningful benefits of AI-accelerated development.</p>
<p>This isn&rsquo;t to say that human review shouldn&rsquo;t be done; it should. The trick is to focus your review attention where it really counts: Database schema design, system architecture, and test case descriptions. The first two are consequential design aspects that are hard to fix if you get them wrong, and the last one is your clearest insight into what your software actually does. These are things LLMs can effectively review for correctness, but they generally don&rsquo;t have enough context to evaluate them for <em>appropriateness</em>. This is what humans still bring to the table and can do better than AI, so it&rsquo;s where we should focus our time and energy.</p>
<p>Conversely, it&rsquo;s worth minimizing time spent on reviewing things like business logic and presentation. Business logic implementation will only ever be as good as its original specification, and LLMs are reliably good at deriving the former from the latter. Presentation is better verified through means other than code review, such as automated visual diffing and acceptance testing (either it looks and feels right or it doesn&rsquo;t). Leave the actual code review of these parts of your code to the robots. They&rsquo;re about as good at it as we are, and they have vastly higher capacity to do it well.</p>
<p>There&rsquo;s a predictable drawback of reviewing less code: Code quality will go down. Rather than reflexively balking at that idea, let&rsquo;s consider: Is that really a big deal? This is a sincere question, not ragebait. What is the purpose of code quality? The only two practical reasons I can think of are maintainability and performance.</p>
<p>Software engineers can be a discerning bunch. We value precision and elegance, and we abhor complexity. This is frequently out of love for the craft, but it also serves a practical purpose: We don&rsquo;t want to have to reason about code that makes our heads hurt when a bug is reported or we need to add a feature. The shorthand for this is &ldquo;maintainability.&rdquo; Maintainable code prevents migraines, high blood pressure, and missed deadlines. But the conversation around code maintainability historically assumes that it would be <em>humans</em> maintaining the code. What about when that&rsquo;s not the case? When we can hand off unintelligible code to a robot to interpret and change according to our whims with reckless abandon, who really cares how elegant or ugly it is? The AI certainly doesn&rsquo;t have any feelings about it. We&rsquo;re at a point with AI where we can abstract ourselves away from the implementation details of our work and not really lose anything, so it stands to reason that we should.</p>
<p>When compilers were first developed, there was extreme resistance from the programmers who wrote machine code by hand. In their view, compilers produced inefficient assembly code that was inferior to their handcrafted output. And they were objectively right. But they couldn&rsquo;t see the forest for the trees; history proved their valid reservations irrelevant. Computers got faster and the compiler output was demonstrably good enough.</p>
<p>Does this sound familiar?</p>
<p>If we&rsquo;re going to move as fast as AI lets us, we&rsquo;ll need to become comfortable with prioritizing directionality over precision. We need to become okay with &ldquo;good enough&rdquo; and shipping minor defects from time to time, because those are inevitable when you&rsquo;re shipping at a high velocity. This might sound counterintuitive, but it is abated by AI&rsquo;s ability to quickly iterate and ship fixes once the bugs are found. Of course, different organizations&rsquo; tolerance for defects will vary, so it&rsquo;s on you to determine what the right balance is for yours.</p>
<p>Before you reject this idea, ask yourself this: Were you shipping bug-free code before you had AI?</p>
<p>Machines are faster than humans. If you want to move at machine speed, then you need to get out of their way. Direct, don&rsquo;t gatekeep. And don&rsquo;t keep yourself beholden to development processes today simply because you did them yesterday.</p>
]]></content:encoded></item><item><title>The Modern Tech Career: A Survival Guide</title><link>https://jeremyckahn.github.io/posts/modern-tech-career-survival-guide/</link><pubDate>Mon, 17 Aug 2026 07:40:12 -0500</pubDate><guid>https://jeremyckahn.github.io/posts/modern-tech-career-survival-guide/</guid><description>Tech is an excellent field to be in, as the compensation-to-effort ratio far exceeds virtually all others. I am not aware of any other career that offers a six figure income at such a low barrier of entry. Even at the low end, you&amp;rsquo;re nearly guaranteed to make considerably more money than far more difficult and important careers such as public school teaching or waste management. This is great until you start experiencing the capriciousness of tech.</description><content:encoded><![CDATA[<p>Tech is an excellent field to be in, as the compensation-to-effort ratio far exceeds virtually all others. I am not aware of any other career that offers a six figure income at such a low barrier of entry. Even at the low end, you&rsquo;re nearly guaranteed to make considerably more money than far more difficult and important careers such as public school teaching or waste management. This is great until you start experiencing the capriciousness of tech. The good news is that this capriciousness can be identified, understood, and managed.</p>
<p>This is a letter to myself 17 years ago when starting out in tech. It is a post about cold truths and mitigations. It is intended to be illuminating rather than inspiring. My hope is that others find it instructive.</p>
<h2 id="embrace-the-layoff">Embrace the layoff</h2>
<p>You will eventually be laid off. That is how jobs in tech end, assuming you don&rsquo;t leave or get fired first. Practically speaking, there is no concept of staying at one company for decades until you retire. The exception to this rule is company leadership which executes said layoffs as a means of protecting the business. Some non-leadership outliers win the job stability lottery and achieve career-long jobs, but it is unwise to bet on winning the lottery.</p>
<p>Given this inevitability, your best option is to own it, plan for it, and delay it. When I start a new job, I think to myself: &ldquo;I wonder how the layoff for this one will go?&rdquo; I find out concretely in time, but it usually follows a similar pattern: A few bad quarters and company meetings focusing on lagging sales, followed by the CFO leaving, followed by an unexpected, late-breaking &ldquo;Company Update&rdquo; meeting with HR the next day.</p>
<p>You can&rsquo;t choose how to feel about your future layoff, but you can choose how to think about it. You can preemptively strategize around it, both with your personal finances (you do have 6+ months of cash on hand, right?) and your choices as you navigate your job through its untimely end. Those choices are actually more about setting up for the job that follows the current one. Specifically, it&rsquo;s about crafting success stories you can share from this job in a future interview and building personal connections with which to leverage a future referral.</p>
<p>Sidebar: Jobs are only obtained via referrals now. Cold-applies are nearly pointless; employers only hire through their employee network. This is not an absolute truth, but it is a practical one.</p>
<p>The rest of this post is about strategies for delaying your layoff.</p>
<h2 id="the-salary-catch-22">The salary catch-22</h2>
<p>Having a big salary is great. In tech, salaries can range from underwhelming to obscene. It&rsquo;s rational to seek and negotiate for the highest salary you can for any given position — you should do this.</p>
<p>We all wear a layoff target on our backs. The size of that target is roughly proportional to your salary. You might think that, at layoff time, a company would rationally stack rank each employee&rsquo;s individual value and simply cull the least valuable employees as necessary. This is not how it works. Layoffs are not about value, they are about cost. The purpose of a layoff is to reduce costs to make the balance sheet make sense at the end of the quarter. Your salary is a cost. If you want to reduce your layoff risk, consider not maximizing your salary when negotiating an offer. I don&rsquo;t actually recommend doing this (making more money is better than making less), but it&rsquo;s a tiny knob that&rsquo;s available to you if you value stability over wealth.</p>
<p>It&rsquo;s not totally black and white in terms of who goes and stays at layoff time. The salary-based survival cutoff is a little fuzzy; leaders can and do make choices of who to keep and who to cut when it&rsquo;s down to choosing between a handful of people of comparable cost levels. Let&rsquo;s call this &ldquo;the zone of fungibility.&rdquo; You can make choices to put yourself on the better edge of that zone.</p>
<h2 id="know-what-your-job-is">Know what your job is</h2>
<p>Most people don&rsquo;t actually know what their job is. Engineers, for instance, often think their job is to write code, or solve problems, or perhaps even to build great products. This is an illusion. The reality: Your job is to make the company money and please your management chain. That&rsquo;s it. You could ship the most inane, low-brow slop and still be considered a hero if it results in a noticeable improvement to the bottom line. The seminal piece on this is Patrick Mackenzie&rsquo;s</p>
<p><a href="https://www.kalzumeus.com/2011/10/28/dont-call-yourself-a-programmer/"><!-- raw HTML omitted -->Don&rsquo;t Call Yourself A Programmer, And Other Career Advice<!-- raw HTML omitted --></a>. If you haven&rsquo;t already, stop here and read and internalize that essay. Key quote:</p>
<blockquote>
<p>Engineers are hired to create business value, not to program things</p>
</blockquote>
<p>It&rsquo;s in your interest to seek opportunities to create direct business value. Try to work closely to revenue streams. If you&rsquo;re not in a role that puts you in a position to do this (e.g. internal operations), try to transfer to one that is. If you can&rsquo;t do this (or simply don&rsquo;t want to), your next best option is to seek opportunities to reduce costs. Find inefficiencies in the organization, own them, and eliminate them. If your work is visible to leadership (more on that later), it will be considered by decision makers in case you find yourself in the zone of fungibility.</p>
<h2 id="make-friends-in-high-places">Make friends in high places</h2>
<p>Pithy though it is, they saying &ldquo;it&rsquo;s not what you know, it&rsquo;s who you know&rdquo; is a universal truth in the business world. Do not underestimate this fact. You are not smart enough to be exempt from it.</p>
<p>Make friends with your manager, director, VP, CTO, and ideally CEO. They should be aware of your existence and what you do for the company. This is one of your best tools to defer your layoff.</p>
<p>How do you make friends with these people? Proactively reach out to them and provide useful information to them. Literally just ping them on Slack from time to time. If you&rsquo;re an individual contributor, you have valuable perspective as a person with boots on the ground. You can give them insight that&rsquo;s obvious to you but perhaps not to them. Good leaders crave high-quality data, as that&rsquo;s what lets them do their job. When doing this, take care to optimize for signal over noise. Don&rsquo;t use any more words than necessary and don&rsquo;t overwhelm them lest you not be heard at all. And absolutely do not be annoying.</p>
<p>How do you differentiate between signal and noise? Consider what you know that they don&rsquo;t and think they should. That&rsquo;s it. If you don&rsquo;t have this information, don&rsquo;t ping them. If you do, then do. Either way, don&rsquo;t do this more than about once a week.</p>
<p>The goal of this is twofold: Contribute to the success of the company by disseminating valuable information to those who can do something with it, and establish yourself as more than just a name on a list of fungible layoff options. To be clear, you are just a name by default. You can choose and work to be more. I recommend that you do so.</p>
<h2 id="visibility-beats-competence">Visibility beats competence</h2>
<p>Competent people make the world go &lsquo;round. Unfortunately, they&rsquo;re not valued or rewarded by default. Reward comes from visibility regardless of any underlying competence. I imagine you&rsquo;ve already seen a loud person take and get credit for work that a more competent person did. Perhaps you were that competent, unappreciated person. You will see this again throughout your career.</p>
<p>Books could be (and likely have been) written about why this is. My reductive understanding is that this is a quirk (failure?) of human nature. It&rsquo;s not going to change and it&rsquo;s foolish to try and deny it.</p>
<p>Competence is important but ultimately irrelevant without visibility. Advertise your wins, even if it feels gross. Frame your failures as lessons learned. Over time you will be widely perceived as competent, which is all that really matters in the end. You are not granted this perception by default, and that&rsquo;s dangerous when you&rsquo;re in the zone of fungibility.</p>
<h2 id="embrace-cynicism-but-dont-lead-with-it">Embrace cynicism, but don&rsquo;t lead with it</h2>
<p>This post is admittedly a little cynical, but it is the distillation of my lived experience and the lessons I&rsquo;ve learned. I don&rsquo;t like much of what I&rsquo;ve shared here, but I&rsquo;ve found it all to be true just the same. It is also consistent with what I&rsquo;ve seen my peers go through (many of which are quite successful). No two career experiences are the same, but many of them follow a general pattern. Chances are, you&rsquo;re in a similar one.</p>
<p>It&rsquo;s easy to let this cynicism spill over into your everyday demeanor, but this is incredibly dangerous. It is very easy to be cast as &ldquo;the negative one&rdquo; and very hard to shake that perception. You should be your authentic self at work, but it&rsquo;s imperative that you attenuate any cynicism you may develop over time. After all, nobody wants to work with a downer.</p>
<p>Be careful not to overcorrect; being toxically positive isn&rsquo;t any better. It&rsquo;s worth being your authentic self, just keep in mind how others perceive you. Perception is everything and it becomes your story. Make sure it&rsquo;s one that people want to hear.</p>
<h2 id="surviving-is-thriving">Surviving is thriving</h2>
<p>There are a lot of influencers who want to sell you on the dream of &ldquo;thriving&rdquo; (they make money from that message). Take bold risks, launch a startup, be your own boss. Some people are well suited for founding and leading companies, but most are better suited for being employees. There is no shame in this and it&rsquo;s not some sort of moral failure.</p>
<p>Simply finding and keeping a job these days is success. Reaching your local maximum is an achievement worth being proud of, and you may even find that your ceiling is higher than you thought. If so, you should try to continually raise and reach it. But surviving is a prerequisite to thriving, so start there.</p>
<p>Hopefully this post will help you do that!</p>
]]></content:encoded></item><item><title>So it Seems</title><link>https://jeremyckahn.github.io/posts/so-it-seems/</link><pubDate>Mon, 17 Feb 2025 15:55:55 +0000</pubDate><guid>https://jeremyckahn.github.io/posts/so-it-seems/</guid><description>A few jobs ago, I worked with an engineer named Mike. Mike is one of those quietly brilliant engineers who has no online presence and nothing to prove. He didn&amp;rsquo;t go to college for computer science or anything at all related to it (if my recollection is correct, he majored in Philosophy). Mike wrote some of the best code I&amp;rsquo;ve ever seen: Wonderfully boring, straightforward, and devoid of any cleverness. It was like code from an academic textbook.</description><content:encoded><![CDATA[<p>A few jobs ago, I worked with an engineer named Mike. Mike is one of those quietly brilliant engineers who has no online presence and nothing to prove. He didn&rsquo;t go to college for computer science or anything at all related to it (if my recollection is correct, he majored in Philosophy). Mike wrote some of the best code I&rsquo;ve ever seen: Wonderfully boring, straightforward, and devoid of any cleverness. It was like code from an academic textbook. Unexciting though it was, his code was very easy to follow and worked well. Mike&rsquo;s coding style has greatly influenced my own and I strive to write code that is as boring as his.</p>
<p>But it wasn&rsquo;t Mike&rsquo;s excellent code that influenced me the most. It was actually a very simple rhetorical construct that I don&rsquo;t think he even used consciously in engineering debates. Two simple words: &ldquo;It seems.&rdquo; Now, &ldquo;it seems&rdquo; might not strike you as very compelling at first. But it&rsquo;s what it&rsquo;s used <em>as an alternative for</em> that makes it powerful.</p>
<p>Engineers tend to be an opinionated bunch. We have a point of view and part of our job is to sell that perspective and design systems around it. We also tend to be extremely emotional and get attached to our ideas. Right now you might be thinking &ldquo;That&rsquo;s nonsense. I&rsquo;m not emotional! I&rsquo;m logical! I exclusively make logical analyses and decisions!&rdquo; If you&rsquo;re thinking this, you are <em>the most</em> emotional type of engineer. You have a concept of who you are and what you do, and you are very attached to it. But don&rsquo;t feel bad! Humans are emotional beings no matter how much we&rsquo;d like to tell ourselves otherwise. We can&rsquo;t will our emotions away. At best, we can manage them. At worst (as engineers), they manage us.</p>
<p>Typically in engineering debates, participants try to make their case by saying that they &ldquo;feel,&rdquo; &ldquo;think,&rdquo; or &ldquo;believe&rdquo; something. For example:</p>
<ul>
<li>&ldquo;I feel that using a state management system will make this code more maintainable.&rdquo;</li>
<li>&ldquo;I think Postgres is the way to go for this project.&rdquo;</li>
<li>&ldquo;I believe that our test coverage should be at least 90%.&rdquo;</li>
</ul>
<p>These are all valid points of view, but they&rsquo;re presented in an inherently subjective way. Engineering, when done well, is not a subjective discipline. Real engineering is fully objective, and good engineers know how to remain objective when determining a solution to a problem. How you feel or think about something is a subjective reflection, but how something <em>seems</em> is a more objective baseline to work with. Let&rsquo;s apply this to the arguments above:</p>
<ul>
<li>&ldquo;It seems that using a state management system will make this code more maintainable.&rdquo;</li>
<li>&ldquo;It seems Postgres is the way to go for this project.&rdquo;</li>
<li>&ldquo;It seems that our test coverage should be at least 90%.&rdquo;</li>
</ul>
<p>Now, these arguments are actually a bit weaker than they were before because they lack any rationale. But now it&rsquo;s much more obvious that they lack rationale and that&rsquo;s a trigger for the team to acknowledge and discuss it. With &ldquo;feel,&rdquo; &ldquo;think,&rdquo; and &ldquo;believe,&rdquo; the implicit rationale is &ldquo;because I say so.&rdquo; That&rsquo;s a pretty poor way to sell an engineering solution and it doesn&rsquo;t invite collaboration. By using &ldquo;it seems&rdquo; to recast the argument in a less emotional light, it opens the door to different perspectives and potentially better alternatives. And this is what good engineers do: Get to the root of a problem and identify the best-fit solution. A major component of that is willing to not be the loudest or most opinionated person in the room.</p>
<p>&ldquo;It seems&rdquo; has helped me navigate many engineering debates better than if I used my emotions to make a point. It seems that many engineers would benefit from doing it as well!</p>
]]></content:encoded></item><item><title>LLMs and the Total Eclipse of the LSP</title><link>https://jeremyckahn.github.io/posts/llms-and-the-total-eclipse-of-the-lsp/</link><pubDate>Mon, 03 Feb 2025 01:59:41 +0000</pubDate><guid>https://jeremyckahn.github.io/posts/llms-and-the-total-eclipse-of-the-lsp/</guid><description>Or, why I&amp;rsquo;m a grumpy old man who thinks they don&amp;rsquo;t make them like they used to
Welcome to 2025. LLMs have captured the hearts and minds (AKA VC dollars) of everyone and they are literally the only thing happening at all in the entire tech industry. They are the cause of and solution to every problem and will both save and destroy the world.
LLMs are at least a potential solution for a very wide range of problems, but they&amp;rsquo;re often not the best and very rarely the simplest.</description><content:encoded><![CDATA[<p><em>Or, why I&rsquo;m a grumpy old man who thinks they don&rsquo;t make them like they used to</em></p>
<p>Welcome to 2025. LLMs have captured the hearts and minds (AKA VC dollars) of everyone and they are literally the only thing happening at all in the entire tech industry. They are the cause of and solution to every problem and will both save and destroy the world.</p>
<p>LLMs are at least a potential solution for a very wide range of problems, but they&rsquo;re often not the best and very rarely the simplest. The one thing you can say for sure with LLMs is that you can put stuff into them, and <em>something</em> will definitely come out. Will it be the right thing? Who knows, hit the button and see what happens!</p>
<p>Hitting the button and seeing what happens is a fine workflow for a lot of situations. It&rsquo;s great for creative writing, drafting Jira tickets, cheating on homework, and writing emails to people you don&rsquo;t care about. But some work requires a bit more determinism. Programming is an example of such work; either software works correctly or it does not. Because we live in the future, LLMs are quite good and will often provide you with code that at least <em>mostly</em> works. And if you already know how to write the code you&rsquo;re asking the LLM to write, then you&rsquo;ll be able to verify the output and grin smugly about all the time you just saved yourself (or regenerate the response five times and then give up and just write it yourself in frustration). If you don&rsquo;t already know how to write it yourself&hellip; well, hopefully somebody catches the bugs in code review.</p>
<p>What makes LLMs both great and terrible is that they hallucinate. It&rsquo;s not a bug, it&rsquo;s the very essence of what they exist to do. LLMs don&rsquo;t actually know anything and mostly don&rsquo;t have access to any kind of database of verifiable information. They are machines that were shown a lot of information in training and learned to infer new conclusions based on the patterns they picked up in that training. But they don&rsquo;t <em>know</em> anything. They have no truly concrete way to validate nontrivial assumptions or conclusions. They&rsquo;re just making extremely educated guesses. And they&rsquo;re doing it in an extraordinarily resource-intensive way.</p>
<p>I like LLMs (<a href="/posts/local-ai-is-the-only-ai/">at least ones that I can run on my own personal hardware</a>), but I&rsquo;m also a simple man who enjoys simple things. A resource-intensive guessing machine is not the simplest solution for a majority of programming-related tasks. Such tasks include writing, refactoring, finding and moving code. Ironically, this problem has been well-solved by long-established, proven static analysis tools that predate LLMs by decades. Linters, for example, are static code analysis tools that deterministically evaluate code and identify a wide range of problems. They&rsquo;re not as versatile as LLMs, but they are completely consistent and reliable and very often versatile enough.</p>
<p>In the mid-2010&rsquo;s, Microsoft gave the world a wonderful gift: The Language Server Protocol, or LSP for short. At a high level, LSPs are a unified way for code editors such as Neovim to communicate with a wide range of development tools. That doesn&rsquo;t sound particularly exciting, but it&rsquo;s the technology that tells you what properties or methods the object you just typed has available to it. This is <em>a little</em> more exciting, but still not exactly compelling. More advanced LSPs (such as the ones available for TypeScript) offer advanced refactoring capabilities such as extracting functions, moving code to different files, renaming variables (across files!), finding code references and definitions, and more.</p>
<p>There&rsquo;s a good chance you&rsquo;re sitting there rolling your eyes because you know that LLMs can do this too. But hold on there, buddy. Your LLM takes <em>an extraordinary</em> amount of compute to do this work. And if you&rsquo;re not running it on a $20k custom-built NVIDIA rig that heats up your whole house, then you&rsquo;re paying someone like Anthropic to do it in a data center. LSPs, on the other hand, can do this work on any random laptop purchased from Walmart. And the best part? LSPs don&rsquo;t hallucinate! They literally can&rsquo;t! They will always provide you with a valid response, unlike LLMs which may or may not.</p>
<p>LLMs definitely have their place. But they aren&rsquo;t the only solution to most problems, and are very rarely the best. For many programming tasks, LSPs are just as good of a solution and much more efficient. New tools don&rsquo;t have to replace old ones, they can supplement them too! I have no problem using LLMs in my workflow, but I use LSPs far more frequently because they&rsquo;re faster and better for real-world scenarios. And the best part? I don&rsquo;t have to provision a server rack or fund a new yacht for Sam Altman to use them.</p>
<p>Long live LSPs!</p>
]]></content:encoded></item><item><title>Local AI is the Only AI</title><link>https://jeremyckahn.github.io/posts/local-ai-is-the-only-ai/</link><pubDate>Mon, 02 Dec 2024 03:11:25 +0000</pubDate><guid>https://jeremyckahn.github.io/posts/local-ai-is-the-only-ai/</guid><description>If there&amp;rsquo;s one thing that the last several decades have taught us, it&amp;rsquo;s that tech companies do not exist for the benefit of everyday people. Despite what the heartwarming Superbowl ads may have you believe, tech companies exist for the pleasure and benefit of venture capitalist investors. There are indeed companies that are not beholden to the interests of VCs, but they&amp;rsquo;re typically not successful enough for you to have heard of them.</description><content:encoded><![CDATA[<p>If there&rsquo;s one thing that the last several decades have taught us, it&rsquo;s that tech companies do not exist for the benefit of everyday people. Despite what the heartwarming Superbowl ads may have you believe, tech companies exist for the pleasure and benefit of venture capitalist investors. There are indeed companies that are not beholden to the interests of VCs, but they&rsquo;re typically not successful enough for you to have heard of them. Any tech company that&rsquo;s a household name is in the pocket of at least one glassy-eyed investor off of Sand Hill Road. It&rsquo;s a historical constant that success and VC investment inevitably lead to <a href="https://en.wikipedia.org/wiki/Enshittification">enshittification</a>. And it&rsquo;s not a bug, it&rsquo;s a feature of the VC investment model: The line must go up forever, and eventually the product (and users) will suffer in the long run to make that happen. It&rsquo;s an unhappy ending that has yet to be avoided by anybody who has tried.</p>
<p><strong>AI is the future.</strong> You can disagree with this, fight against it, or ignore it. But there is no scenario (short of a literal apocalypse) in which our future involves <em>less</em> AI than it does today. It is simply too useful to not stick around and improve. Even if AI progress stops with LLMs (it won&rsquo;t), people will find more uses for it (both good and bad) and build more products around it. It&rsquo;s not all hype; this technology has practical applications. I&rsquo;m not necessarily endorsing the AI future, but I accept that it is reality. And it&rsquo;s only when you accept reality that you can thrive within it.</p>
<p>As of December 2024, OpenAI is the only mainstream household name in AI. Anthropic is the company that is used by AI power users. In other words, OpenAI is for normies and casuals and Anthropic is for the hardcores. This will probably change pretty soon because there&rsquo;s no stability in this space. It&rsquo;s too early to tell who will be the winners and losers. But to be honest, I don&rsquo;t really care. None of these AI companies are doing anything particularly interesting.</p>
<p>&ldquo;But wait,&rdquo; I hear you say. &ldquo;In one breath you&rsquo;re saying that AI is the future, and in another you&rsquo;re saying that the leading AI companies aren&rsquo;t doing anything interesting. That doesn&rsquo;t make sense!&rdquo;</p>
<p>My friend, you need to expand your notion of what AI is and can be. While these companies are indeed developing the most advanced AI technology on earth, their actual product is API access to their models. And therein lies the problem. As per the (inexplicably) standard Silicon Valley playbook, both <a href="https://www.nytimes.com/2024/09/27/technology/openai-chatgpt-investors-funding.html">OpenAI</a> and <a href="https://www.tanayj.com/p/openai-and-anthropic-revenue-breakdown">Anthropic</a> operate at a loss. I would bet on them eventually becoming profitable, but not before at least setting the stage for full-scale enshittification, if not fully embracing it. And by then it will be too late. The moats will be established and the API dependencies will be established. We&rsquo;ve already seen this with cloud providers like AWS and there is, realistically, no way back. Big tech will win again because it always does.</p>
<p>But there is space for another option! Smaller, open source LLMs are flourishing right now and will only get better with time. Unlike the frontier models like Open AI&rsquo;s GPT4 and Anthropic&rsquo;s Claude that are trained on many hundreds of billions (maybe even trillions) of parameters, there are many smaller, open source LLMs ranging from <a href="https://ollama.com/library/smollm">less than one billion parameters on the low end</a> to <a href="https://ollama.com/library/llama3.1">around 400 billion on the high end</a>. These models are free to download and run on your own hardware as you see fit. And because these models run locally, you don&rsquo;t have to worry about token costs, rate limiting, or privacy concerns. There&rsquo;s no catch and it&rsquo;s as good as it sounds!</p>
<p>To directly address the elephant in the room: Many of these open source models require <em>significant</em> hardware resources to run. You&rsquo;d probably need a RAM and CPU-maxed MacBook Pro or an array of NVIDIA 4090&rsquo;s to run the larger models well. But to focus on this is to miss the forest for the trees: There&rsquo;s a respectable set of small but capable LLMs that run well on commodity-grade hardware and probably even the one you&rsquo;re reading this blog post on. You don&rsquo;t necessarily need high-end GPUs or specced-out Macs to run models such as <a href="https://ollama.com/library/llama3.2">Llama 3.2 3B</a> or <a href="https://ollama.com/library/qwen2.5-coder">Qwen 7B</a> at usable speeds. To offer one data point: My iPhone SE 3, which is the lowest-end iPhone Apple makes, can run Llama 3.2 3B locally via <a href="https://github.com/a-ghorbani/pocketpal-ai">PocketPal</a>. While Llama 3.2 3B objectively has a tiny fraction of the training data available to generate responses that something like GPT 3.5+ has, it has fully replaced ChatGPT for me. It&rsquo;s in no way the best LLM, but it is easily good enough for general purpose LLM tasks. For more specific tasks such as coding, I use more specialized models such as Qwen.</p>
<p>While we can easily deduce that OpenAI and Anthropic will enshittify, it&rsquo;s unclear when it will happen and what that will look like. It could be as simple as jacking up API rates and bleeding customers dry, or it could take on a more insidious form like monetizing user data to make ends meet for the investors <a href="https://www.eff.org/deeplinks/2020/03/google-says-it-doesnt-sell-your-data-heres-how-company-shares-monetizes-and">à la Google</a>. We simply don&rsquo;t know. Personally, I&rsquo;m not sticking around to find out. And I don&rsquo;t need to, because I have amazingly capable &ldquo;small&rdquo; LLMs that I can easily run locally on my laptop and phone. I have zero dependence on the cloud for my AI needs and have no API bills to pay. This is a delightful reality that everyone is free to enjoy right now and in the future. If you&rsquo;re curious to explore this exciting new world, I&rsquo;d recommend installing <a href="https://jan.ai/">Jan</a> and Llama 3.2 3B via its model hub. If you&rsquo;re not using a Mac, you&rsquo;ll want to look into enabling &ldquo;Vulkan Support&rdquo; and &ldquo;GPU Acceleration&rdquo; in the settings for better performance.</p>
<p>I think you&rsquo;ll be surprised at what you can do with small, local LLMs. I for one am continuously amazed at what I&rsquo;m able to do with just <a href="https://frame.work/products/laptop-diy-13-gen-amd/configuration/new">my daily driver laptop</a> and Llama 3.2 3B and Qwen. You just need to have a realistic sense of what they can and can&rsquo;t do well and how to make the most of them. I&rsquo;ve been deep-diving this rabbit hole a lot lately, and it&rsquo;s clear that the difference between the &ldquo;best&rdquo; and &ldquo;good enough&rdquo; LLM models is insignificant for many tasks. And at the end of the day, it seems like an obviously worthwhile tradeoff to own your computing experience and digital future.</p>
<p>Don&rsquo;t be another victim of enshittification and start owning your AI today!</p>
]]></content:encoded></item><item><title>A Future of the Web</title><link>https://jeremyckahn.github.io/posts/a-future-of-the-web/</link><pubDate>Sun, 28 Jul 2024 01:48:26 +0000</pubDate><guid>https://jeremyckahn.github.io/posts/a-future-of-the-web/</guid><description>One of my favorite things about technology is seeing how it evolves over time and how we adapt to the changes it brings. In the 90&amp;rsquo;s, digital documents were largely stored locally on people&amp;rsquo;s computers. This was delightfully simple, but if there was a hardware failure or software bug, the document was gone forever. In the 2000&amp;rsquo;s, we got cloud-based applications like Google Docs. This automated away the burden of data redundancy.</description><content:encoded><![CDATA[<p>One of my favorite things about technology is seeing how it evolves over time and how we adapt to the changes it brings. In the 90&rsquo;s, digital documents were largely stored locally on people&rsquo;s computers. This was delightfully simple, but if there was a hardware failure or software bug, the document was gone forever. In the 2000&rsquo;s, we got cloud-based applications like Google Docs. This automated away the burden of data redundancy. If the device you were working on got lost or broken, you could log into the cloud service on another device and carry on with your work. From a user experience perspective, this seems to be the way that things should be.</p>
<p>As cloud-based apps evolved, they were necessarily designed around the business models of their developers. And business models, at least in the tech industry, are often at odds with the interests of users<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>. In the case of Google, the relationship between the service and user is predicated on surrendering stewardship of the user&rsquo;s digital identity and property to Google. This is problematic, as Google is neither benevolent nor trustworthy. There are numerous reports of people losing access to their Google accounts due to <a href="https://9to5google.com/2022/08/22/google-locked-account-medical-photo-story/">misinterpreted misuse</a> or <a href="https://news.ycombinator.com/item?id=20835350">bad luck</a>. Losing something as depended upon as a Google account would be catastrophic for many people. And Google has little incentive to improve the situation, as they have no real accountability to users when admittedly rare cases like these happen. But do you want to be the one-in-a-million person that inadvertently triggers a spurious policy violation and lose your Google account? I certainly don&rsquo;t. All that&rsquo;s left is to either live in fear of Google, live in ignorance of the risk, or find a different solution entirely.</p>
<p>The core of what Google offers as a cloud solution is fundamentally good at a high level, but it can&rsquo;t be trusted because of the interests and track record of the company that operates it. There are safer alternatives such as <a href="https://proton.me/blog/docs-proton-drive">Proton Drive</a> that prevent the service from accessing user data. However, users still need to identify themselves to the service and manage their account credentials lest they lose access forever. We need something that&rsquo;s as private as Proton, but simpler to manage.</p>
<hr>
<p>People often talk about &ldquo;the future&rdquo; of a given technology or domain. The future of mobile devices, the future of design, etc. But this is such a limiting way to see it! &ldquo;The&rdquo; future implies there is only path to go down, but there are in fact many possible futures that can happily coexist. The world is too complex for one solution to solve every problem well. There&rsquo;s space for more than one way of doing things!</p>
<p>I get really excited by decentralized systems and peer-to-peer networks because they have tremendous potential to empower individuals. I&rsquo;m a lot less excited by traditional centralized systems and client/server networks, but that&rsquo;s because of how they&rsquo;ve manifested in practice. Centralized, client/server systems defer power and authority to the server, and that&rsquo;s problematic when the server is controlled by a self-interested business with incentives that are misaligned with that of its service&rsquo;s users.</p>
<p>Despite the drawbacks, centralized systems have numerous technical advantages:</p>
<ul>
<li>Simplicity</li>
<li>High performance</li>
<li>High availability</li>
</ul>
<p>Decentralized, peer-to-peer systems are great because they keep control and authority with the users. In a decentralized system, individual nodes (users) manage their own data and identity. However, these advantages come with tradeoffs:</p>
<ul>
<li>High complexity</li>
<li>Unreliable availability</li>
<li>Significant collective maintenance burden</li>
</ul>
<p>These are fundamentally limiting issues. Enthusiasts will put up with the challenges of participating in a decentralized system, but typical users will not. If a product is going to achieve widespread adoption and enjoy the network effect benefits that brings, it needs to be approachable to the majority of people.</p>
<p>The ideal between these two extremes is a system that has the benefits of both without the drawbacks of either. Here&rsquo;s what I think that could look like:</p>
<ul>
<li>Dumb servers</li>
<li>Smart clients</li>
<li>Public key identity</li>
</ul>
<p>Let&rsquo;s break down what each of these mean.</p>
<h2 id="dumb-servers">Dumb servers</h2>
<p>The fundamental problem with platforms like Google and Facebook is that the service knows <em>everything</em> about its users. An alternative that actually keeps users safe is a service that knows <em>nothing</em> substantial about them. This can be achieved through <a href="https://en.wikipedia.org/wiki/End-to-end_encryption">end-to-end encryption</a>. This is where alternatives such as Proton Drive shine: The service delivers significant value to its customers, but it doesn&rsquo;t monitor them because it&rsquo;s designed such that <em>it can&rsquo;t</em>.</p>
<p>A more user-centric model of cloud software is one where services do little more than store encrypted data that only clients can decrypt and utilize. For that to work well, we need smart clients.</p>
<h2 id="smart-clients">Smart clients</h2>
<p>There has been a decades-long shift away from independently-functioning software that lives on user&rsquo;s machines and towards a model where clients are only focused on managing the user experience rather than business logic.</p>
<p>End user devices are quite powerful these days and there&rsquo;s no reason we can&rsquo;t have them execute substantial business logic. Given that, and the fact that we apparently can&rsquo;t trust cloud providers to access and work with our data, it&rsquo;s worth considering a shift back to a model where clients do the heavy lifting and treat the server as a functional enhancement (such as for data redundancy) rather than a requirement. This is a core tenet of <a href="https://www.inkandswitch.com/local-first/">local-first software</a>, and it fits elegantly with the concept dumb servers that only store end-to-end encrypted data.</p>
<h2 id="public-key-identity">Public key identity</h2>
<p>While Proton offers an excellent privacy-oriented cloud solution, it still requires a username and password to register. Like Google and Facebook, this relinquishes ownership of the user&rsquo;s identity to the service. We&rsquo;ve normalized this model of software, but that doesn&rsquo;t mean it&rsquo;s a good one. People should be able to own their digital identity and not have to depend a on third-party to authenticate them.</p>
<p>Fortunately, there is an effective, established, battle-tested alternative: <a href="https://en.wikipedia.org/wiki/Public-key_cryptography">Public key cryptography</a>! It allows a user to create and provably attest their unique identity. When done correctly, it&rsquo;s effectively impossible for one person to impersonate another person&rsquo;s cryptographic key pair.</p>
<p>There are two significant drawbacks with public key cryptography:</p>
<ul>
<li>It&rsquo;s not intuitive to most people and never will be</li>
<li>Effective key management is critical and challenging</li>
</ul>
<p>These may be the major reasons that public key cryptography is not more widely used for identity. But in recent years, a solution to these problems has been developed: <a href="https://www.passkeys.io/">Passkeys</a>! Passkeys completely encapsulate the complexities of public key identity and automate away the burden of key management. <a href="https://webauthn.io/">WebAuthn</a> is the implementation of Passkeys for the web, and hopefully we will see increased adoption of it.</p>
<p>Rather than provide a username and password to web services when registering, users could instead provide public key credentials via WebAuthn and keep their real identity private. This is a better model, because it&rsquo;s safer and ultimately simpler for users. Passkeys can be backed up to a trusted cloud-based system of a user&rsquo;s choosing, and they don&rsquo;t need to worry about remembering usernames or passwords. All they have to do is present biometric identification (such as a fingerprint or facial scan) and they have access to their account.</p>
<hr>
<h2 id="a-future-we-can-have-if-we-choose-it">A future we can have if we choose it</h2>
<p>We have normalized cloud services knowing everything about us and having total control over us online. This is a risky way to live, as our digital existence is based on little more than hope. Hope that Google and Facebook won&rsquo;t misuse our data (either intentionally or accidentally), and hope that we don&rsquo;t run afoul of capricious and byzantine service policies.</p>
<p>Many people are comfortable with the status quo, and they probably always will be because it&rsquo;s familiar and works well most of the time. But not everyone wants to settle for the status quo. There&rsquo;s always room for alternatives to exist and thrive, and there&rsquo;s always an audience for more sophisticated way of doing things. Along with the mainstream options like Google and Facebook, we can have more advanced cloud services that are designed around end-to-end encryption and public key identity. <strong>We just have to choose to build something better.</strong></p>
<p>This is a future that I personally want to see, so I&rsquo;m building my own expression of what that might look like. I&rsquo;m developing <a href="https://github.com/passway-project/passway/wiki/Passway-architecture">Passway</a>, an API designed around end-to-end encrypted storage and public key identity. My long-term goal is to build a cloud that does everything for you, but knows nothing about you. It&rsquo;s very early days for the project, but I hope to see it or something like it become a common model for cloud computing. Wish me luck!</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>I specifically mean &ldquo;users&rdquo; and not &ldquo;customers&rdquo;, because many of Google&rsquo;s users are indeed <a href="https://quoteinvestigator.com/2017/07/16/product/">the product and not the customer</a>.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded></item><item><title>Unkillable Apps</title><link>https://jeremyckahn.github.io/posts/unkillable-apps/</link><pubDate>Sun, 05 Nov 2023 16:42:22 +0000</pubDate><guid>https://jeremyckahn.github.io/posts/unkillable-apps/</guid><description>Good software doesn&amp;rsquo;t die. Great software can&amp;rsquo;t be taken away.
Much like a cool URI, software is only relevant so long as it&amp;rsquo;s available for use. Unfortunately, software is trending towards a fragile design: The Cloud. If you&amp;rsquo;re a Cloud Architect and reading this, relax. This isn&amp;rsquo;t a condemnation of your work. Cloud-based architecture has many benefits and there is a place for it. However, it is fundamentally flawed in a key way: The user doesn&amp;rsquo;t own the software.</description><content:encoded><![CDATA[<p>Good software doesn&rsquo;t die. Great software <em>can&rsquo;t be taken away</em>.</p>
<p>Much like a <a href="https://www.w3.org/Provider/Style/URI">cool URI</a>, software is only relevant so long as it&rsquo;s available for use. Unfortunately, software is trending towards a fragile design: The Cloud. If you&rsquo;re a Cloud Architect and reading this, relax. This isn&rsquo;t a condemnation of your work. Cloud-based architecture has many benefits and there is a place for it. However, it is fundamentally flawed in a key way: The user doesn&rsquo;t own the software. At best the user <em>rents</em> the software, and even then the user can be evicted (<a href="https://www.nytimes.com/2022/08/21/technology/google-surveillance-toddler-photo.html">or worse</a>) with no recourse. This is a critical design flaw for many use cases and there needs to be an alternative.</p>
<p>We need software that doesn&rsquo;t go down when AWS does. We need software that the user owns and controls. We need software that can&rsquo;t be taken away due to <a href="https://killedbygoogle.com/">corporate whims</a> or <a href="https://en.wikipedia.org/wiki/Censorship_of_GitHub">government overreach</a>. We need <strong>Unkillable Apps</strong>.</p>
<h2 id="anatomy-of-an-unkillable-app">Anatomy of an Unkillable App</h2>
<p>An Unkillable App is:</p>
<ul>
<li>Open source</li>
<li>A self-hostable static web app</li>
<li>Cloud-agnostic</li>
</ul>
<p>Let&rsquo;s dig into each of these characteristics.</p>
<h3 id="open-source">Open source</h3>
<p>The foundation of an Unkillable App is its source code. If the user does not have access to their software&rsquo;s source code, then they have no ability to modify its operation. If your app is not open source, then it is trivially killable and you might as well stop reading this article now.</p>
<p>With open source code, the user is empowered to fix bugs and make updates when the software&rsquo;s context changes. For example, closed-source software is liable to be abandoned by its developer and may cease to function when the operating system it runs on is updated.</p>
<p>Open source software is automatically redundant. Everything on the internet is permanent (<a href="https://www.normantranscript.com/news/once-on-the-internet-always-on-the-internet/article_4bb953b0-8804-11eb-9bad-c7b05bdeb4cc.html">for better or worse</a>), and that includes published source code. It is trivial to hit the Fork button in GitHub or simply <code>git clone</code> a project to preserve it offline. When software is open source, everyone owns it and it cannot be taken away. A hostile government could attempt to suppress an open source project (<a href="https://element.io/blog/india-bans-flagship-client-for-the-matrix-network/">and they do</a>), but there are no technical means by which they could remove it from existence.</p>
<p>Open source software will last until the end of the internet.</p>
<h3 id="a-self-hostable-static-web-app">A self-hostable static web app</h3>
<p>Open source software is a great place to start, but it won&rsquo;t do people much good if it can&rsquo;t actually be run. Software that&rsquo;s designed to be <a href="https://en.wikipedia.org/wiki/Self-hosting_(web_services)">self-hosted</a> is designed to survive. This doesn&rsquo;t mean that software <em>must</em> be self-hosted (after all, doing so is extra work), but it must be available as an option in case the principal version of an app becomes unavailable. Think of it as a <a href="https://en.wikipedia.org/wiki/Failover">failover</a> mechanism. To make self-hosting practical, complete application data export functionality must be available to users so that they can migrate between app instances.</p>
<p>Software that is open source and self-hostable is a <a href="https://en.wikipedia.org/wiki/Lernaean_Hydra">hydra</a>. You can try to kill it, but it will always reappear elsewhere.</p>
<p>The simplest kind of app to self-host is a <a href="https://www.staticapps.org/articles/defining-static-web-apps/">static web app</a>. It&rsquo;s strictly a set of HTML, CSS, and JavaScript files. If built appropriately, it will run on any device. A static web app is immune to operating system updates and the risks of outdated system libraries. And web apps can last <strong>forever.</strong> The original <a href="https://www.spacejam.com/1996/">Space Jam website</a> is still online and functional because it was built to web standards. Web standards are both stable (once completed) and <a href="https://whatwebcando.today/">powerful</a>.</p>
<p>I&rsquo;ve written previously about <a href="https://jeremyckahn.github.io/posts/pwa-agony-and-ecstasy/">the incredible power of PWAs</a>. That power can be made available indefinitely if it is built to be self-hosted and not reliant on specific cloud services.</p>
<h3 id="cloud-agnostic">Cloud-agnostic</h3>
<p>A static web app can be served from any HTTP server. That flexibility lends a lot of durability because anyone can run an HTTP server. Why not extend that flexibility to any web services that the app depends on?</p>
<p>It would be very limiting to artificially restrict a web app to just locally-available APIs. After all, web browsers are most powerful when they connect to other computers and exchange data. Unkillable Apps don&rsquo;t depend on proprietary web services. Instead, they treat web services like a &ldquo;dumb&rdquo; resource. A practical example of this is remote data storage. Rather than building a web app&rsquo;s storage mechanism around something like AWS S3, consider building it to use generic file storage solutions as a back end. You could integrate with <a href="https://nextcloud.com/">Nextcloud</a>, Dropbox, Google Drive, etc. and allow the user to log in to whichever storage provider they want. <a href="https://stackedit.io/">StackEdit</a> is a shining example of this. StackEdit persists data locally by default but offers the option to sync with Dropbox, Google Drive, GitHub, or GitLab. Even if the developer of StackEdit abandons the project, I can be confident that I&rsquo;ll always have access to my data because it was stored in the system of my choosing.</p>
<p>An Unkillable App relegates the cloud to being an implementation detail. When one doesn&rsquo;t meet the needs of the user, they can trivially switch to one that does.</p>
<h2 id="unkillable-apps-for-a-better-future">Unkillable apps for a better future</h2>
<p>I believe the future of software can be bright and amazing, but only if we design for it. We have to choose open source. We have to choose a standard and stable technology platform. We have to choose to be cloud-agnostic. <strong>We have to choose to build software that cannot die or be taken away.</strong></p>
<p>Users need to rightly trust that the apps they depend on will be there tomorrow. Because if we don&rsquo;t do this, we will always be dependent on corporations that do not prioritize our interests.</p>
<p>We have the tools to build the future we want. So let&rsquo;s build it!</p>
]]></content:encoded></item><item><title>The Agony and Ecstasy of PWAs</title><link>https://jeremyckahn.github.io/posts/pwa-agony-and-ecstasy/</link><pubDate>Fri, 03 Nov 2023 13:48:42 +0000</pubDate><guid>https://jeremyckahn.github.io/posts/pwa-agony-and-ecstasy/</guid><description>I love PWA technology. I think it&amp;rsquo;s the most powerful and empowering technology that has come along since the creation of the internet. And it&amp;rsquo;s never going to succeed.
Why is this? How could a great technology utterly fail to make meaningful market share inroads? Let&amp;rsquo;s explore why PWAs are awesome, and why nobody cares.
User-centric design Progressive Web Apps (PWAs) are literally just web pages with some additional functionality to make them behave like a native application.</description><content:encoded><![CDATA[<p>I love <a href="https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps">PWA technology</a>. I think it&rsquo;s the most powerful and empowering technology that has come along since the creation of the internet. And it&rsquo;s never going to succeed.</p>
<p>Why is this? How could a great technology utterly fail to make meaningful market share inroads? Let&rsquo;s explore why PWAs are awesome, and why nobody cares.</p>
<h2 id="user-centric-design">User-centric design</h2>
<p>Progressive Web Apps (PWAs) are literally just web pages with some additional functionality to make them behave like a native application. The key components of this illusion are the ability to install the web page such that it appears alongside actually-native apps like Microsoft Paint or Apple Messages, and some level of offline functionality. When opened, PWAs render in a dedicated window as their own app, distinct from any browser. Under the hood they&rsquo;re just another browser tab, but they present as a fully-formed, installed application.</p>
<p>Because PWAs are web pages at their core, they natively offer all of the benefits of a standard web page. That includes <a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility">accessibility</a>, <a href="https://wiki.mozilla.org/Security/Sandbox#Overview">security sandboxing</a>, the potential to be customized via browser extensions, and observability via browser devtools. Every mainstream web browser has devtools that allow the user to take a look at the code that&rsquo;s running on their device. Most people won&rsquo;t do this, but the important thing is that they <em>can</em>. Observability is a de facto right of web users that cannot be taken away by web developers<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>. And this is wonderful. I can&rsquo;t think of any other mainstream technology platform that puts the user&rsquo;s interests ahead of the developer&rsquo;s in this way. Because of this, PWAs are inherently user-centric in a manner that native apps uniformly choose not to be.</p>
<p>In general the tech industry has sort of lost the plot of what we&rsquo;re trying to accomplish. Computers are magical and amazing things, and they could do so much great stuff for people. Unfortunately &ldquo;tech&rdquo; has been largely co-opted by VCs into being a wealth extraction mechanism, so user-centric design has taken a back seat to investor-centric design. This has led to widespread <a href="https://en.wikipedia.org/wiki/Enshittification">enshittification</a> and a general degradation of product quality. I don&rsquo;t see this changing in the near future, but the user-centric design built in at the platform level of PWAs at least gives us a hope that it someday could.</p>
<h2 id="simple-deployment">Simple deployment</h2>
<p>Not only do PWAs offer the most user-centric design, but they have the most developer-centric deployment mechanism available as well: The web! Depending on how a project is set up, deployment could be as simple as modifying a file on a server. By contrast: If you want to update a native app, you need to submit your change to the app store operator (Apple, Google, etc.), wait, and pray that they accept it. Native app developers have no real control over the software that is delivered to their users because app store operators could capriciously deny updates for any reason. <em>They</em> own the deployment platform.</p>
<p>With web technology, the server is the deployment platform. You could run one for free from home, if you&rsquo;d like. The web also has no gatekeepers or censors. There is no inherent payment processor that skims 30% off of every transaction. The web lets you own and control the code, the infrastructure, and the content. And the best part? PWAs run on every device! There&rsquo;s only one build target. It is the most successful implementation of &ldquo;<a href="https://en.wikipedia.org/wiki/Write_once,_run_anywhere">write once, run everywhere</a>&rdquo; in history. I struggle to conceive of a better way to ship software.</p>
<p>So far I&rsquo;ve extolled the myriad virtues of PWAs and you&rsquo;re hopefully as excited about them as I am. If you are, prepare to be disappointed!</p>
<p>PWAs have struggled to gain meaningful app market share, and I don&rsquo;t expect that to ever really change. There are two main reasons for this: Gatekeeping incumbents, and user expectations.</p>
<h2 id="corporate-incentives-stand-in-the-way">Corporate incentives stand in the way</h2>
<p>Apple effectively invented the concept of a modern app store, and it makes them billions of dollars a year. Many people seem to consider their practices unfair. I don&rsquo;t quite see it that way (nobody is requiring developers to publish with Apple), but I do see what such a market position means for us. iOS and its derivatives offer only one web browser<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup>, Safari. The problem is that Safari has always lagged behind the other major browsers in its feature set. This holds iOS back, and it therefore holds the potential for PWAs back as well because it&rsquo;s such a major platform. After all, why would a developer invest resources into a project if it won&rsquo;t work properly on <a href="https://www.statista.com/statistics/272698/global-market-share-held-by-mobile-operating-systems-since-2009/">over a quarter of mobile devices</a>?</p>
<p>Apple has an obvious incentive to limit its browser&rsquo;s capabilities: Apple can&rsquo;t monetize the web. Being the cunning profit-driven corporation that it is, Apple is going to seek to widen its various <a href="https://www.investopedia.com/ask/answers/05/economicmoat.asp">moats</a> as much as possible. Why invest in a technology that doesn&rsquo;t produce revenue when you could invest in one that does? It&rsquo;s hard to fault their logic, but the end result hurts users because it disincentivizes developers from creating PWAs and therefore diminishes user freedom.</p>
<h2 id="user-expectations">User expectations</h2>
<p>PWAs, as a concept, don&rsquo;t make sense to the average person. PWA installation is effectively a power user feature because typical users don&rsquo;t even consider the concept. Computer users have been implicitly trained for decades to think of web browsers as a means of basic content access and to rely on installed native apps for more advanced work and engagement. Can you honestly think of anyone in your life (who isn&rsquo;t a web developer or technology enthusiast) that would default to installing an app via the web rather than their app store?</p>
<p>This isn&rsquo;t actually a technology or design problem. No, it&rsquo;s a <em>marketing</em> problem. Marketing problems can only be solved with money, and there isn&rsquo;t a clear ROI in solving this particular one. So things will likely remain this way.</p>
<p>&ldquo;We just need an app store for PWAs!&rdquo; I hear you say. Bad news: It&rsquo;s been tried and it hasn&rsquo;t succeeded. <a href="https://appsco.pe/">Appscope</a> has been abandoned and nobody is talking about <a href="https://store.app/">store.app</a>. I <em>want</em> these stores to win. I just don&rsquo;t see the business model to support them, though.</p>
<p>I really want to be wrong. I want to see PWAs flourish and render native apps irrelevant. But there needs to be a killer business model behind them for it to happen. Without that, the primary audience for PWAs is other web developers.</p>
<h2 id="what-we-can-do">What we can do</h2>
<p>The good news is that PWAs aren&rsquo;t going anywhere. It&rsquo;s a web standard that&rsquo;s in wide deployment. It&rsquo;s an effective technology choice for hobby projects and side hustles. I don&rsquo;t see Apple ceding its market share any time soon, but that doesn&rsquo;t mean that we can&rsquo;t enjoy PWAs today and into the future. I think <strong>we just have to accept that it will always be a less successful platform, especially for Apple users</strong>.</p>
<p>I plan to keep making open source PWAs because it&rsquo;s such an effective solution for <a href="https://github.com/jeremyckahn/">the hobby projects I like to build</a>. I encourage you to do the same. If you value developer control and user freedom, PWAs are the obvious choice.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>It&rsquo;s worth mentioning that developers can (and generally should, for performance reasons) minify their code before deploying it. This makes it less than trivial to figure out what the code is doing, but the point is that it&rsquo;s possible to do so, rather than impossible (or <a href="https://www.nowsecure.com/blog/2021/09/08/basics-of-reverse-engineering-ios-mobile-apps/">harder</a>, anyways) like it is with native apps.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>Yes, I know there&rsquo;s other browsers on the iOS App Store. But due to Apple&rsquo;s restrictions, they&rsquo;re implemented as reskins of Safari and therefore cannot implement the web platform features that Safari is missing.&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded></item><item><title>YAB: Yet Another Blog</title><link>https://jeremyckahn.github.io/posts/yet-another-blog/</link><pubDate>Tue, 31 Oct 2023 09:31:40 -0500</pubDate><guid>https://jeremyckahn.github.io/posts/yet-another-blog/</guid><description>For at least the fourth time in my career, I am starting a dev blog. Surely, thoughts as original and provocative as mine must be shared with the the world1, so here they are. After all, are you even an open source developer if you don&amp;rsquo;t make the occasional rambling screed on the internet?
The first time I tried this, I used Octopress. I really enjoyed the Git and Markdown-driven nature of the tool, but sadly it has become irrelevant due to lack of maintenance.</description><content:encoded><![CDATA[<p>For at least the fourth time in my career, I am starting a dev blog. Surely, thoughts as original and provocative as mine <em>must</em> be shared with the the world<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>, so here they are. After all, are you even an <a href="https://github.com/jeremyckahn/">open source developer</a> if you don&rsquo;t make the occasional rambling screed on the internet?</p>
<p>The first time I tried this, I used <a href="http://octopress.org/">Octopress</a>. I really enjoyed the Git and Markdown-driven nature of the tool, but sadly it has become irrelevant due to lack of maintenance. Also nobody uses Ruby anymore <sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup>. The second time I tried this, I used Medium. But Medium doesn&rsquo;t support syntax highlighting without <a href="https://medium.com/@Maluen0/how-to-add-code-highlighting-in-medium-articles-without-leaving-the-editor-8f24f5a88d28">absurd workarounds</a>, so I gave up on it. Next I tried <a href="https://dev.to/jeremyckahn">dev.to</a>. I like dev.to and actually plan to keep using it for some content because it provides a lot of nice features out of the box and has a strong community. But I&rsquo;ve come to realize that dev.to is more geared towards tutorials, which is not always what I want to write. Sometimes I just want to rant into the void about computers and dev.to simply isn&rsquo;t the forum for that. Also I don&rsquo;t love the idea of my authored content generating income for a platform that doesn&rsquo;t share it back with me.</p>
<p>If I&rsquo;m not making money with my work, then nobody is, dammit.</p>
<p>Which brings me to this iteration of my attempt at blogging. This blog is <a href="https://github.com/jeremyckahn/jeremyckahn.github.io">open source</a> and built with <a href="https://gohugo.io/">Hugo</a>. I wanted a solution that would get the tech out of the way and just let me write. I&rsquo;m hoping that Hugo can be that. <a href="https://github.com/jeremyckahn/jeremyckahn.github.io/commit/f1d83c7edc4a7eb4c9cca289240f7a350b8968fb">I&rsquo;ve set this blog up</a> such that I can just <a href="https://github.com/jeremyckahn/jeremyckahn.github.io/blob/main/.github/workflows/init-post.yml">create a post and go</a>. Hopefully by simplifying the blogging process down to just managing Markdown files and <a href="https://github.com/jeremyckahn/jeremyckahn.github.io/blob/main/.github/workflows/deploy.yml">pushing to GitHub</a>, I can stay motivated to actually write. We shall see.</p>
<p>I like to make snarky jokes about technology. I like absurdity. I don&rsquo;t take anything seriously, because life is too short for that. I believe in <a href="https://twitter.com/mjkeenan/status/832684374680219649">Comedy first. Always</a>. If you can&rsquo;t learn to laugh at yourself and everything else, this blog is probably not for you. There&rsquo;s also an outside chance that I may occasionally have something vaguely insightful to share, but I&rsquo;m not making any promises.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>I am not actually this self-congratulatory. Most of the time when I say something even remotely self-aggrandizing, I am being sarcastic. But sarcasm doesn&rsquo;t come across properly on the internet unless you use italics, emojis, or footnotes, hence this clarification.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>Again, sarcasm. You&rsquo;d better get used to this, or you&rsquo;re going to have a tough time with this blog.&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded></item></channel></rss>