<?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>&lt;shortdiv /&gt;</title>
    <link>https://shortdiv.com/</link>
    <description>Recent content on &lt;shortdiv /&gt;</description>
    <generator>Hugo -- 0.152.0</generator>
    <language>en-us</language>
    <lastBuildDate>Tue, 24 Mar 2026 10:54:13 -0400</lastBuildDate>
    <atom:link href="https://shortdiv.com/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Infra has an intent problem</title>
      <link>https://shortdiv.com/posts/infra-has-an-intent-problem/</link>
      <pubDate>Tue, 24 Mar 2026 10:14:13 -0400</pubDate>
      <guid>https://shortdiv.com/posts/infra-has-an-intent-problem/</guid>
      <description>&lt;p&gt;In a past job, I broke networking within my first week of starting. The change? A single line commit that added a customer domain to a reverse proxy control loop that directed traffic to a specific server.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;api.somecompany.com, api.anotherfancynewcompany.ai {
  reverse_proxy http://localhost:4200
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;At a glance, this code is legible, it &lt;em&gt;should&lt;/em&gt; work; we’re manually proxying traffic from two domains to a locally running instance. A passing caddy validate run further verifies this.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Whatever you do, don&#39;t lose the plot</title>
      <link>https://shortdiv.com/posts/dont-lose-the-plot/</link>
      <pubDate>Fri, 20 Mar 2026 15:13:19 -0400</pubDate>
      <guid>https://shortdiv.com/posts/dont-lose-the-plot/</guid>
      <description>&lt;p&gt;The other day, I was working on translating data from a file into json to visualize the results. Easy enough, given that this was an operation I’d done countless times in the past. Still, I blanked. After spending months delegating all coding related tasks to an agent, I’d completely lost the muscle memory of a simple &lt;code&gt;fs.readFileSync&lt;/code&gt; call. I ended up sheepishly reaching for Claude, which wrote the function in more time than past me would have taken.&lt;/p&gt;</description>
    </item>
    <item>
      <title>2025; Welcome Home</title>
      <link>https://shortdiv.com/posts/2025-welcome-home/</link>
      <pubDate>Wed, 31 Dec 2025 19:16:09 -0500</pubDate>
      <guid>https://shortdiv.com/posts/2025-welcome-home/</guid>
      <description>&lt;p&gt;Who am I, if not what I do? This was the question that haunted me at the start of the year. I began 2025 willingly unemployed, which was more uncomfortable than I’d imagined. Growing up in Asia, I’d been conditioned to believe that “a life well-lived” followed a clear rubric: education, career, family, being a “good person”. But who am I, bereft of that plan? If not in relation to someone else, and to a job? I work, therefore I am.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Infra is stacks of turtles</title>
      <link>https://shortdiv.com/posts/infra-is-stacks-of-turtles/</link>
      <pubDate>Mon, 22 Dec 2025 21:21:36 -0500</pubDate>
      <guid>https://shortdiv.com/posts/infra-is-stacks-of-turtles/</guid>
      <description>&lt;p&gt;In Pulumi, stacks can separate an infrastructure build by environment or by more granular concern. In a recent setup I worked on, we went with the latter approach. One stack handled compute, another handled networking and a third managed global artifacts like container images. Given that Pulumi stacks are all about independent interoperable units, the stack differentiation helped us reason about our infrastructure as separate areas of concern. Until it didn’t.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Journey to Otel Collector</title>
      <link>https://shortdiv.com/posts/the-journey-to-otel-collector/</link>
      <pubDate>Fri, 19 Dec 2025 23:25:03 -0500</pubDate>
      <guid>https://shortdiv.com/posts/the-journey-to-otel-collector/</guid>
      <description>&lt;p&gt;In a previous role, I worked on establishing an observability stack using OpenTelemetry (OTel) which mostly involved setting up instances of OTel collector to run across a distributed network. The main goal of this effort was to decouple data collection from data export, to more reliably gather data from various services for export.&lt;/p&gt;
&lt;p&gt;In the simplest of setups, logs, and metrics can be sent directly to Grafana Cloud via an &lt;strong&gt;OTLP (OTel Protocol)&lt;/strong&gt; exporter. An OTLP exporter is the component that sends your telemetry data from the OTel Collector to a backend like Grafana. Exporters generally handle authentication, and batching and can be configured for HTTP or gRPC transport. Essentially, they act as the bridge between your application’s telemetry and your monitoring platform.&lt;/p&gt;</description>
    </item>
    <item>
      <title>You might not need an orchestrator</title>
      <link>https://shortdiv.com/posts/you-might-not-need-an-orchestrator/</link>
      <pubDate>Wed, 17 Dec 2025 22:59:11 -0500</pubDate>
      <guid>https://shortdiv.com/posts/you-might-not-need-an-orchestrator/</guid>
      <description>&lt;p&gt;Across the startups that I’ve worked at, a recurring theme has been using Nomad and eventually migrating off of it. In one of them, &lt;a href=&#34;https://fly.io/blog/carving-the-scheduler-out-of-our-orchestrator/&#34;&gt;which you might already be fairly acquainted with&lt;/a&gt;, Nomad was an initial iteration at constraint-based deployments enabling regional rollouts and seamless rescheduling across a fleet during maintenance events. For a company like Fly.io that gives customers the ability to schedule apps in different regions, an orchestrator is fundamental to the user experience. That said, many companies (at least several that I’ve worked at) rely on orchestrators like Nomad for deployments. In these instances, Nomad is overkill and often complicate the deployment experience.&lt;/p&gt;</description>
    </item>
    <item>
      <title>There&#39;s an &#39;A&#39; in failure</title>
      <link>https://shortdiv.com/posts/theres-an-a-in-failure/</link>
      <pubDate>Tue, 16 Dec 2025 22:53:59 -0500</pubDate>
      <guid>https://shortdiv.com/posts/theres-an-a-in-failure/</guid>
      <description>&lt;p&gt;I was recently let go from my role. This wasn’t my first experience with an unexpected termination. In fact, this time last year I found myself in a similar situation albeit under different circumstances and with far more surprise. Yet this one felt like an especially low point in my career; unexpected in a similar way, but predictable given the circumstances.&lt;/p&gt;
&lt;p&gt;I was technically on an unofficial PIP prior to receiving the news, which was somewhat reasonable given that I wasn’t shipping and showing progress fast enough. I had taken on the substantial task of reconfiguring our infra from the ground up, all while maintaining the current one single handedly. &lt;a href=&#34;https://shortdiv.com/posts/30-60-90-into-the-new-job/&#34;&gt;I’d written about this in a previous blogpost&lt;/a&gt;, but this job stretched my skills well past my comfort zone and I was firing on all cylinders. With little to no onboarding (as is often common in every early-stage startup) I had to learn fast, make decisions confidently, and move at breakneck pace. In previous roles, I frequently had the support of a team or a more senior coworker when I pushed significantly past a growth edge. This time, however, I was on my own, operating in a completely asynchronous remote environment, building greenfield infra I had no prior experience with. I thought I could manage (I am no stranger to working through uncertainty) but this work was arduous and there was barely enough room or time for a beginner’s mindset.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Sync the local-first powerhouse</title>
      <link>https://shortdiv.com/posts/sync-the-local-first-powerhouse/</link>
      <pubDate>Mon, 15 Dec 2025 23:47:33 -0500</pubDate>
      <guid>https://shortdiv.com/posts/sync-the-local-first-powerhouse/</guid>
      <description>&lt;p&gt;One of the hardest problems in local-first software is sync. In previous posts, I talked about OTs/CRDTs, the role of the cloud relative to the client, and general conflict resolution. But I never quite landed on the core theme behind those ideas; sync is the bread and butter of data reconciliation in local-first software. Briefly, a sync engine is responsible for collecting changes, resolving conflicts and propagating these changes across all clients. Considering that every client operates on their own copy of the data, and can go offline for long, unknown stretches of time, a good sync engine must be designed for availability, partition tolerance, and &lt;strong&gt;eventual&lt;/strong&gt; consistency the classic trifecta of trade-offs in distributed systems.&lt;/p&gt;</description>
    </item>
    <item>
      <title>What Makes a Good Deterministic Merge</title>
      <link>https://shortdiv.com/posts/what-makes-a-good-deterministic-merge/</link>
      <pubDate>Fri, 12 Dec 2025 22:19:26 -0500</pubDate>
      <guid>https://shortdiv.com/posts/what-makes-a-good-deterministic-merge/</guid>
      <description>&lt;p&gt;The goal of every data reconciliation algorithm is to ensure all replicas converge on the same state of the world, in spite of concurrent changes. The best way to achieve this is through a deterministic merge where the same result can be guaranteed regardless of the order or timing of updates. The backbone of a deterministic merge is one that is associative (grouping doesn’t matter), commutative (order doesn’t matter) and idempotent (reapplying changes yields the same result).&lt;/p&gt;</description>
    </item>
    <item>
      <title>It&#39;s more than just OT vs CRDT</title>
      <link>https://shortdiv.com/posts/its-more-than-just-ot-vs-crdt/</link>
      <pubDate>Thu, 11 Dec 2025 20:33:10 -0500</pubDate>
      <guid>https://shortdiv.com/posts/its-more-than-just-ot-vs-crdt/</guid>
      <description>&lt;p&gt;When it comes to data reconciliation in the context of building real-time, collaborative user experiences, two major techniques are often discussed: Operational Transform (OT) and Conflict-free Data Replicated Types (CRDT). OT was developed in the late 80s and pioneered the foundational principles of real time collaborative editors. CRDTs emerged much later (around 2006), and were partly motivated by the complexities of implementing OT and the correctness pitfalls it can introduce. If we compare the two methodologies more broadly, OT is a strictly operation-based approach to data reconciliation while CRDTs offer both state-based and operation-based approaches. Examining the two from this lens, it’s clear that OT and CRDT are not simply opposites. More accurately, they are representative examples within a broad spectrum of reconciliation strategies. A more meaningful comparison therefore would be state-based vs operation-based approaches. This better captures the fundamental differences in how changes are propagated and merged across replicas.&lt;/p&gt;</description>
    </item>
    <item>
      <title>A Primer on Conflict in Local First</title>
      <link>https://shortdiv.com/posts/a-primer-on-conflict-in-local-first/</link>
      <pubDate>Wed, 10 Dec 2025 23:50:49 -0500</pubDate>
      <guid>https://shortdiv.com/posts/a-primer-on-conflict-in-local-first/</guid>
      <description>&lt;p&gt;In my last post, I argued that conflict in local-first is an inherently human problem. Without understanding the intent, and expectations of the end user, reconciliation is not always meaningful, given that correctness doesn’t equal usefulness from a user perspective. Before we dive into the technicalities of how conflicts get resolved, it’s worth exploring why drift happens in the first place and the basics of how it gets resolved.&lt;/p&gt;
&lt;p&gt;When we work in settings where multiple replicas can be edited independently, conflict is a direct, unavoidable result. Replicas can drift apart for several reasons: network latency, concurrent changes, and offline edits are all a natural cause of divergence in local-first systems. Once the replicas diverge, the need to agree on consistent state arises. The goal here is deterministic reconciliation. In other words, given a set of changes, all replicas should eventually all converge on the same result.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The semantics of conflict</title>
      <link>https://shortdiv.com/posts/the-semantics-of-conflict/</link>
      <pubDate>Tue, 09 Dec 2025 23:28:42 -0500</pubDate>
      <guid>https://shortdiv.com/posts/the-semantics-of-conflict/</guid>
      <description>&lt;p&gt;Conflict is a recurring topic of discussion in the local-first space. This is unsurprising given that real time collaboration and intermittent offline access inevitably introduces drift between replicas. When multiple users collaborate on a single application or even when a user works on the same application from separate devices, change conflicts occur. This echoes a foundational principle in distributed systems: when networks partition, systems must decide how and whether to be consistent or available. In fact, much of the conversation around conflict resolution in local-first draws directly from distributed systems. Topics such as Conflict-free Replicated Data Type (CRDT) and Operational Transform (OT) all stem from key research in distributed systems. However, unlike in distributed systems where conflict is a matter of direct data reconciliation, conflict in local-first is a result of collaboration and is therefore, arguably, a human problem as much as a technical one.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The client is the replica</title>
      <link>https://shortdiv.com/posts/the-client-is-the-replica/</link>
      <pubDate>Mon, 08 Dec 2025 18:56:18 -0500</pubDate>
      <guid>https://shortdiv.com/posts/the-client-is-the-replica/</guid>
      <description>&lt;p&gt;With the rise of mobile in the early aughts, where updates and collaborative edits felt instantaneous (since they wrote directly to local storage and used shared network drives) the traditional client-server model of the web proved clunky. Instead of instantaneous updates that were common to mobile interactions, web updates incurred added latency from the extra round trip it had to make. The responsiveness of native apps set a new precedent for user experience.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The promise of local-first</title>
      <link>https://shortdiv.com/posts/the-promise-of-local-first/</link>
      <pubDate>Fri, 05 Dec 2025 23:47:54 -0500</pubDate>
      <guid>https://shortdiv.com/posts/the-promise-of-local-first/</guid>
      <description>&lt;p&gt;There’s nothing quite like the clarity of losing your job on a friday that forces you to contend with the bigger question; who and what kind of future do you want to build for? For the last year, I’ve been deep in the local-first ecosystem, learning alongside peers and building the infrastructure to power local-first software. Amidst the hype of AI and agent-driven code, I’ve witnessed a quiet hum of folks demanding to take back control, of their data, of their tools and of the role software has in their everyday lives. Local-first is not just a software methodology, it is a philosophical movement. It’s about building software for people in the context of where they’re at.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The cloud is the cache</title>
      <link>https://shortdiv.com/posts/the-cloud-is-the-cache/</link>
      <pubDate>Thu, 04 Dec 2025 22:42:00 -0500</pubDate>
      <guid>https://shortdiv.com/posts/the-cloud-is-the-cache/</guid>
      <description>&lt;p&gt;As the saying goes there is no cloud, just someone else’s computer. Simplistic as it is, the saying captures a universally accepted reality: app data is better off hosted elsewhere living on someone else’s hardware (I’m looking at you GCP and AWS). The issue with this cloud-first sentiment is that it relegates the cloud as a panacea. Sure, giving control to the cloud frees us from the burden of bootstrapping infrastructure and managing complex ops, but it comes with its own set of tradeoffs. Chief among them? The total loss of control over our own data. Not to mention the added reliance on third-party uptime (looking right at you us-east-1).&lt;/p&gt;</description>
    </item>
    <item>
      <title>Local-first, why now?</title>
      <link>https://shortdiv.com/posts/local-first-why-now/</link>
      <pubDate>Wed, 03 Dec 2025 23:33:11 -0500</pubDate>
      <guid>https://shortdiv.com/posts/local-first-why-now/</guid>
      <description>&lt;p&gt;The rise of the local-first movement was no anomaly. For years, browsers were no match for native environments that offered superior performance and offline capabilities. The gap was painfully obvious, native apps could store gigabytes of data and had access to a whole file system while browsers barely scraped by with megabytes. Modern browsers have since caught up over the last few years and the divide between browser and native environments has significantly blurred. There were many developments that gave rise to this, chief among which are: larger browser storage capacity, and new storage APIs. Let’s examine these.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Local-first is not offline-first</title>
      <link>https://shortdiv.com/posts/local-first-is-not-offline-first/</link>
      <pubDate>Tue, 02 Dec 2025 22:53:43 -0500</pubDate>
      <guid>https://shortdiv.com/posts/local-first-is-not-offline-first/</guid>
      <description>&lt;p&gt;In my last post, I mentioned that what makes an app local-first is its ability to keep running even when a connection falters. At first glance, this might look a lot like the offline-first movement that arose alongside the progressive enhancement wave of the mid to late 2010s. But there’s a subtle distinction. Offline-first apps focused primarily on staying functional during network interruptions but the server remained the primary data source. Data in this context is stored locally until a connection is restored, after which the locally stored data is deleted in favor of the remote store. A restored network connection progressively enhanced the experience and syncing only happened when there was new data created during the interim offline period to upload.&lt;/p&gt;</description>
    </item>
    <item>
      <title>What is local-first?</title>
      <link>https://shortdiv.com/posts/what-is-local-first/</link>
      <pubDate>Mon, 01 Dec 2025 22:46:44 -0500</pubDate>
      <guid>https://shortdiv.com/posts/what-is-local-first/</guid>
      <description>&lt;p&gt;I’m frequently amused by how often local-first software gets mistaken for community initiated software. The ethos is spot on, but the confusion is revealing: cloud first has become the de facto standard for building apps. Local-first challenges this notion and subverts the dynamic between cloud and device. It puts the device at the center of operations. In this way, local-first apps remain operational despite an unstable connection unlike cloud-first ones. This of course doesn’t disregard the cloud completely. In a local-first model, the cloud shifts to the role of facilitator, ensuring data is synchronized across devices and sessions.&lt;/p&gt;</description>
    </item>
    <item>
      <title>30/60/90 into the new job</title>
      <link>https://shortdiv.com/posts/30-60-90-into-the-new-job/</link>
      <pubDate>Tue, 02 Sep 2025 10:45:06 -0400</pubDate>
      <guid>https://shortdiv.com/posts/30-60-90-into-the-new-job/</guid>
      <description>&lt;p&gt;I’ve been pretty quiet about my work life lately. But spoiler alert, I have a job (and have been at it for the last 3 months)!&lt;/p&gt;
&lt;p&gt;If you spoke to me earlier this year or read a previous post about my job search, you’d have heard that the journey to a job post layoff for me was an emotional rollercoaster. Interviewing was not a strength of mine. I spent months getting wooed by companies impressed by my resume only to get rejected after yet another failed technical. It was horrifyingly depressing. But just as I was starting to lose steam, I got my break and landed a dream role, in the most unexpected (but unsurprising) of ways—in person, at a conference.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Somewhere Between Lost and Found</title>
      <link>https://shortdiv.com/posts/somewhere-between-lost-and-found/</link>
      <pubDate>Thu, 24 Jul 2025 09:23:09 -0400</pubDate>
      <guid>https://shortdiv.com/posts/somewhere-between-lost-and-found/</guid>
      <description>&lt;p&gt;A few years ago, I received news of a professor’s passing in the most bizarrely impersonal way we tend to receive news these days: via a twitter mention from a college ex I hadn’t spoken to in years. The memorial service was set for that weekend in Central Massachusetts where he and his family lived. At the time, I was living in Cambridge, which was just a short train ride away. But I never made it past Back Bay.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Job Search Post-ZIRP</title>
      <link>https://shortdiv.com/posts/job-search-post-zirp/</link>
      <pubDate>Wed, 02 Apr 2025 14:25:47 -0400</pubDate>
      <guid>https://shortdiv.com/posts/job-search-post-zirp/</guid>
      <description>&lt;p&gt;I got laid off for the first time back in September (surprise!) and it took a giant toll on me emotionally. For the last 10 or so years I’d managed to muscle my way through engineering jobs despite not having a formal degree in CS. I’ve had the immense privilege of working at some really cool companies, working my way from the front of the frontend through the bowels of the stack and (for a brief moment) into the cold heart of bare metal. I’ve worked on product, systems, support tooling, growth/sales pipelines, billing, and miscellaneous developer workflows. In that time, I’ve written code in Ruby, JavaScript, TypeScript, Golang, Elixir and (some) Rust and worked with some crazy intelligent people. I’ve given talks internationally and written blog posts about various deeply technical pursuits. While I’m by no means an expert at all or many of things, I share this to say that I have a chunk of experience under my belt.&lt;/p&gt;</description>
    </item>
    <item>
      <title>2024 and thriving</title>
      <link>https://shortdiv.com/posts/2024-and-thriving/</link>
      <pubDate>Tue, 31 Dec 2024 20:48:29 -0800</pubDate>
      <guid>https://shortdiv.com/posts/2024-and-thriving/</guid>
      <description>&lt;p&gt;2024 was the year when I finally transitioned from surviving to thriving. With everything that transpired over the last few years, I got lost in the chaos of my reality and it&amp;rsquo;s taken me a second to &amp;ldquo;get back&amp;rdquo;. I&amp;rsquo;m not quite who I used to be, but I&amp;rsquo;ve become a version of myself that I&amp;rsquo;m quite pleased with, same same but different.&lt;/p&gt;
&lt;p&gt;The year came and went, for the most part, without incident. And (for once) I have no one to blame but myself for any and all shenanigans I found myself in. I grew, I learnt, and successfully averted any major crisis. In no specific order, here’s everything that happened this year in a nutshell:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Eventful Endeavors; Understanding how events shape a system</title>
      <link>https://shortdiv.com/posts/eventful-endeavors/</link>
      <pubDate>Thu, 08 Feb 2024 23:42:27 -0600</pubDate>
      <guid>https://shortdiv.com/posts/eventful-endeavors/</guid>
      <description>&lt;p&gt;Change is inevitable, especially so in applications that ebb and flow with system changes and user requirements. Generally, changes are codified in the form of an event; an event like a ddos attack for instance triggers a reaction or a response from one or more nodes, which ultimately mutates the overall state of the universe in a system.&lt;/p&gt;
&lt;p&gt;Undoubtedly, events rarely happen as one offs. At any given time, a sequence of events flows through the system. Whether it be a cascade of related events or multiple isolated events, the system is consistently responding and adapting.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Not So Hidden Life of Nodes; an exploration of how nodes talk to each other</title>
      <link>https://shortdiv.com/posts/not-so-hidden-life-of-nodes/</link>
      <pubDate>Wed, 07 Feb 2024 22:02:37 -0600</pubDate>
      <guid>https://shortdiv.com/posts/not-so-hidden-life-of-nodes/</guid>
      <description>&lt;p&gt;Distributed nodes share neither memory nor a logical clock. In order to effectively keep a system in running order, nodes need some way to communicate with one another to share data and coordinate complex tasks. Interprocess communication (IPC) plays an integral role in this. IPC is the mechanism that enables a server to query a database instance and resolve a request with the associated data successfully. Without it, nodes remain stranded akin to the people in the Tower of Babel, connected by infrastructure but unable to communicate with one another.&lt;/p&gt;</description>
    </item>
    <item>
      <title>She Doesnt Even Go Here! Defining membership in a distributed system</title>
      <link>https://shortdiv.com/posts/she-doesnt-even-go-here-membership-protocols/</link>
      <pubDate>Tue, 06 Feb 2024 22:12:54 -0600</pubDate>
      <guid>https://shortdiv.com/posts/she-doesnt-even-go-here-membership-protocols/</guid>
      <description>&lt;p&gt;In a distributed system, failures are to be expected. Whether it be a fault of the network or the node, failure is disruptive to the entire system. Failed processes struggle to recover and receive updates. Healthy nodes that try to connect to a failed node might fail completely or receive stale information, which can jeopardize the integrity and overall (C)onsistency of the system. To mitigate this, nodes have a failure mode, which it codifies in the form of a membership protocol.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Spilling the Hot Gossip Protocols</title>
      <link>https://shortdiv.com/posts/spilling-the-hot-gossip-protocols/</link>
      <pubDate>Mon, 05 Feb 2024 23:02:10 -0600</pubDate>
      <guid>https://shortdiv.com/posts/spilling-the-hot-gossip-protocols/</guid>
      <description>&lt;p&gt;In a distributed system, communication is crucial to ensuring no node becomes stale. Updates can happen in 2 main ways, through consensus, or through gossip. In a consensus model, nodes attempt to reach quorum by mutually agreeing on the order of updates or periodically voting on and rotating the leader in charge of distributing updates to fellow nodes—I covered the ins and outs of this in &lt;a href=&#34;https://shortdiv.com/posts/how-to-be-consistent-in-a-distributed-context/&#34;&gt;an earlier post&lt;/a&gt;, if you’re curious to learn more about it. Gossip is a concept analogous to consensus. It similarly keeps nodes updated except it achieves this via epidemic theory; If one node is infected, the entire population of nodes will eventually become infected.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Oh Cap Theorem My Cap Theorem</title>
      <link>https://shortdiv.com/posts/oh-cap-theorem-my-cap-theorem/</link>
      <pubDate>Sun, 04 Feb 2024 14:24:41 -0600</pubDate>
      <guid>https://shortdiv.com/posts/oh-cap-theorem-my-cap-theorem/</guid>
      <description>&lt;p&gt;In an earlier post, I glossed over a concept that forms a fundamental tenet of systems design; the CAP theorem. To reiterate, the CAP theorem states that of 3 desirable traits in a distributed system, Consistency, Availability and Partition tolerance, only 2 can be prioritized at any given time. It highlights the tradeoffs we make when we design for a distributed setting.&lt;/p&gt;
&lt;p&gt;The CAP theorem was birthed from the move away from vertical scaling where we simply sized up machines for greater processing capacity to horizontal scaling where machines work in a distributed and parallel fashion. The CAP theorem specifically focuses on databases, since it highlights the difficulty of maintaining state when reads and writes can originate from anywhere and can easily be disrupted in the event of a network failure.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to Be Consistent in a Distributed Context</title>
      <link>https://shortdiv.com/posts/how-to-be-consistent-in-a-distributed-context/</link>
      <pubDate>Sat, 03 Feb 2024 21:33:14 -0600</pubDate>
      <guid>https://shortdiv.com/posts/how-to-be-consistent-in-a-distributed-context/</guid>
      <description>&lt;h2 id=&#34;what-does-it-mean-to-be-consistent&#34;&gt;What does it mean to be consistent?&lt;/h2&gt;
&lt;p&gt;In an earlier post, we talked about the importance of building consensus when it comes to ensuring consistency in a distributed setting. Loosely, consistency focuses on keeping all nodes in a system up to date on changes as they happen in real time or near real time. This ensures the reliability of the system as a whole, so users are never (fully) let down when parts of the system unexpectedly go down.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Reaching Consensus</title>
      <link>https://shortdiv.com/posts/reaching-consensus/</link>
      <pubDate>Fri, 02 Feb 2024 23:59:03 -0600</pubDate>
      <guid>https://shortdiv.com/posts/reaching-consensus/</guid>
      <description>&lt;p&gt;In a distributed setup where nodes share the load of processing requests and storing/retrieving data, reaching consensus is crucial to ensuring consistency in an application. To return to the concert ticket sales example from the last post, we wouldn’t want 2 users buying the same seat since that violates the condition of assigned seating. Consensus can then be described as ensuring all nodes agree on a specific value or a state &lt;em&gt;in spite of a potential failure or delay&lt;/em&gt;; there lies the rub.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Demystifying Distributed Systems</title>
      <link>https://shortdiv.com/posts/demystifying-distributed-systems/</link>
      <pubDate>Thu, 01 Feb 2024 23:47:13 -0600</pubDate>
      <guid>https://shortdiv.com/posts/demystifying-distributed-systems/</guid>
      <description>&lt;h1 id=&#34;demystifying-distributed-systems-the-what-and-why&#34;&gt;Demystifying Distributed Systems: the what and why&lt;/h1&gt;
&lt;p&gt;If you deploy an app today, dealing with a distributed system is an inescapable problem. Whether it’s understanding how to balance requests, or synchronizing data replication, at least some aspect of your deployment will require orchestrating and coordinating multiple servers to operate in unison. The goal of “distributedness” here is to have things work across regions and systems in a way that is completely imperceptible to a user.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Playing With Shapes</title>
      <link>https://shortdiv.com/posts/playing-with-shapes/</link>
      <pubDate>Thu, 05 Dec 2019 23:31:04 -0600</pubDate>
      <guid>https://shortdiv.com/posts/playing-with-shapes/</guid>
      <description>&lt;p&gt;Didn&amp;rsquo;t make a lot of progress today and decided to play around with shapes instead.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a heart -&amp;gt; &lt;a href=&#34;https://codepen.io/shortdiv/pen/zYxGQBm?editors=1010&#34;&gt;https://codepen.io/shortdiv/pen/zYxGQBm?editors=1010&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Back to Primitives</title>
      <link>https://shortdiv.com/posts/back-to-primitives/</link>
      <pubDate>Wed, 04 Dec 2019 21:40:17 -0600</pubDate>
      <guid>https://shortdiv.com/posts/back-to-primitives/</guid>
      <description>&lt;p&gt;Geometry is the basis for drawing any shape in ThreeJS. As I covered in earlier posts, geometry in ThreeJS consists of vertices and faces, which can be defined by hand in order to create custom geometry. Of course, this task of defining your own vertices and faces is ambitious and requires a firm understanding of how math works in ThreeJS—knowledge which I currently do not have. To keep things simple, ThreeJS offers default 3D shapes known as primitives so you don’t have to grok geometry to generate common shapes like spheres and cubes.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Curveball</title>
      <link>https://shortdiv.com/posts/curveball/</link>
      <pubDate>Tue, 03 Dec 2019 22:58:23 -0600</pubDate>
      <guid>https://shortdiv.com/posts/curveball/</guid>
      <description>&lt;p&gt;Most shapes in ThreeJS and WebGL can be created using primitives many of which, you can use to create composite geometries, like &lt;a href=&#34;https://codepen.io/josephrexme/pen/YEemvw&#34;&gt;this really neat christmas tree&lt;/a&gt;. Creating complex and unique geometries however takes effort and can be difficult to achieve by simply compositing, mutating and ”extruding” existing primitives in ThreeJS. A better approach, as I highlighted in a previous post, is to utilize the methods like &lt;code&gt;Geometry&lt;/code&gt; in ThreeJS that give you the flexibility of defining vertices and faces for custom polyhedrons. In addition to this, ThreeJS also offers support for working with curves and smooth surfaces. &lt;code&gt;ParametricGeometry&lt;/code&gt; is example of such a method that gives you the ability to work with parametric surfaces, or surfaces which extend the idea of &lt;a href=&#34;https://mathinsight.org/parametrized_curve_introduction&#34;&gt;parametrized curves&lt;/a&gt; (fancy terms for bézier curves) to vector-valued functions of two variables—from my understanding this basically means a 3D non straight surface.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Walking at angles</title>
      <link>https://shortdiv.com/posts/walking-at-angles/</link>
      <pubDate>Mon, 02 Dec 2019 21:45:21 -0600</pubDate>
      <guid>https://shortdiv.com/posts/walking-at-angles/</guid>
      <description>&lt;h1 id=&#34;walking-at-angles&#34;&gt;Walking at angles&lt;/h1&gt;
&lt;p&gt;When drawing in 3D and even in 2D, we rely on shapes to make up a larger geometry, which then go on to form a more complex scene. This may seem rather straightforward but to a machine the task of drawing shapes could not be more complicated. This is largely because most machines only know how to render triangles. Take the humble square. Ordinarily, a square is drawn from point to point around the perimeter of the square, so in the figure below we’d draw a square from 1 → 2 → 3 → 4. From a computer’s perspective however, drawing a square would go 1 → 2 → 4 → 3.&lt;/p&gt;</description>
    </item>
    <item>
      <title>A Cube in 3d</title>
      <link>https://shortdiv.com/posts/a-cube-in-3d/</link>
      <pubDate>Sun, 01 Dec 2019 22:50:16 -0600</pubDate>
      <guid>https://shortdiv.com/posts/a-cube-in-3d/</guid>
      <description>&lt;p&gt;Because we’re starting from the basics, this week we’ll focus largely on shapes and rendering shapes to the screen. This task may seem trivial but I assure you there’s a lot happening to occupy a week’s worth of content. To keep things simple, we’ll create our 3D images using ThreeJS, a JS library that abstracts a lot of the complexities of WebGL so you can write graphics with the power of JavaScript!&lt;/p&gt;</description>
    </item>
    <item>
      <title>3December</title>
      <link>https://shortdiv.com/posts/3december/</link>
      <pubDate>Sun, 01 Dec 2019 22:43:20 -0600</pubDate>
      <guid>https://shortdiv.com/posts/3december/</guid>
      <description>&lt;p&gt;At the start of 2018, I got the opportunity to be part of the first mini batch at the Recurse Center. Recurse Center is a self-directed, community-driven programming retreat in NYC aimed at attracting programmers who want to grow their programming chops in a rigorous yet, supportive environment. Students who attend Recurse generally come in with a dedicated project focus. This helps with setting a course and creating a clear purpose through the course of the term, which lasts anywhere between 1 week and six months. During my time at Recurse, which lasted one week (hence mini), I focused on ramping up on WebGL. While 1 week was far too short to get anywhere near mastery, it did give me the space and time to navigate the vastness of core WebGL concepts and chart a semblance of a path to eventual mastery. If you’re curious about this and my learnings from my rather short stint there, check out &lt;a href=&#34;https://github.com/shortdiv/recurse-minis&#34;&gt;my musings over on Github&lt;/a&gt; as well as &lt;a href=&#34;https://github.com/shortdiv/webglolz&#34;&gt;my experiments with WebGL/GLSL&lt;/a&gt;—the furthest I got was rotating a triangle.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Geocoding Data</title>
      <link>https://shortdiv.com/posts/geocoding-data/</link>
      <pubDate>Thu, 28 Feb 2019 23:17:54 -0600</pubDate>
      <guid>https://shortdiv.com/posts/geocoding-data/</guid>
      <description>&lt;p&gt;A key step in the data visualization process is the conversion of data to the right format. When working with geospatial related information in particular, data needs to be in &lt;a href=&#34;http://geojson.org/&#34;&gt;geoJSON&lt;/a&gt; to be accurately superimposed onto a map. In many instances, geospatial data available via Open Data Portals like data.gov is already in a proper format to be mapped. However, there are times when the available data needs to be cleaned and/or transformed into a more appropriate format to be useable. For example, physical address data needs to be converted to coordinates so they can be properly added to a map. In cases like these, data formatters specifically known as geocoders come in handy.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Redirect Rulez</title>
      <link>https://shortdiv.com/posts/redirect-rulez/</link>
      <pubDate>Mon, 07 Jan 2019 22:33:18 -0600</pubDate>
      <guid>https://shortdiv.com/posts/redirect-rulez/</guid>
      <description>&lt;h1 id=&#34;redirect-rulez&#34;&gt;Redirect Rulez&lt;/h1&gt;
&lt;p&gt;Browsers rely on URLs to access content on the web. One way to think about URLs is as a giant phone book for the web. When a browser wants access to a specific resource, it looks it up in the “phone book” and makes a request for it by visiting the address specified. However, like physical addresses, virtual addresses are not permanent and are subject to change. When a person moves irl, they often file a change of address at the local post office so that mail gets routed appropriately. Changing addresses on the web can be similarly achieved using redirect rules.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Predictive Web Performance</title>
      <link>https://shortdiv.com/posts/predictive-web-performance/</link>
      <pubDate>Thu, 03 Jan 2019 22:20:36 -0600</pubDate>
      <guid>https://shortdiv.com/posts/predictive-web-performance/</guid>
      <description>&lt;p&gt;Some of the most cutting edge and effective web performance optimizations, like prefetch and preconnect, involve being proactive. We make predictions to determine where a user is likely to go next and load resources ahead of time so page load is as fast as possible. While there is somewhat of a science to making these predictions, thanks to analytics tracking and extensive user testing, they are still largely manual. Making an accurate prediction therefore becomes progressively more difficult as your site scales since there’s no sure way of knowing where a user will go next. This is where machine learning comes in handy. By training a machine learning model (maybe a markov chain?) with current analytics data, we can take the guess work our of our predictions and more accurately load resources ahead of time. There’s currently ongoing development to make techniques such as this more accessible to web developers. A project worth checking out is called GuessJS, which serves as a landing page for all libraries and tools that enable Machine Learning driven user-experiences on the web. The convergence of machine learning and web performance is still in its infancy. However, with the growing popularity of machine learning (especially among web developers), it&amp;rsquo;s only a matter of time when techniques like predictive prefetching will become more commonplace on the web.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Myth of &#39;It&#39;s Just Javascript&#39;</title>
      <link>https://shortdiv.com/posts/the-myth-of-its-just-javascript/</link>
      <pubDate>Wed, 02 Jan 2019 19:55:34 -0600</pubDate>
      <guid>https://shortdiv.com/posts/the-myth-of-its-just-javascript/</guid>
      <description>&lt;p&gt;If you’ve spent some time in frontend land, chances are you’ve heard someone say “it’s just javascript” when referencing a framework, library or snazzy new tool. While the phrase has an element of truth in it—a framework like React compiles down to JavaScript for instance—it often betrays the full picture. For one, a frontend framework like React or Ember often involves complex-ish tooling, templating systems, and high level architectural decisions around state management, and routing. Saying something is “just JavaScript” creates a culture of shaming and heightens the (already fairly high) barrier to entry for newer developers. It also paradoxically &amp;ldquo;cheapens” the work of practising JavaScript developers by making it seem like their work is trivial. Quite like the oft-misquoted phrase “A jack of all trades is a master of none”*, let’s stop popularizing the half truth that things are “Just JavaScript”. Instead, let’s do the frontend world some justice and express our work with a more nuanced approach that takes into account the chaotic albeit robust ecosystem that we’ve worked so hard to build. Maybe this way we can start having more meaningful, and productive conversations without delving into yet another pithy argument over who or what framework/tool/library is better.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Components Rule Everything Around Me</title>
      <link>https://shortdiv.com/posts/components-rule-everything-around-me/</link>
      <pubDate>Tue, 01 Jan 2019 21:51:14 -0600</pubDate>
      <guid>https://shortdiv.com/posts/components-rule-everything-around-me/</guid>
      <description>&lt;p&gt;Componentization is the central concept driving frontend development today. It enables us to encapsulate core logic of a user interface into smaller chunks thereby making them easier to reason about. While each of these components exist in isolation, they work in concert to build a unified interface. This relative isolation also means that components are reusable and can be easily mixed and matched to create a variety of patterns and styles. An example that best illustrates this is the screwdriver. Though there are many types of screwdrivers, like the phillips head, the flat head, the allen head and so on, these variations can be made by simply changing the head of the screw instead of having to buy multiple single use screwdrivers. By enabling a high level of isolation, components thereby promote ownership while also maintaining the right conditions to efficiently scale.&lt;/p&gt;</description>
    </item>
    <item>
      <title>2018 in Review</title>
      <link>https://shortdiv.com/posts/2018-in-review/</link>
      <pubDate>Mon, 31 Dec 2018 19:48:50 -0600</pubDate>
      <guid>https://shortdiv.com/posts/2018-in-review/</guid>
      <description>&lt;p&gt;With 2018 drawing to a close, I&amp;rsquo;d like to take a moment to review some of my personal highlights from the past year.&lt;/p&gt;
&lt;h2 id=&#34;attended-recurse-center&#34;&gt;Attended Recurse Center&lt;/h2&gt;
&lt;p&gt;2018 was by far the first time that I hit the ground running at the start of the year. I successfully matriculated(?) at the Recurse Center in their first ever mini retreat and spent a full week in January learning and building alongside a bunch of incredibly smart, talented recursers. My project for the week was to ramp up on WebGL and gain (pseudo) proficiency in working with shaders. While I managed to &lt;a href=&#34;https://github.com/shortdiv/webglolz&#34;&gt;somewhat accomplish this&lt;/a&gt;, I also spent a good chunk of time pairing on other recurser projects that ranged from building compilers to writing functional code in haskell. The week was wonderful, albeit a tad exhausting and I hope to return again sometime soon.&lt;/p&gt;</description>
    </item>
    <item>
      <title>All Eyes on Wasm</title>
      <link>https://shortdiv.com/posts/all-eyes-on-wasm/</link>
      <pubDate>Mon, 24 Dec 2018 11:31:15 -0600</pubDate>
      <guid>https://shortdiv.com/posts/all-eyes-on-wasm/</guid>
      <description>&lt;p&gt;If you’ve been keeping up with the JavaScripts, chances are you’ve heard snatches of excitement about the latest and greatest in web technology, WebAssembly. WebAssembly is a binary executable for the web that promises near-native performance for web applications. This means that graphics heavy applications like Photoshop, and AutoCAD can now be run in the browser without the need for clunky third party plugins like Silverlight, Flash and Java Applets. Web Assembly effectively removes the notion that JavaScript is the de-facto assembly language of the Web and opens the door for other languages like C, and C++ to run on the web.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Through the (Magic) Window</title>
      <link>https://shortdiv.com/posts/through-the-magic-window/</link>
      <pubDate>Sun, 23 Dec 2018 10:49:36 -0600</pubDate>
      <guid>https://shortdiv.com/posts/through-the-magic-window/</guid>
      <description>&lt;p&gt;In the last few years, virtual reality (VR) and augmented reality (AR), also known as cross reality or XR, have developed far beyond the niche realms of the gaming industry. There are now compelling use cases for using XR for building applications focused on education (Aurasma, Math Alive), home improvement (Wayfair, Ikea Place) and even beauty (Meitu) that are accessible to the masses. Despite its growth in popularity, many XR applications today often require the installation of a separate mobile application. Snapchat lenses, and Instagram face filters for instance require using these applications to get the full XR experience. The reason developers lean on mobile when building XR is largely because mobile gives them more fine tuned control of native input controls compared to the web. To address this current handicap and to better bridge the gap between the virtual world and the web, browser vendors have teamed up to work on a XR focused web API termed WebXR.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Finding the Right Voice Ui</title>
      <link>https://shortdiv.com/posts/finding-the-right-voice-ui/</link>
      <pubDate>Sat, 22 Dec 2018 15:46:21 -0600</pubDate>
      <guid>https://shortdiv.com/posts/finding-the-right-voice-ui/</guid>
      <description>&lt;p&gt;One of the most memorable cinematic portrayals of a voice recognition system is Hal 9000, the seemingly omniscient computer from Stanley Kubrick’s 2001: A Space Odyssey. Hal captured our collective imaginations and opened our eyes to the possible future of a voice based human-computer interaction. Since the movie’s release in 1966, the landscape of voice recognition systems have changed drastically. According a study done by Adobe Analytics over 32% of US consumers own a smart speaker and that number is expected to increase nearly twofold by the end of the year. The emergence of integrated digital assistants like Amazon’s Alexa and Google’s Google Home has also meant that voice is now being used beyond just playing music and checking the weather forecast. With the increased reliance on voice as a medium of interacting with the web, designers and developers are now faced with a new challenge: designing interfaces optimized for voice-based interactions.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Allez AI A11y</title>
      <link>https://shortdiv.com/posts/allez-ai-a11y/</link>
      <pubDate>Fri, 21 Dec 2018 20:42:07 -0600</pubDate>
      <guid>https://shortdiv.com/posts/allez-ai-a11y/</guid>
      <description>&lt;p&gt;The task of building for accessibility, while worthwhile, can be a rather daunting one. Strategies to incorporate it into a product frequently involve a fair amount of work, much of which tends to be manual and admittedly, tedious. The web accessibility community has made many strides to improving this by making accessibility more &lt;em&gt;accessible&lt;/em&gt; for developers. In addition to the best practices and recommendations by WCAG, there are many automated tools that make implementing them a breeze. Recent advances in AI have contributed further improvements to this, such that is it now possible to build for accessibility with minimal effort. In addition to helping streamlining existing tasks like &lt;code&gt;alt-text&lt;/code&gt; generation, AI advances in areas such as natural language processing, machine learning and image processing have opened up new possibilities in the world of accessibility online.&lt;/p&gt;</description>
    </item>
    <item>
      <title>A Picture Is Worth the Thousand Words</title>
      <link>https://shortdiv.com/posts/a-picture-is-worth-the-thousand-words/</link>
      <pubDate>Thu, 20 Dec 2018 18:25:13 -0600</pubDate>
      <guid>https://shortdiv.com/posts/a-picture-is-worth-the-thousand-words/</guid>
      <description>&lt;p&gt;For most of us, the web is a magical world of media rich content like images, gifs and most importantly, cat videos. Images, however humorous, are the primary means of maintaining user engagement online. Unfortunately, for many users with disabilities and/or other impairments, this rich visual heavy experience of the web remains inaccessible. Assistive devices like screen readers and refreshable braille displays can only interpret text and rely on developers adding &lt;code&gt;alt-text&lt;/code&gt; or captions to make sense of images. Though this type of content is hard to parse, low vision users should not be predisposed to a text only web experience. For one, not all low vision users are blind. Many, like sighted users, can benefit from the added semantic meaning that images and video provide. As a result, as developers it is important to account for the range of abilities and adjust our media content appropriately.&lt;/p&gt;</description>
    </item>
    <item>
      <title>AOM at Me Bro, I&#39;ve seen the future of a11y</title>
      <link>https://shortdiv.com/posts/aom-at-me-bro/</link>
      <pubDate>Wed, 19 Dec 2018 17:33:19 -0600</pubDate>
      <guid>https://shortdiv.com/posts/aom-at-me-bro/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://shortdiv.com/posts/aria-ready/&#34;&gt;Earlier this week&lt;/a&gt;, we briefly examined the concept of an accessibility tree, which represents the information model—much like the DOM—that assistive devices use to parse and make sense of a webpage. Unlike the DOM tree which can be queried and modified after the fact via JavaScript APIs, the accessibility tree can only be queried but not modified by assistive technologies. In an increasingly JavaScript heavy web ecosystem, input events like click and hover drive interactivity. Interactions are tailor made to suit specific input controls, so a hover event may open up help text, while changing focus states by clicking away may trigger form validation. These specific mappings between input controls and actions add a layer of fine grained control to the overall user experience. While alternate input controls have access to similar interactions, they still have to rely on DOM updates since they is no way to directly access the accessibility tree.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Client Side A11y</title>
      <link>https://shortdiv.com/posts/client-side-a11y/</link>
      <pubDate>Tue, 18 Dec 2018 20:22:14 -0600</pubDate>
      <guid>https://shortdiv.com/posts/client-side-a11y/</guid>
      <description>&lt;p&gt;With the rise in popularity of client side, JavaScript frameworks like React, Vue and Angular, it is undeniable that JavaScript is eating the web. This increased reliance on JavaScript isn’t necessarily a bad thing. JavaScript enables us to add interactivity to a page and thereby create more engaging user experiences online. It has also helped address many performance issues with its solutions relating to lazy load and client-side routing via the history API. JavaScript however, is also a notorious cause of many accessibility issues. For instance, client side routing while enabling navigation without a full page reload, &lt;a href=&#34;https://medium.com/@robdel12/single-page-apps-routers-are-broken-255daa310cf&#34;&gt;doesn’t get picked up accurately by screen readers&lt;/a&gt;. In addition, click and hover only events make apps virtually unusable for keyboard only users. To better understand the role of JavaScript with regards to these accessibility issues, let’s more closely examine how assistive devices are used to navigate the web.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Superstylin With A11y in Mind</title>
      <link>https://shortdiv.com/posts/superstylin-with-a11y-in-mind/</link>
      <pubDate>Mon, 17 Dec 2018 20:26:28 -0600</pubDate>
      <guid>https://shortdiv.com/posts/superstylin-with-a11y-in-mind/</guid>
      <description>&lt;p&gt;When building for the web and making considerations for accessibility, it is easy to fall into the trap of assuming that accessible features only benefit disabled users. While disabled users positively benefit from accessibly designed interfaces, there are many other reasons why a user may similarly leverage keyboard shortcuts or specialized software to navigate websites. For instance, an otherwise able-bodied user may be forced to use assistive technologies as a result of an injury or a recent surgery that make it difficult to navigate a website as they ordinarily would. A user may also choose to use such assistive technologies purely out of personal preference because it allows them to navigate a site quickly and efficiently. It is therefore important for us as developers to build online experiences that don’t discriminate against how a website is accessed.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Aria Ready</title>
      <link>https://shortdiv.com/posts/aria-ready/</link>
      <pubDate>Sun, 16 Dec 2018 21:32:16 -0600</pubDate>
      <guid>https://shortdiv.com/posts/aria-ready/</guid>
      <description>&lt;p&gt;As a user without disabilities, I often take for granted the experience of using the web. Browsing and interacting with the web often involves reading visual cues to decipher the general purpose of a particular element. For one, sighted users of the web know that the (now infamous) hamburger icon that sits at the top left of the screen is representative of a clickable menu item. Such assumptions and relationships that we make between icons and their meaning are largely a result of context clues. We understand that a hamburger icon is a menu item because of its placement in the top navigation bar, which we use to “navigate” a webpage. For visually impaired users, such clues may go completely unnoticed depending on how a screen reader interprets a webpage. This is especially the case when elements are given no additional meaning that can be deciphered and prioritized by a screen reader (i.e. a button is just a button to a screen reader even if it is styled to be a menu button). This is where ARIA comes in.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Be a Better A11y</title>
      <link>https://shortdiv.com/posts/be-a-better-a11y/</link>
      <pubDate>Sat, 15 Dec 2018 10:00:41 -0600</pubDate>
      <guid>https://shortdiv.com/posts/be-a-better-a11y/</guid>
      <description>&lt;h1 id=&#34;being-a-better-a11y&#34;&gt;Being a better A11Y&lt;/h1&gt;
&lt;p&gt;It’s almost impossible to think of the world without the web. Compared to other inventions of yore, the web is the single most powerful medium of communication. Through its promise of openness, freedom and independence, the web levelled the playing field. It gave everyone the chance to transcend the limitations of their physical condition regardless of their level of ability. In spite of this promise of inclusivity, the web&amp;rsquo;s potential as a &amp;ldquo;global community&amp;rdquo; was never truly realized. Most of the internet today is a maelstrom of inaccessible iframes, popups and captionless gifs that are near impossible to parse via a screen reader or the tab key.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Don&#39;t Skip Out on PE</title>
      <link>https://shortdiv.com/posts/dont-skip-out-on-pe/</link>
      <pubDate>Fri, 14 Dec 2018 17:20:33 -0600</pubDate>
      <guid>https://shortdiv.com/posts/dont-skip-out-on-pe/</guid>
      <description>&lt;p&gt;This week, I focused on the many aspects of PWAs and their role in making the web experience more streamlined across browsers and devices. Inherent to PWAs is the concept of progressive enhancement. To the untrained eye, progressive enhancement might seem akin to the concept of “it works without JavaScript”. While this is kinda sorta true (a well built PWA should work with JS turned off 🤞🏾), progressive enhancement is more about using web technologies in a so-called “layered” fashion. This technique of building apps makes them adaptable and allows them to run seamlessly regardless of bandwidth, network connectivity or software. In short, Progressive Enhancement is the deliberate strategy of building apps on the foundation of making it usable everywhere.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Errwhere PWA; bridging the mobile and desktop experience</title>
      <link>https://shortdiv.com/posts/errwhere-pwa/</link>
      <pubDate>Thu, 13 Dec 2018 18:20:20 -0600</pubDate>
      <guid>https://shortdiv.com/posts/errwhere-pwa/</guid>
      <description>&lt;p&gt;In the latest stable build of Chrome, came support for desktop progressive web apps (PWAs). Similar to mobile PWAs, desktop PWAs allow users to install apps onto a device’s home screen for quick and easy access. In addition to this, they allow web apps leverage to the numerous capabilities of modern web APIs like authentication, payments and so on, without having to worry about potential security vulnerabilities. After all, a desktop PWA is basically a web browser running in its own app window context.&lt;/p&gt;</description>
    </item>
    <item>
      <title>When Push Comes to Shove</title>
      <link>https://shortdiv.com/posts/when-push-comes-to-shove/</link>
      <pubDate>Wed, 12 Dec 2018 19:36:20 -0600</pubDate>
      <guid>https://shortdiv.com/posts/when-push-comes-to-shove/</guid>
      <description>&lt;p&gt;Push notifications are a simple way in which web applications can interact with users to provide them with timely updates and customized content. When integrated with service workers, push notifications allow web applications a more active and engaging experience that was previously reserved for mobile applications. Technically speaking, this feature is possible thanks to the Push API.&lt;/p&gt;
&lt;p&gt;The Push API is what allows web applications to receive messages from the server, regardless of whether an application or a user agent is active. This API effectively gives developers control over delivering asynchronous notifications and updates to users who have opted in. In theory—if done right—push notifications allow for higher engagement. However, most of the time push notifications are disruptive to user experience. In a sense, push notifications have come to represent the web equivalent of that annoying sales person who hovers over your shoulder as you browse. Even browsers—&lt;a href=&#34;https://support.mozilla.org/en-US/kb/push-notifications-firefox#w_how-do-i-disable-web-push-completely&#34;&gt;I see you firefox&lt;/a&gt;—have taken to rolling out user settings so you can disable push notifications completely. With this poor sentiment around push, how can we effectively leverage them without being an annoyance to users?&lt;/p&gt;</description>
    </item>
    <item>
      <title>The (not so) secret life of service workers</title>
      <link>https://shortdiv.com/posts/the-not-so-secret-life-of-service-workers/</link>
      <pubDate>Tue, 11 Dec 2018 18:58:05 -0600</pubDate>
      <guid>https://shortdiv.com/posts/the-not-so-secret-life-of-service-workers/</guid>
      <description>&lt;p&gt;Service workers are an important player in the PWA game. Not only are they handy for keeping applications functional while offline, they are also instrumental when it comes to improving overall page load time. Working with a service worker however can be a little tricky. Because they are run in the background of a page (outside of a page’s render cycle) and are registered only once, service workers don’t always work as expected. Contrary to how we normally build and debug for the web, service workers don’t update when the file is updated and the page is refreshed. Depending on your use case, reflecting changes made to a service worker may require either closing the browser tab, refreshing the page or navigating to another page. The reason for this behavior is that the service workers are bound to a specific lifecycle that predetermines whether and how they gain control of the document. The lifecycle of a service worker can be one of the most confusing if not frustrating aspects of working with a service worker. Even so, understanding this lifecycle is the key to unlocking the possibilities that service workers provide.&lt;/p&gt;</description>
    </item>
    <item>
      <title>If it&#39;s not online does it exist</title>
      <link>https://shortdiv.com/posts/if-its-not-online-does-it-exist/</link>
      <pubDate>Mon, 10 Dec 2018 17:45:35 -0600</pubDate>
      <guid>https://shortdiv.com/posts/if-its-not-online-does-it-exist/</guid>
      <description>&lt;p&gt;Offline storage is the linchpin of progressive enhancement. Under a low or unreliable network connection, the app is not dependent on a successful response from the server to be operational. Instead, it reads and writes data from a local in browser database while in offline mode. There are several ways to serve data offline. Picking the right option for your PWA ultimately depends on the type of data you’re intending to store and how big it is.&lt;/p&gt;</description>
    </item>
    <item>
      <title>At Your Service Worker</title>
      <link>https://shortdiv.com/posts/at-your-service-worker/</link>
      <pubDate>Sun, 09 Dec 2018 20:43:10 -0600</pubDate>
      <guid>https://shortdiv.com/posts/at-your-service-worker/</guid>
      <description>&lt;p&gt;Network connectivity is a single point of failure when it comes to user experience on the web. By nature of the web’s reliance on the network, the web fails when the network b0rks. Inadvertently as developers, this means that we’re always at the mercy of network connectivity. When faced with a slow or failed network connection, there is no way for us to help websites gracefully fail. While connectivity is an issue for most mobile web applications because of the reliance on the network, native mobile apps are able to deliver an offline user experience that is on par with an online one. This is largely because native mobile apps are built on the premise of “offline first”, where users are sent cached resources even before the app makes a connection to the server.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Leveraging the Mobile Web</title>
      <link>https://shortdiv.com/posts/leveraging-the-mobile-web/</link>
      <pubDate>Sat, 08 Dec 2018 18:45:24 -0600</pubDate>
      <guid>https://shortdiv.com/posts/leveraging-the-mobile-web/</guid>
      <description>&lt;p&gt;Last week, we identified the trend that a large and growing number of users are accessing the web via mobile devices. With this trend in mind, we covered various strategies to building websites that load fast and seamlessly without discriminating based on a user’s bandwidth and/or connectivity. From a performance standpoint, lightning fast websites translate to lower bounce rates and an overall more satisfactory user experience. In spite of this, however, the performance of a webpage, no matter how amazing, plays only a partial role when it comes to user engagement. According to a study done by Google comparing the top 1000 native mobile apps vs. top 1000 mobile web apps, it was discovered that while the mobile web saw close to 4 times the number of unique visitors than native apps, the time users spent on the mobile web was only 5% of the time spent on native apps (yikes!).&lt;/p&gt;</description>
    </item>
    <item>
      <title>Compression Makes Matters Light</title>
      <link>https://shortdiv.com/posts/compression-makes-matters-light/</link>
      <pubDate>Fri, 07 Dec 2018 18:56:43 -0600</pubDate>
      <guid>https://shortdiv.com/posts/compression-makes-matters-light/</guid>
      <description>A dive into compression algorithms available when building for the web</description>
    </item>
    <item>
      <title>Http2; the Magic Elixir of Performance</title>
      <link>https://shortdiv.com/posts/http2-the-magic-elixir-of-performance/</link>
      <pubDate>Thu, 06 Dec 2018 22:51:36 -0600</pubDate>
      <guid>https://shortdiv.com/posts/http2-the-magic-elixir-of-performance/</guid>
      <description>Though we as developers can influence how the browser downloads resources, the browser ultimately gets the last say when it comes to the order in which to load content. In this post, we dive into the new and exciting features that HTTP/2 brings.</description>
    </item>
    <item>
      <title>Dont Be Such a Render Block</title>
      <link>https://shortdiv.com/posts/dont-be-such-a-render-block/</link>
      <pubDate>Wed, 05 Dec 2018 19:02:43 -0600</pubDate>
      <guid>https://shortdiv.com/posts/dont-be-such-a-render-block/</guid>
      <description>&lt;p&gt;In previous posts, we talked about optimizing our websites to reduce page weight and inadvertently decrease overall page load time. This page load metric, though incredibly important, doesn’t fully take into account the user’s perception of a websites’ performance. At the very least, a user’s goal when visiting a website is to view the page content. As a result, they are more likely attuned to the time it takes for a page to be viewable (&lt;a href=&#34;https://www.quora.com/What-does-First-Meaningful-Paint-mean-in-Web-Performance&#34;&gt;first meaningful paint&lt;/a&gt;) or usable (time to interactive) rather than on the time it takes for the entire page to load (page load time). Optimizing for render performance requires a sound understanding of the steps the browser takes when going from initial page request to rendering pixels to the screen.&lt;/p&gt;</description>
    </item>
    <item>
      <title>If You Can Read This Fonts Work</title>
      <link>https://shortdiv.com/posts/if-you-can-read-this-fonts-work/</link>
      <pubDate>Tue, 04 Dec 2018 19:15:38 -0600</pubDate>
      <guid>https://shortdiv.com/posts/if-you-can-read-this-fonts-work/</guid>
      <description>High performance web fonts.</description>
    </item>
    <item>
      <title>Video Killed the Web Performance Star</title>
      <link>https://shortdiv.com/posts/video-killed-the-web-performance-star/</link>
      <pubDate>Mon, 03 Dec 2018 21:06:38 -0600</pubDate>
      <guid>https://shortdiv.com/posts/video-killed-the-web-performance-star/</guid>
      <description>&lt;p&gt;Video is one of the most sought out mediums on the web and is used widely in web page designs today. &lt;a href=&#34;https://www.cisco.com/c/en/us/solutions/collateral/service-provider/visual-networking-index-vni/white-paper-c11-741490.html&#34;&gt;According to a Cisco report&lt;/a&gt;, video constitutes the majority of the world’s internet traffic. In 2017, video was reported to have constituted 75% of all internet traffic and this number is slated to surpass 80% by 2022. This should come as no surprise to most of use, considering the fact that video content is a powerful medium for visual communication and offers a great way to keep users engaged. Adding video to websites however, can oftentimes be a double-edged sword; We may make some gains via a richer, more delightful user experience but risk performance issues if our websites are not optimized appropriately. This, alongside the rapid growth of traffic originating from mobile and wireless connections means we as developers are increasingly responsible for optimizing our sites for performance. In this post, we’ll dive into video optimization strategies so we can reap the benefits video provides without driving users away.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Images Are Worth Optimizing For</title>
      <link>https://shortdiv.com/posts/images-are-worth-optimizing-for/</link>
      <pubDate>Sun, 02 Dec 2018 21:05:54 -0600</pubDate>
      <guid>https://shortdiv.com/posts/images-are-worth-optimizing-for/</guid>
      <description>&lt;p&gt;Images make up a large portion of a webpage’s payload. According to the HTTP Archive, the average image size has grown almost twofold and now constitute a whopping 63% of total bytes of a webpage. This growth in images on the web has coincided with faster network speeds and growing bandwidth; meaning that loading webpages today has never been faster— for some of us. High network latencies and low bandwidth (mostly over mobile connections) is unfortunately commonplace for a large percentage of the world. This means incredibly slow webpage load times and an increasingly frustrating experience browsing webpages. While doing away with images altogether would theoretically solve the problem of slow page load—removing all images from the top 1,000 websites, these sites would load 30% faster on average over 3G (high performance images)—a text only webpage would significantly hamper user engagement. Thankfully, there are many tricks to optimizing images for the web so we don’t have to skimp on the overall design and user experience of a webpage.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Weighing in on Page Weight</title>
      <link>https://shortdiv.com/posts/weighing-in-on-page-weight/</link>
      <pubDate>Sat, 01 Dec 2018 21:38:21 -0600</pubDate>
      <guid>https://shortdiv.com/posts/weighing-in-on-page-weight/</guid>
      <description>&lt;p&gt;Early on in my career, when web performance metrics were brought up in conversation, I would take how others reacted to the number as a cue to understanding what those numbers meant (read: I had no idea what those numbers meant). A high number elicited shock and horror, while a low number drew admiration and praise. This could only mean, high page weight bad, low page weight good. Though my naïveté around web performance at the time was a result of my overall lack of experience, it did highlight a point worth considering; the concept of a “page weight” is somewhat of a confusing term especially when seen in isolation.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Testing With Custom Matchers in Vue</title>
      <link>https://shortdiv.com/posts/testing-with-custom-matchers/</link>
      <pubDate>Sat, 26 May 2018 15:32:23 -0500</pubDate>
      <guid>https://shortdiv.com/posts/testing-with-custom-matchers/</guid>
      <description>Techniques for writing custom matchers with various popular testing libraries.</description>
    </item>
    <item>
      <title>Old to New; Contexts in React 16.3</title>
      <link>https://shortdiv.com/posts/react-16.3-context-api/</link>
      <pubDate>Sun, 01 Apr 2018 14:18:15 -0500</pubDate>
      <guid>https://shortdiv.com/posts/react-16.3-context-api/</guid>
      <description>&lt;p&gt;A couple of days ago, React 16.3 was released. The update brought with it many changes, including an official (recommended for use) Context API that replaces the old (not recommended for use) Context API, a &lt;code&gt;createRef&lt;/code&gt; API, and a &lt;code&gt;forwardRef&lt;/code&gt; API to name a few. Among the changes introduced in React 16.3, I most anticipated the change to the Context API.&lt;/p&gt;
&lt;h2 id=&#34;adding-context-to-context&#34;&gt;Adding Context to &lt;code&gt;Context&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;For those of you unfamiliar with the concept, &lt;code&gt;context&lt;/code&gt; is a technique in React used to pass data down from parent to child without having to rely on props. Passing data via props is a common pattern used in React to give children access to parent data. While declarative, passing props can be unnecessarily verbose as it requires passing state explicitly down through the tree. If a child needed access to a grandparent component, the state would have to be passed to every intermediate component regardless of whether or not that component needs access to that data property. React&amp;rsquo;s context feature offers you the ability to pass state down while bypassing intermediary components.&lt;/p&gt;</description>
    </item>
    <item>
      <title>An Ode to Vue</title>
      <link>https://shortdiv.com/posts/an-ode-to-vue/</link>
      <pubDate>Sun, 18 Feb 2018 15:12:39 -0600</pubDate>
      <guid>https://shortdiv.com/posts/an-ode-to-vue/</guid>
      <description>&lt;p&gt;A couple of months ago, I made the switch from React to Vue. I had been playing around with Vue for a bit before making the switch and was impressed by how lightweight, and versatile Vue was. Compared to my initial experience learning React (👋 JSX), picking up Vue felt like a breeze. Not only is Vue very well documented, it is also very straighforward and doesn&amp;rsquo;t require a lot of initial set up to get started. If you&amp;rsquo;ve been considering using Vue in your next project, here are a few of the reasons I think you should use Vue:&lt;/p&gt;</description>
    </item>
    <item>
      <title>New-ish Year, New-ish Blog</title>
      <link>https://shortdiv.com/posts/first-post-of-the-year/</link>
      <pubDate>Sat, 03 Feb 2018 13:08:04 -0600</pubDate>
      <guid>https://shortdiv.com/posts/first-post-of-the-year/</guid>
      <description>First post of the year</description>
    </item>
  </channel>
</rss>
