<![CDATA[Ash Furrow's Blog]]> https://ashfurrow.com en <![CDATA[Five Years in New Brunswick]]> https://ashfurrow.com/blog/five-years-in-new-brunswick/ Fri, 31 Oct 2025 00:00:00 GMT https://ashfurrow.com/blog/five-years-in-new-brunswick/ <p>Today marks five years since my wife and I moved away from New York and back to New Brunswick. <a href="https://ashfurrow.com/blog/four-years-in-new-brunswick/">When I wrote about this last time</a>, I seemed unhappy. I guess things hadn't worked out the way that I had envisioned them when we moved home – even if I didn't have a really clear vision for how things would go. I have a more optimistic view now.</p> <p>About a year ago, <a href="https://photos.ashfurrow.com/downtown-in-the-rain">I started taking photos again</a>. It started on my phone, but then I got out my old film cameras which <em>still had film in them from New York</em>. I finished the rolls and sent them off to be developed. When they came back, I found this:</p> <div class="wide"> <p><img src="https://ashfurrow.com/blog/five-years-in-new-brunswick/photo.jpg" alt="Double-exposure photo with New York on the left and Fredericton on the right" /></p> </div> <p>This is a double exposuree, with half the frame being taken in New York and the other half being taken here in Fredericton. <em>Five years apart!</em> From what I can piece together, what happened is:</p> <ol> <li>I took a photo in New York.</li> <li>Five years pass.</li> <li>At some point, the &quot;double exposure&quot; lever on my camera was activated.</li> <li>I advanced only halfway to the next frame.</li> <li>I took another photo in Fredericton.</li> </ol> <p>That's what I've pieced together, because this was not what I intended when I took either photo. One of the last photos I took in New York, and one of the first photos I took in Fredericton. <em>This was not what I envisioned.</em> (I also have <em>no idea</em> why one of the photos was taken <em>upside down!</em> What!?)</p> <p>Something I love about film photography – and digital, too – is the unexpected. In photography, you see a scene and you pre-visualize the shot, and then you try to realize your photographic vision. But unexpected things happen. And I think <em>good</em> photographers are open to that spontaneity. You can't always faithfully execute on your vision, but you can choose to work with whatever happens.</p> <p>In this case, I've <em>edited</em> the photo to look good. Without those edits, the original was kind of bleh:</p> <div class="wide"> <p><img src="https://ashfurrow.com/blog/five-years-in-new-brunswick/original.jpg" alt="The same photo, but less contrasty and not cropped. I looks faded." /></p> </div> <p>This is not what I envisioned, but I love what I made of it. This is probably my favourite photo that I've ever taken <em>ever</em>, and it was an accident.</p> <p>Things haven't gone the way I intended when I moved home, but that's okay. Part of being human is accepting the spontaneity of life and making something beautiful with it.</p> <![CDATA[Joining Wealthsimple]]> https://ashfurrow.com/blog/joining-wealthsimple/ Tue, 14 Oct 2025 00:00:00 GMT https://ashfurrow.com/blog/joining-wealthsimple/ <p>I'm excited to announce that today is my first day working at <a href="https://www.wealthsimple.com/">Wealthsimple</a>! I'll be working as a staff developer on their mobile app. <a href="https://ashfurrow.com/blog/floating-on/">In a previous blog post</a>, I teased that this role was a perfect fit for me. Today, I'm excited to share some details.</p> <p>But first we need some context and a little background on React Native.</p> <hr /> <p>I started working with React Native at Artsy. <a href="https://artsy.github.io/blog/2016/08/15/React-Native-at-Artsy/">Orta and Eloy were keen on adopting it in 2016</a>, but I was very skeptical. So skeptical, in fact, that I found myself working on non-mobile Artsy projects. That's when I learned React on the web, and <a href="https://ashfurrow.com/blog/the-case-for-react-native/">that's when I came around to React Native</a>. I got on board with the vision that the two of them had started building. I started contributing to that vision and eventually I worked up to <a href="https://artsy.github.io/blog/2020/09/29/becoming-mobile-first-at-artsy/">leading the team that owned the whole app</a>.</p> <p>One of the foundational principles that Orta and Eloy had established was that Artsy wouldn't use React Native where it led to a worse user experience; we'd use React Native only <em>where it made sense</em>, and use native iOS tech where <em>it</em> made sense. Our goal was to create a great app, and React Native couldn't do that on its own. As a concrete example, the navigation stack itself was still in Objective-C (while the view controllers were slowly migrated to React Native).</p> <p>That was (gosh) nearly a decade ago. React Native itself has gotten <em>much</em> better, especially as tools like <a href="https://expo.dev/">Expo</a> have taken off. It's now easy for developers to access underlying native SDKs from JavaScript (like photo pickers, Spotlight integration, even augmented reality). But! There still remains a &quot;last mile&quot; in React Native, where native technologies <em>must</em> be used <em>directly</em> in order to build the best user experience. In 2016, maybe you could get 70% to a great UX in React Native alone. By 2020, maybe that had reached 90%. Today, maybe it's around 95%, or so? But I don't believe it will ever reach 100% for two reasons.</p> <p>First is the platform vendors themselves. Apple and Google develop their own SDKs for building apps and would prefer you to use them. Now, React Native <em>uses</em> those SDKs under the hood, but React Native itself doesn't fit in certain restrictive runtimes. Take widgets, for example. Or push notification extensions, or smartwatch apps, or any number of the small-but-deeply-integrated features that elevate an app from <em>good</em> to <em>great</em>. (Even where it's <em>possible</em> to fit a React Native runtime into these environments, you might not actually want to. I helped a team at Shopify build an <a href="https://developer.apple.com/documentation/appclip">App Clip</a> in React Native; App Clips needed to archive down to under 10MB and fitting inside that constraint was a huge challenge. While the project was a technical success, the user experience wasn't great.)</p> <p>Second is the irreducible complexity of a cross-platform development tool like React Native. This kind of tool needs to work across all kinds of platforms while not <em>feeling</em> like a &quot;lowest common denominator.&quot; The React Native project itself has made a lot of improvements here over the years. In case you weren't aware, please let me blow your mind: there is now synchronous, two-way interoperability between React Native's JavaScript runtime and native code. JavaScript can now communicate <em>directly</em> with native code through object references 🤯 This has come a long way since React Native's original, asynchronous bridge where all communication was serialized over JSON. This advancement has led to huge performance gains that close the distance on that last mile – even if it can't close it entirely.</p> <p>However. This fancy <a href="https://reactnative.dev/architecture/landing-page">new architecture</a> comes with added complexity. You don't get end-to-end type-safe memory access between TypeScript and native runtimes without <em>at least a little bit</em> of C++. Any app developer who's serious about delivering the <em>highest-possible quality mobile user experience</em> will need to dive under React Native's JavaScript exterior and work in the underlying native stack, in C++, Swift, Kotlin... whatever it takes.</p> <p>That's where I come in.</p> <p>It's very rare to find a developer who is comfortable in <em>both</em> React Native <em>and</em> the underlying native SDKs. Mobile native developers tend to avoid React Native. On the other side, React Native developers tend to want to stay in JavaScript, avoiding native tech. There are exceptionally few developers out there with deep enough experience with native iOS that they could still write manual-retain-release Objective-C <em>and</em> who have extensive experience building React Native applications in JavaScript. <em>And</em> who enjoy working in both.</p> <p>What I have to offer is an unbiased perspective. (Or at least, a less biased one.) Someone to help make the right decision for the product, whether it's native or React Native. Someone who is confident contributing at any level of the stack. And someone to help scale up a larger team with those same skills. I can't wait!</p> <hr /> <p>My new role will have a narrower focus with more day-to-day coding and <a href="https://ashfurrow.com/blog/work-at-your-spikes/">I'm expecting a greater career satisfaction</a>. I've learned that I <em>can</em> do anything, but if I try to do <em>everything</em>, then my work suffers. I suffer. It's time to specialize in mobile UX again.</p> <div class="narrow"> <p><img src="https://ashfurrow.com/blog/joining-wealthsimple/wwdc2010.jpg" alt="Photo of (a younger) me at WWDC 2010." /></p> </div> <p>I'm also <em>really</em> excited to be working in native technologies more often. I've followed every WWDC since I attended my first in 2010, but if I'm being completely honest, it's been hard to feel as immersed as I used to in Apple technology without working in native iOS day-to-day. My Swift skills are a little rusty and my SwiftUI skills... well, let's just say that I'm looking forward to sparring with Xcode again. In some ways, this will be a return to native iOS for me. But I'm not &quot;going back&quot;, I'm using my experience to go forward.</p> <div class="narrow"> <p><img src="https://ashfurrow.com/blog/joining-wealthsimple/mdevcamp.jpg" alt="Photo of (a less younger) me speaking at mDevCamp." /></p> </div> <p>I'm really looking forward to ramping up with Wealthsimple. They have a great product for an underserved Canadian market. <a href="https://www.wealthsimple.com/en-ca/culture">Their stated culture</a> describes the exact kind of environment where I can do my best work. Also, I've opened personal bank accounts in three countries so I also get to bring my experience banking in the US and Europe. When I moved home to Canada, I was surprised to see how little the big banks had changed in the seven years I lived away. Wealthsimple is pushing Canada forward here. They've built a quality app and have already done a lot to cover that last mile of React Native user experience – I can't wait to pitch in!</p> <![CDATA[Eleventy Launch]]> https://ashfurrow.com/blog/eleventy-launch/ Wed, 08 Oct 2025 00:00:00 GMT https://ashfurrow.com/blog/eleventy-launch/ <p><a href="https://ashfurrow.com/blog/yet-another-blog-rewrite/">As I discussed previously</a>, I've been rewriting this blog in a new tool called <a href="https://www.11ty.dev/">11ty</a> (aka Eleventy - the project's devs aren't consistent so I won't be either). <em>This</em> is the first blog post written in the new blog engine, and the migration is complete!</p> <p>I already mentioned my reasons for migrating off of Gatsby, but it's worth repeating <em>how much less complex</em> an 11ty implementation is. Gatsby's complexity led to long build times, which started exceeding Netlify's (free tier) deploy timeout. On my M2 MacBook Air, you can see a <strong>16x speedup on fresh builds</strong>:</p> <pre><code># Gatsby yarn build 329.83s user 28.18s system 257% cpu 2:19.14 total # Eleventy yarn build 57.01s user 4.42s system 387% cpu 15.863 total </code></pre> <p>I had let the project sit on the back burner for a while but <a href="https://ashfurrow.com/blog/floating-on/">recent events</a> have led me to have spare time to finish it. One of my first priorities was to get Netlify deploy previews working again, which was a great call. This helped me test end-to-end and verify that I would get back continuous (one of the goals of this project). To fully deploy the site from Netlify takes about a minute.</p> <p>Side note: I don't want to beat up on Gatsby but it's also clear that it hasn't been a good fit. Gatsby is great for complex sites with dynamic content, but <em>this</em> site is a static blog with hundreds of posts. My precious posts! When testing the build times, I saw the following warning:</p> <pre><code>Your GraphQL query in createPages took 28.522 seconds which is an unexpectedly long time. See https://gatsby.dev/create-pages-performance for tips on how to improve this. </code></pre> <p>Huh! Okay maybe the performance problems are on <em>my</em> side of the keyboard after all! Maybe I'm holding Gatsby wrong. I examined the query in question, and laughed out loud.</p> <pre class="language-graphql"><code class="language-graphql"><span class="token punctuation">{</span> <span class="token property-query">allMdx</span><span class="token punctuation">(</span><span class="token attr-name">sort</span><span class="token punctuation">:</span> <span class="token punctuation">{</span> <span class="token attr-name">order</span><span class="token punctuation">:</span> <span class="token constant">DESC</span><span class="token punctuation">,</span> <span class="token attr-name">fields</span><span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token property">frontmatter___date</span><span class="token punctuation">,</span> <span class="token property">frontmatter___title</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token object">edges</span> <span class="token punctuation">{</span> <span class="token object">node</span> <span class="token punctuation">{</span> <span class="token property-query">excerpt</span><span class="token punctuation">(</span><span class="token attr-name">pruneLength</span><span class="token punctuation">:</span> <span class="token number">250</span><span class="token punctuation">)</span> <span class="token property">body</span> <span class="token property">id</span> <span class="token object">frontmatter</span> <span class="token punctuation">{</span> <span class="token property">date</span> <span class="token property">title</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token object">siteSearchIndex</span> <span class="token punctuation">{</span> <span class="token property">index</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre> <p>All it's doing is querying blog posts, which are <em>just text</em>. Even the search index is <em>just processing text</em>. It's all just text! So I'm putting the blame here on Gatsby. I'm left wondering who this tool is for? Gatsby can't scale to <em>under a thousand text files</em> so it's not a good fit for a simple static site. Do you need something more complex? Then you probably want more than a static site, anyway.</p> <p>Counting lines of code isn't a perfect way to measure complexity, but in this case I think it's helpful for comparing the two implementations. Remember that Gatsby is a React site generated from Markdown using GraphQL with lots of other bells and whistles; more complex but more expressive. The 11ty implementation uses plain HTML, CSS, and JavaScript; simpler but more verbose.</p> <pre><code># Gatsby cloc --exclude-dir=node_modules,public,.netlify,blog,.cache, ------------------------------------------------------------------------------- Language files blank comment code ------------------------------------------------------------------------------- TypeScript 50 259 52 3143 Markdown 6 112 0 616 JavaScript 2 9 19 207 JSON 3 0 0 155 CSS 1 19 10 111 SVG 6 0 3 93 Text 2 13 0 61 diff 1 2 28 24 TOML 1 0 0 4 ------------------------------------------------------------------------------- SUM: 72 414 112 4414 ------------------------------------------------------------------------------- # 11ty cloc --exclude-dir=node_modules,public,.netlify,.husky --not-match-d=&quot;blog|fontawesome&quot; . ------------------------------------------------------------------------------- Language files blank comment code ------------------------------------------------------------------------------- CSS 7 86 54 1589 Nunjucks 17 76 17 1239 JavaScript 10 96 124 619 Markdown 5 86 0 179 Text 2 13 0 61 SVG 3 0 3 48 JSON 3 0 0 47 TOML 1 0 0 4 ------------------------------------------------------------------------------- SUM: 48 357 198 3786 ------------------------------------------------------------------------------- </code></pre> <p>Despite being less expressive, 11ty is still the &quot;smaller&quot; implementation. Which makes sense, since <em>you don't need GraphQL to render markdown into HTML</em>. In any case, I remain impressed at how much can be accomplished using only what we was once called &quot;Dynamic HTML.&quot; Gatsby's implementation used 24 dependencies (which get shipped to users reading the blog) and just as many build-time Gatsby plugins. 11ty used only <em>three</em> user dependencies and <em>four</em> build-time plugins. <code>package.json</code> has gone from 118 lines down to just 39.</p> <p>You might be asking about using plain JavaScript instead of TypeScript. I'm generally in favour of TypeScript, but you don't need to have a full build pipeline to benefit from it. In this project, TypeScript only helps with local development, it doesn't really prevent user-facing bugs. I don't think the tradeoff is worth it, so instead I used JSDoc comments to add types where I though they would help. Everything is a tradeoff, and I wanted the biggest benefit for the smallest complexity. That's why I wrote my own <code>groupBy</code> instead of using lodash.</p> <p>Overall, implementing the new site went smoothly with one exception. The thing that furstrated me the most was <a href="https://www.11ty.dev/docs/plugins/image/">11ty's Image plugin</a>. This is the most (only?) opinionated part of 11ty's stack. The project clearly wants developers to use new HTML features (like image source sets) to provide multiple resolutions of an image so browsers can choose the best one to display. That makes sense, and Gatsby actually does something similar (albeit using JavaScript). But I just couldn't really wrap my head around the plugin, it kept getting in my way. And due to <s>me being a stubborn ass</s> some hard constraints of my directory structure, I couldn't <em>not</em> use it.</p> <p>Eventually, I figured it out. Actually it was quite easy, once I started <em>actually using my brain</em>. I had been fighting the Image plugin by proxy, with Claude Code. This is probably a good time to talk about AI.</p> <p>I mentiond in the last post that Claude Code had accelerated this project. I think it's fair to say I would not have gotten this done if Claude Code hadn't automated some of the most tedious work. But Claude Code was <em>awful</em> at the start of the project; only when I completed the initial project setup myself was it helpful. Maybe I just needed the context to prompt it, but I didn't have that context without building the foundation. Near the end of the project, Claude Code became similarly frustrating, especially as I fought with the Image plugin. Once I <s>lost access to my former employer's Claude Code account</s> decided to valiantly complete the project on my own terms, it became a lot easier. I had to fully read the docs to understand what the Image plugin was trying to accomplish. Half an hour of using my brain was more rewarding and succesful than fighting with Claude Code.</p> <p>In summary, <em>AI tools seem most useful in the middle of a project</em>. I needed to give them a solid foundation to start from. Simiarly, at the end of the project, they could not polish work to my satisfaction. I think it's also helpful to be able to maintain this project <em>without</em> using AI tools; call me old fashioned, but <em>I want to understand the code</em>. I want to be able to maintain this project even if <s>the AI bubble bursts</s> my internet connection goes down.</p> <p><a href="https://github.com/ashfurrow/blog/pull/520">You can review the pull request here</a> for insights into my process (ignore the lines-of-code count, as prettier formatted thes blog posts once they were migrated from MDX to markdown).</p> <p>I've taken pains to make sure the RSS feeds still work as expected, but I always worry about changes that might affect my favourite readers, the RSS nerds. If you see any problems, anywhere on the site, <a href="https://github.com/ashfurrow/blog/issues/new">please open an issue</a>.</p> <![CDATA[Work At Your Spikes]]> https://ashfurrow.com/blog/work-at-your-spikes/ Mon, 06 Oct 2025 00:00:00 GMT https://ashfurrow.com/blog/work-at-your-spikes/ <p>I want to discuss my career trajectory and a chronic issue I've identified with my job satisfaction since becoming a staff developer. It's been subtle and I didn't notice it for years. Maybe this will resonate with you.</p> <p>After a lot of reflection, I've identified a trend in my career direction that started when I first led Artsy's new Mobile Experience team in 2019. It was the perfect role for me, and I <em>crushed</em> it. But it also set me on a path where I would feel unfulfilled with my work. This trend that I've identified has followed me from Artsy to Shopify to Float. But now that I've identified it, I've got a better understanding of where I want my career to go next.</p> <p>The trend is not working at my &quot;spikes&quot;, doing more and more work that is only &quot;okay.&quot; Basically, the amount of my day-to-day time that's spent on tasks that aren't a distinguishing strength of mine.</p> <h2>Spikiness</h2> <p>&quot;Spiky&quot; people (also sometimes called &quot;<a href="https://en.wikipedia.org/wiki/T-shaped_skills">T-Shaped</a>&quot; people) refers to people who have <em>specific</em> areas of professional skill and experience. I'm spiky in mobile UX implementation, for example. Spikes are deep and narrow. Spiky people tend to have gaps, though. These are areas where they have neither the need or interest to improve. One of my gaps is low-level database optimization; it just doesn't interest me and I've never needed to learn it.</p> <p><img src="https://ashfurrow.com/blog/work-at-your-spikes/spiky.svg" alt="A star shape with big spikes and a small centre." /></p> <p>You can think of a spiky person as a contrast to a well-rounded person. These two ideas are at either ends of a gamut – no one is &quot;only spiky&quot; or &quot;only well-rounded.&quot; But it's a helpful metaphor for professional growth. Spiky people have gaps that well-rounded people don't have, but spiky people can have an outsized impact in their areas of expertise. So it's a tradeoff.</p> <p><img src="https://ashfurrow.com/blog/work-at-your-spikes/compared.svg" alt="Diagram comparing the same spiky star shape from above with another star shape. The new one is labelled &quot;well-rounded&quot; and its peaks are smaller than the spiky shape, but it's area is greater because it's centre is larger; it has fewer gaps." /></p> <p>I like being spiky. My spikes have helped me stand out and get opportunities that a more well-rounded version of myself wouldn't get. I prefer to <em>manage</em> my gaps rather than fill them in because filling them in would smooth down my spikes. After all, there is only so much time in a day and you have to choose where to spend your time and energy.</p> <p>Everything has an opportunity cost. Filling in my gaps would mean less time spent getting <em>even better</em> at my spikes. My spikes are also where my interests lie, so doing work in my gaps is already less interesting. Which would help me more? Spending time getting better at mobile UX implementation, or spending time getting better at low-level database optimization?</p> <p>There are tradeoffs to being spiky, of course. For example, I <em>need</em> a team to do my best work. Working solo, I can do a <em>good</em> job; working in a team where I can rely on and support others, I can do a <em>great</em> job. I like to work with other spiky people because we help mitigate each other's gaps. A team with a lot of spiky people can accomplish more than a team of generalists, in my experience.</p> <p>The thing is, though, I haven't been working at my spikes. For a while, I've been generalizing. <a href="https://ashfurrow.com/blog/perspective-of-the-polyglot/">I've written about how it's good and fun to branch out</a>, and it is! This is not a post <em>against</em> generalizing. But it's about the consequences and tradeoffs. (Spoilers: <a href="https://ashfurrow.com/blog/specializing-in-being-a-generalist/">I've also written about stretching myself out too thin</a>.) I've caught myself accepting that I was a generalist now. I accepted that I wouldn't get to do as much deep work at my spikes – mobile UX implementation – because there were <em>so many other things</em> that my job demanded needed me to do instead.</p> <p>Side note: a lot of staff/principal developers struggle with letting go of <em>coding</em> as their primary responsibility. At a certain level of seniority, your time is better spent helping your <em>whole team</em> be productive than it is spent on your own productivity. I (and many peers) do struggle with decoupling a sense of accomplishment from a number of pull requests or features built. But this is something different. Because I (and many peers) do find ways to be fulfilled by technical leadership work.</p> <p>The root of my issue is that I've allowed the needs of my employers to guide my career growth too much. I've become whatever the business needs me to be at the time. To be clear, this has been a successful career! From the business' perspective, it's <em>really</em> handy to have a staff-level mobile developer who can design UI themselves, who can manage their own projects, who can deploy their own microservices, who can even build their own dashboards! That kind of person can jump into any environment and be effective. Businesses love that.</p> <p>Consider that the Shop Minis SDK that I built didn't have an actual product manager for the first year of its existence. It was just me, organizing the small team of engineers and whatever design capacity we could borrow. Without many resources, I got <em>a lot</em> accomplished. The project was a success even without a PM.</p> <p>Those other skills, though – design, project management, backend, dashboards – they are not my spikes. I can do them, but... so, uh, the thing is my dashboards are not... exceptional, okay? They're fine, they're good. Dashboards are not a <em>gap</em> for me like database optimization, but they're not a spike either. They sit in-between.</p> <p><img src="https://ashfurrow.com/blog/work-at-your-spikes/detailed.svg" alt="A zoomed-in view of the spiky diagram, with three dots along one of the edges. The dot in the gap is labelled &quot;database optimization&quot;, the dot at the spike is labelled &quot;mobile UX&quot;, and the dot in between is labelled &quot;dashboards.&quot;" /></p> <p>I don't like making dashboards. I find the task tedious. And yet, I've spent more and more time on dashboards over the years. I've had to, to be an effective leader in my different roles. I now have enough &quot;experience in dashboards&quot; that I could credibly list it as a skill on my resume. Ugh.</p> <p>Upon reflection, I've found myself working further and further away from my spikes in a lot of different ways (not just dashboards). I'm doing many types of work not because I excel in those areas, but because <em>I can be effective working across many areas</em>. And <em>that</em> has been what my employers have needed. When I <em>do</em> get to work at my spikes, my work has still been of high enough quality that I can still get a lot of job satisfaction. The tradeoff has worked for me. Also, it feels <em>amazing</em> to be &quot;the fixer&quot; who can parachute in and help any team do any thing.</p> <p>But this trend has picked up and the balance has been broken. It led me to not really enjoy my work like I used to. This affected my motivation and the quality of my work.</p> <p>So what happened?</p> <h3>Early Stage Companies</h3> <p>There are a lot of things I enjoy about working for early-stage startups and one of the my favourite aspects is how you get to own a broad domain. To &quot;wear a lot of hats&quot;, so to speak. If you see a problem or opportunity, you get to own the solution. There actually aren't a lot of resources in early companies, so being able to handle a broad range of responsibilities is <em>really important to being successful</em> at a startup.</p> <p>However, such a resource-constrained setting can make it challenging to advocate for resources you <em>do</em> need. I can understand the business' perspective here: why allocate scarce resources to a team who's already so effective without them? There is a great reason, actually. Artsy's CTO <a href="https://code.dblock.org/about/">dB</a> once explained to me how startups need more and more engineers year-over-year <em>just to keep shipping at the same velocity</em>. As you build the product, its surface area grows which increases complexity and risk, which require more engineer time to manage. Not every company understands this.</p> <p>Over time (especially if you don't get more resources as your own surface area grows) you can easily become overstretched. You can get used to being overstretched, spending <em>so little</em> of your time working at your spikes that the time you <em>do</em> get to feels... almost like a chore? Work you once loved can feel like obstacle to doing the work your team needs... like building dashboards. You can lose your own sense of accomplishment and the sense of shared accomplishment that comes from enabling others.</p> <p>As your motivation drops, the quality of your work drops too. If you a person who is motivated by doing great work, this can easily become a self-reinforcing cycle where lowered quality leads to less motivation and even worse quality. The whole time, you feel worse and worse.</p> <h3>AI and the Push Towards Average</h3> <p>The other factor that accelerated my mid-career malaise was AI. LLM tools have had an impact on baseline expectations for many, many roles in the past few years. They let you &quot;do more with less.&quot; It's now pretty easy for <em>anyone</em> to make dashboards almost as good as mine! <em>Despite my years of experience!</em></p> <p>It's honestly really frustrating to me. Infuriating! I'm enraged! What is even the point?? If <em>anyone</em> can &quot;vibe chart&quot; then <em>why</em> the fuck am <em>I</em> doing it? AI tools have lifted up the &quot;floor&quot; of dashboard skills which has, in effect, brought me down closer to average. Average! Me! No way.</p> <p>Now, you could push back here and suggest that maybe <em>I</em> need to use the AI tools to become better at dashboards. Either improve the quality of the dashboards, or build them faster, or whatever. And that would be a fair pushback except <em>I already didn't want to be doing dashboards.</em> It's one of many skills that I picked up because various employers needed me to. Using AI to get better at dashboards would just be filling in my gaps ✨ but with AI ✨ and <em>still</em> at the expense of my spikes.</p> <p>(Besides, if I'm going to use AI tools to improve my skills, then why not use them at my spikes?)</p> <h2>Mid-Career Slump</h2> <p>I'm really glad that I specialized in mobile software so early in my career. It's been fun and rewarding. I'm also glad that I branched out a few years in. Being able to fit into whatever shape a business needs has been very lucrative. The problem is that I've spent the past six years fitting into other shapes that I've lost a connection to my own intrinsic shape.</p> <p>It feels a little ironic to end up back where I started, specializing again. But I'm not really &quot;back&quot; here because I'm not the same person I was in 2019.</p> <p><img src="https://ashfurrow.com/blog/work-at-your-spikes/meme.jpg" alt="The &quot;bell curve&quot; meme where the beginner and expert have the same opinion of &quot;it's good to specialize&quot; with the middle person saying &quot;nooooo u need generalized skills&quot;" /></p> <p>I'll offer some advice for software developers, advice I wish I had gotten sooner: specialize at first for a jump-start, then generalize quickly after that to accelerate your career. But re-specialize again as <em>soon</em> as possible. Once you become &quot;general enough&quot; to specialize again, do it. Do it <em>before</em> you feel ready.</p> <p>One of my best skills is being able to discern the most important thing I need to do for a business at any given time, and I've always prioritized the business need. Putting the business first is a great way to get rewarded, but I'm not working <em>just</em> to collect a paycheque. I want to do great work! I'm lucky enough to <em>get</em> to pursue a fulfilling career, so it's time to prioritize my own satisfaction. It's time to find a role where the business' needs overlap with my own.</p> <p>My hope is to use this reflection like a gravity assist, <em>approaching</em> a career as a generalist before spectacularly sling-shotting away towards a more specialized, more fulfilling career. Gravity assists are famously difficult courses to plot – you have to work backwards from the destination. My destination has been my mobile UX spike.</p> <p>I've found my next role in a larger organization where I'll have a narrower focus. I'll have an announcement about where I'm going soon. In my new role, I'll get to leverage my expertise as a specialist again. Fewer dashboards, more mobile UI implementation. Less average, more spiky. And hopefully, a happier me.</p> <![CDATA[Floating On]]> https://ashfurrow.com/blog/floating-on/ Fri, 26 Sep 2025 00:00:00 GMT https://ashfurrow.com/blog/floating-on/ <p>It's with mixed emotions that I'm announcing today is my last day working at <a href="https://floatfinancial.com/">Float</a>. I've accomplished a lot here and I'm grateful for the opportunity to help shape such a young company and product team. I'm sad to say goodbye to my coworkers and I wish everyone the best.</p> <p>Whatever job I'm in, I always learn something – that's just how I practice product development. But I was surprised by how much I learned <em>about myself</em> at Float. I've worked in early-stage startups before and so I <em>thought</em> I had an idea of what to expect. There were two curve balls I didn't anticipate.</p> <p>The first is Float's distinct ferocity: <em>everyone</em> at the company cares deeply about Float's success. They work harder than anyone to earn customers' business, to fight for their market position. I care a lot about my work, so a company full of other people who care about <em>their</em> work was a perfect fit for me. The unexpected part was the intensity. Float is the most ferocious company I have ever worked for. While I'm proud of how I rose to that challenge, I also learned where some of my own limits are.</p> <p>The other difference is me. <em>I'm</em> different. At other startups I've joined, my role was (at first) to build apps. I grew into leadership positions, but Float was my first time I <em>joined</em> an early company <em>as a leader</em>. That brought a whole new set of challenges. I worked more closely with company leadership, I learned more about the business than I had at other startups, and I exercised my autonomy appropriately. That's a lot of extra context to absorb and execute on.</p> <p>I'm proud of my accomplishments here, as both a technical leader and as an organizational leader. Building an app from scratch is always a lot of fun, and the team I led launched the app <em>only 99 days after our initial commit!</em> Scaling a mobile app within a product organization is always an interesting challenge, and I led the Float mobile app to get contributors from <em>every</em> product team. Being part of a high-growth engineering team is always thrilling, and I've successfully modelled my practice of product development through curiosity and empathy. I joined Float to build a great app, and customers have said the app is their favourite part of Float's product. What a compliment! I'm proud of what I've done and how I've done it.</p> <p>Failure has always been my greatest teacher. Float is a company where you cannot succeed without taking risks and making mistakes, and I've been successful enough here to have made some of my most interesting mistakes. I'm proud of those mistakes. I treasure them.</p> <p>Deciding to leave a company is never easy for me, and particularly so with Float. It's a unique company and I'm sure it will continue to make waves. I wish Float and my coworkers well.</p> <p>I keep a small box of what I call &quot;captain's trinkets.&quot; Picard had his flute, Sisko had his baseball, and Freeman had her flag of the California Republic. In my office, I keep a small collection of objects that symbolize meaningful times of my career. Float's first product was in corporate credit cards so I feel it's appropriate to retire my own Float card to the captain's trinkets box.</p> <p><img src="https://ashfurrow.com/blog/floating-on/trinkets.jpeg" alt="A box with old Artsy business cards, a UNB keychain, a Series 0 Apple Watch, an old passport, and other items." /></p> <p>I have an exciting new opportunity that I'm starting after some time off. When I've described the role to people who've worked with me, they've nodded and said something along the lines of &quot;oh yeah, that sounds perfect for you.&quot; I'm excited to share more. Until then, take care!</p> <![CDATA[Yet Another Blog Rewrite]]> https://ashfurrow.com/blog/yet-another-blog-rewrite/ Tue, 26 Aug 2025 00:00:00 GMT https://ashfurrow.com/blog/yet-another-blog-rewrite/ <p><a href="https://ashfurrow.com/blog/gatsby-for-great-good/">In 2019, I rewrote this blog with Gatsby</a>. I outlined my reasons in that post, but basically I wanted to use similar technology to build my blog as I used day-to-day at work. Middleman, Bootstrap, and jQuery seemed old and busted. Gatsby, React, and TypeScript seemed so much more fun.</p> <p>When I launched the rewrite, someone on social media cautioned me &quot;I hope you don't regret this.&quot; At the time, I resented it. But unfortunately I do regret the decision.</p> <p>Gatsby is large, cumbersome, and slow. Its dependencies constantly change. It breaks under the weight of my many posts, to the point that Netlify is no longer able to build the site without a timeout.</p> <p>It turns out, you don't need GraphQL to turn markdown into markup.</p> <p>I looked into going back, to Middleman, but the dependencies are just so outdated and the code <em>is</em> pretty janky, that it made more sense to move forward, to something new.</p> <p>I chose <a href="https://www.11ty.dev/">11ty</a>, which is a JavaScript-based static site generator with a focus on simplicity and API stability. I wrote the old blog in 2014 using Bootstrap and jQuery, with a CSS preprocessor; the progress of browser standards means I don't need any of that anymore. (CSS Grids are amazing!)</p> <p>Now, 11ty doesn't really do as much as Gatsby. But I value the simplicity of maintainence over the Gatsby's promises of client-side performance. My blog just doesn't need the powerful features that Gatsby can provide.</p> <p>All I have to do is port the existing GraphQL implementation. Or, should I port the Middleman implementation? Why not both!</p> <p>So yeah. I'm using Claude Code for this project, and it's gone really well. It turns out AI coding assistants are really great at porting code between languages. I pointed Claude Code at the Gatsby and Middleman implementations, and have worked through an implementation plan piece by piece. This was actually a great project for me to really dive into the capabilities of agentic coding tools, since this is a project I've built twice before.</p> <p>I am concerned about code quality, especially plain CSS. AI is great at spewing out a lot of hard-to-maintain-code, and that seems extra true with CSS. To mitigate this, I'm running an experiment. I threw a weekend or two at the project two months ago to get it about 90% complete. Then, I just let it sit there. I wanted to forget the code so I can revisit it later, to dispassionately evaluate it without the thrill of &quot;getting so much done with AI&quot; clouding my judgement.</p> <p>But honestly, the main site is only 1000 lines of CSS. That's for a fully responsive design. And I'm not that great at CSS, so the bar that Claude has to clear is pretty low. I've actually learned quite a bit about web standards, scrutinizing the code that Claude had spit out.</p> <p>Unlike previous rewrites, I'm blogging about this one ahead of time. <a href="https://github.com/ashfurrow/blog/pull/520">The pull request is here</a>, if you're interested. GitHub's UI shows this as a massive increase in lines of code, only because Prettier formatted seven hundred markdown posts for the first time. I'll have exact numbers once I've finished, but 11ty has a lot less configuration and coding to accomplish the same task. My entire site builds locally in about ten seconds, compared with minutes on Gatsby.</p> <p>I still have a ways to go. The PR has an open task list, but it's mostly &quot;feature complete.&quot; Next steps are things like making sure the RSS feeds' permalinks match, validating the HTML and CSS, and testing. I know that the last twenty percent of a project tends to be eighty percent of the effort, but again, I've done this a few times before so I have a pretty good idea of what I'm doing.</p> <p>I just hope I don't regret this.</p> <![CDATA[The Murderbot Blog]]> https://ashfurrow.com/blog/the-murderbot-blog/ Tue, 12 Aug 2025 00:00:00 GMT https://ashfurrow.com/blog/the-murderbot-blog/ <p>I've been a huge fan of <a href="https://en.wikipedia.org/wiki/The_Murderbot_Diaries"><em>The Murderbot Diaries</em> series by Martha Wells</a> for a few years now, and was very excited to see it adapted to television on Apple TV+. Every adaptation of a story to a new medium has to make creative choices and tradeoffs; it's fun to pick apart the work to identify what's been changed, think about why that might have been done, and examine the impact on the story.</p> <p>As a fan of the books, I'm thrilled to see them adapted <em>at all</em> and I don't want anyone thinking that I dislike the show. It was a joy to see <em>The Rise and Fall of Sanctuary Moon</em> show-within-a-show come to life.</p> <p>This is an ensemble show, based on a single-person narrative novella. That was always going to be hard to adapt, so it makes sense that the production uses an ensemble cast to tell a larger story. More points of view makes it easier to tell a more complete story, and gives the audience more characters to relate to. But <em>too many</em> characters can create confusion, too. The show combined a few characters together and rearranged some of the relationships, to keep the story focused.</p> <p>So we have this ensemble cast telling a story from multiple perspectives, adapted from a very first-person limited-perspective book. The tradeoff here is that you get less time with the titular protagonist, who is admittedly a weirdo. It could be difficult for audiences to relate to SecUnit, especially in a visual format.</p> <p>These changes from the source material seem motivated to me, and so I find it easy to accept them and have fun with the story. Even as I wish we could spent more time with the inner life of SecUnit, I understand how that would be very difficult to portray.</p> <p>The story itself also had to be adapted to fit into ten episodes. This change was less effectively executed than the character changes, in my opinion. The pacing of the show would speed up and slow down so quickly that it felt kind of clumsy. Life-or-death action scenes would be punctuated by relationship drama. The seams of the adaptation were visible.</p> <p>The television show also nerfed the characters. This was a bummer, honestly. The human characters and SecUnit all make poor decisions and get themselves into unnecessary trouble. And I kind of see why. It's hard to tell a compelling story when all the characters are hyper-competent (that's part of why <em>Star Trek Voyager</em> is the way it is). Having the characters make mistakes also allows for more a more dynamic story, making it easier to adapt to television. This was harder for me to roll with, but I see the utility in it from a production and storytelling perspective.</p> <p>I've given these examples as a way to show that <em>motivated changes</em> can lead to a story that works better for a television audience, even as I (a fan) would have preferred something different. I'm not saying that the motivation is good or bad, or that the motivation makes the changes good or bad. I'm saying that I understand it, so I find it easy to roll with as a viewer.</p> <p>But there was one story shift that I don't understand that's been bothering me.</p> <p>In the books, sprawling corporations fight each other for power and control of a lot of human-occupied space called the Corporation Rim. It's a place ruled by contracts and force. The Corporation Rim is home to multigenerational indentured labour contracts, massive amounts of suffering, and wanton death – all for the sake of profit.</p> <p>Our humans, in the Preservation Alliance, exist outside the Corporation Rim. But they do interact with it, and it disgusts them. This is a key thing I love about the books: Preservation Alliance is depicted as an <em>actual, functioning utopia</em>. The planetary alliance has built a society where everyone has access to food and shelter, where menial labour has been automated, and where violent crime does not exist.</p> <p>By depicting Preservation Alliance this way, the books implicitly show that the cruelty and suffering of the Corporation Rim <em>is a choice</em>. It is optional. Something that our human characters avoid.</p> <p>So it really bothered me when the television adaptation depicted Preservation Alliance as so hapless and resource-starved that they were considering joining the Corporation Rim. I don't understand the motivation behind it. Granted, it's a <em>relatively minor</em> change that <em>doesn't necessarily</em> contradict anything in the books. But it does contradicts the story in my head. This was one of the most important background details of the setting to me and it kind of hurt to see it thrown away.</p> <p>Adaptations and creators don't owe anyone explanations about the story choices they make. But if I ever got the chance to ask the show runners a question, I know what I would ask.</p> <![CDATA[Bias Towards Helpfulness]]> https://ashfurrow.com/blog/bias-towards-helpfulness/ Mon, 23 Jun 2025 00:00:00 GMT https://ashfurrow.com/blog/bias-towards-helpfulness/ <p>I've been using Cursor for coding tasks lately, trying to explore what kinds of work it performs well and poorly. It's pretty good at most simple tasks. It's good-to-okay at some complicated tasks. But then, some simple tasks can stump it – usually in very niche domains. Other tasks are <em>so big</em> that they need to be broken into smaller pieces first – a classic project management problem.</p> <p>I ran into this last kind of problem recently, when I tried to prototype a large idea for this blog, my personal website. I told Cursor what we're doing and it started strong. It was making great progress when suddenly it got stuck, in a loop, on a <em>very</em> simple change to a config file.</p> <p>My approach had been too much, too fast. To refine my approach, I tried using a conversational LLM instead of Cursor. I've generally not used conversational LLMs like ChatGPT until a few months ago, because I hadn't found them to be that useful and because it's rational to be skeptical of tech hype. But people <em>are</em> using them, for all kinds of things. Conversational LLMs are replacing search, in terms of user behaviour. I had heard of developers using them to help think through ideas and plans, so why not try?</p> <p>I talked my idea through with the LLM and... it was actually pretty helpful! It was a bit like &quot;rubber duck debugging&quot; if the rubber duck could answer you. And lookup GitHub issues, and quote documentation, etc. I was pretty impressed. It validated my idea was a good idea and suggested some alternatives.</p> <p>The next day, I was meeting another developer for a coffee and my idea came up in our conversation. I explained my idea, asked his opinion, and the <em>first</em> thing he said <em>didn't answer my question at all</em>. Instead, he responded with a question of his own. (A <em>really good</em> question, too. Incisive.) I gave him my answer, and he asked a very good followup question: how much time was I interested in spending on this idea? Only when he understood the full context and my motivation did he give me his perspective.</p> <p>Conversational AI's have a <em>bias towards helpfulness</em>. That may sound absurd, but it's true: LLMs have been trained on helpful conversations from the internet (StackOverflow, for example). LLMs are given system prompts instructing them to answer user questions. They &quot;want&quot; to help us and it's important to be aware of that. This bias prevents LLMs from being able to distinguish prompts that are vague on purpose (users looking for general answers) and vague incidentally (users needing followup questions and/or pushback). LLMs are designed to help users <em>by answering their prompts</em>, not telling them when they're trying to do something really stupid.</p> <p>It's as though LLMs are bound by a local maxima of helpfulness. Sure, they're helping users with their requests. But they can easily, silently fail to consider the bigger picture. People are messy and they have messy problems.</p> <p>The developer I spoke to had the experience, expertise, and relationship with me to cut straight to the heart of my question. I hadn't meant this as an experiment, but it's interesting to think about: when asked the same question, the LLM responded with an answer but the developer responded with a question of his own. I think this is another case of learning what tasks an LLM can help with, or rather, learning the limitations of using an LLM for this kind of task.</p> <p>I want to clarify my stance here because I don't want to be labelled as either a hater or a booster. (Or labelled at all, thanks.) LLMs <em>do</em> have limitations, they <em>have</em> improved, and I <em>am</em> open to the idea that an LLM could be built that is capable of this kind of intentional, selective <em>un</em>helpfulness. To ask clarifying questions or push back on bad ideas. That an LLM product could even use previous interactions with me as context to tailor responses, similar to how a coworker or collaborator might. Indeed, <em>a lot</em> of companies are spending <em>a lot</em> of time and money trying to build AI assistants which develop a &quot;relationship&quot; with users. Maybe they will build something genuinely as helpful and incisive as another skilled human. But I would have to use it to believe it.</p> <p>Incidentally, both the developer and the LLM ultimately arrived at the same answer. But, the developer was better company.</p> <![CDATA[Foresight]]> https://ashfurrow.com/blog/foresight/ Sun, 22 Jun 2025 00:00:00 GMT https://ashfurrow.com/blog/foresight/ <p>Imagine you are a software developer. It's the early 1970's and you make a living writing Basic Assembly Language to build software for the System/360 mainframe. You are great at your job and you enjoy it.</p> <p>You keep hearing about new &quot;high level&quot; programming languages that would allow you to write code in a way that could be &quot;compiled&quot; to run on different kinds of computers. In theory, this would be a huge benefit over writing assembly for just one kind of computer. But there's a catch: these compilers aren't reliable. The code they produce has bugs that wouldn't have existed if a human had written the equivalent application in assembly. The code is inefficient, it is a mess to debug, and you have to use a whole new tool, a compiler.</p> <p>Compilers introduce a layer of abstraction. Another build step. Another cost. Another skill. Using a compiler would <em>mediate the work of programming</em>, alienating a programmer from both their craft and their labour. <strong>Compilers come with tradeoffs</strong>. You don't really like these tradeoffs, personally, and decide to stick with BAL.</p> <p>But you keep an eye on new compilers.</p> <p>Over time, compilers become more reliable, more stable, more performant. There are a lot of new languages and tools and it's hard for you to know which ones to invest time into learning. (We all remember what happened to PL/I, am I right?)</p> <p>You decide to learn a new language named C in your spare time.</p> <p>You have a long and prosperous career.</p> <p>The End.</p> <hr /> <p>Imagine you are a software developer who considers themselves to be a moral person. It's the early 1970's and you make a living writing Basic Assembly Language to build software for the System/360 mainframe. You are great at your job and you enjoy it.</p> <p>You keep hearing about new &quot;high level&quot; programming languages that would allow you to write code in a way that could be &quot;compiled&quot; to run on different kinds of computers. In theory, this would be a huge benefit over writing assembly for just one kind of computer.</p> <p>But there's a catch: <strong>these compilers are cursed</strong>.</p> <p>Compilers are conjured by programmers wearing dark cloaks, chanting under the cover of a new moon. It's an eldritch ceremony. No one <em>really</em> understands how a compiler works, other than... <em>the cost</em>. Every time a programmer compiles a program, <em>the cost</em> is extracted. Every time a programmer compiles a program, someone – somewhere – suffers. Someone suffers just a little bit, and the programmer doesn't get to see it.</p> <p>(Also compilers are slow, unreliable, hard to debug, etc. All the same tradeoffs readers are familiar with, they're just <em>also</em> cursed.)</p> <p><strong>Compilers come with tradeoffs</strong>. You don't really like these tradeoffs, personally, and decide to stick with BAL.</p> <p>But you keep an eye on new compilers.</p> <p>Over time, compilers become more reliable, more stable, more performant. The curse remains. You see the enormous value in using a compiler, you see how much more productive you could be if you used this tool.</p> <p>You try using one compiler, and it doesn't work. You wait a while, and you try another. A new one. It <em>does</em> work. In fact, it <em>exceeds your wildest expectations</em>. You feel conflicted.</p> <p>You consider yourself a moral person. You know about the curse. You see other programmers declining to make the switch, correctly pointing to the tradeoffs.</p> <p>&quot;Compilers aren't worth it,&quot; the other programmers assert. &quot;The curse is an unacceptable tradeoff! We refuse to use a compiler!&quot;</p> <p>But here's the thing. Programmers aren't the ones who get to decide what is worth the cost.</p> <p>You can see ahead. You see jobs writing assembly getting harder to come by. They don't <em>entirely</em> disappear, but... you see the industry moving on. You see an entire new generation of programmers entering the workforce who have <em>never not</em> used a compiler.</p> <p>You have bills to pay, a career to think about, and you can see ahead. And, these compilers are actually pretty fun and useful. You find yourself excited about all the cool things you could build with them.</p> <p>You still consider yourself a moral person. And you make a decision.</p> <![CDATA[Camera Time]]> https://ashfurrow.com/blog/camera-time/ Sat, 31 May 2025 00:00:00 GMT https://ashfurrow.com/blog/camera-time/ <p>Recently, I published <a href="https://photos.ashfurrow.com/downtown-in-the-rain">my first photo blog post since 2018</a>. (Yes I have a separate photo blog, because of course I do.) So what's up with that? Nothing better than a blog post about another blog post.</p> <p>I haven't really been doing a lot of photography since the pandemic, but I had been increasingly drawn to it over the past six months. Creativity is actually something I've found to be missing in my life – when I found a renewed interest in photography, I decided to follow it. I started taking more photos on my iPhone, then I got out my film cameras since that's what I <em>had</em> been mainly shooting. But film wasn't working for me, so I got out my digital camera, a FujiFilm X100S from 2014. And I loved it.</p> <p>But, that camera has some limitations I was hitting. First, it's a fixed focal length and I felt myself wanting something with more reach. I've only used prime lenses since 2014 and I enjoyed their limitations. Prime lenses helped me improve my composition skills, but now I'm ready for a zoom. The X100S is also from 2014, which means it's from near the <em>very beginning</em> of the industry's transition to mirrorless. So, it's fiddly.</p> <p>Don't get me wrong – I've taken some of my favourite shots with the X100S. I have a large canvas print of <a href="https://photos.ashfurrow.com/losing-myself-in-tokyo/photos/2580931">a long exposure of Tokyo taken from Roppongi Tower</a> hanging in my office, and I took that with the X100S. Back when I used to travel a lot, The X100S was exactly what I needed. But as I rediscover photography in Atlantic Canada, I started to feel its limitations. I kept shooting with it anyway.</p> <div class="wide"> <p><img src="https://ashfurrow.com/blog/camera-time/tokyo.jpg" alt="Photo of Tokyo just after sunset" /></p> </div> <p>I started looking around and realized that you can buy really nice used DSLRs for not that much. I had a sick DSLR kit and I daydreamed about recreating that same setup. But it felt weird to invest in a DSLR kit when they are on their way out. And in the decade since I bought my last digital camera, the X100S, mirrorless cameras have gotten really good. They have some distinct advantages over DSLRs.</p> <p>Mirrorless cameras are smaller and weigh less than DSLRs – and their lenses too. They often have a tilting LCD screen and I was interesting in using it as a waste-level viewfinder (like my TLR camera). And unlike DSLRs, mirrorless cameras can be adapted to work with my film lenses. My (only) tattoo is an optical diagram of my favourite lens, the Leica Summicron 50mm f/2. The idea of using my Summicron lens on digital really tickled me.</p> <div class="narrow"> <p><img src="https://ashfurrow.com/blog/camera-time/tattoo.jpeg" alt="Photo of my tattoo" /></p> </div> <p>I was concerned about some of the downsides to mirrorless cameras, like shorter battery life and feeling more like a computer than a camera. But the thing I was most concerned about was having to use an electronic viewfinder. I'm used to being able to see, optically, the actual scene that I'm shooting. I was reluctant to give that up. So as an experiment, I started using my X100S with its electronic viewfinder. (In over ten years, I had barely used it.) The refresh rate was kind of laggy but I got used to it pretty quickly. I was actually enjoying the way the EVF gave me an exposure preview of the photo that the camera was actually going to record when I hit the shutter button – that's something that DSLRs just can't do. I figured that if the older X100S was usable, then a newer mirrorless camera would be great (spoilers I was right).</p> <p>So then the question was: which camera system to get? Usually when a photographer picks a camera system, they're either just getting started or they're experienced and switching systems. I was in a distinct position to knowing what I wanted <em>but also</em> starting fresh. So let me outline my thinking.</p> <p>Canon and Nikon had both initially missed the boat on mirrorless. Sony, FujiFilm, Olympus, and other manufacturers hadn't been caught in the same &quot;innovator's dilemma&quot; as the two market-leading DSLR makers, and so they had had a huge head start. Canon was also being weird about letting third party lens manufacturers not build on its new mirrorless lens mount, which gave me a bad vibe. And to be honest, Nikon digital cameras have always given me a bad vibe.</p> <p>So I ruled out the giants. I considered Micro Four Thirds but decided against it. That narrowed it down to Sony or FujiFilm. I spent a lot of time researching opinions online and thinking about what I actually wanted in a camera.</p> <p>Primarily, I wanted a camera that I would feel inspired by. When I was shooting on my walk to-and-from work in Manhattan every day, I didn't need much inspiration. Photography was automatic. Now, working from home in Fredericton, photography is a decision. It's something I go and do. I've been know to struggle with creative motivation so I was looking for a tool that would get me excited to use it.</p> <p>I tried some cameras out in-person. <em>By far</em>, the FujiFilm cameras I tried were the clear winners. The Sony cameras reminded me that I'm using a computer, while the FujiFilm cameras felt like old film cameras. Many FujiFilm cameras have physical dials for shutter speed and ISO, and their lenses usually have aperture rings. It felt natural. After some more research, I made a decision on a model. Normally, I would buy a used camera and lens, but FujiFilm's used market is currently overinflated (due to a lot of factors). So I picked a current model.</p> <p>But before I bought anything, I hit a wall. I became preoccupied with anxiety that all this excitement was just Gear Acquisition Syndrome. When I first got into photography, I compulsively and continuously upgraded my gear. Over the years, I have bought cameras that I didn't really need and that I quickly moved on from. Nerds call this GAS, and I've worked hard to get it under control. Now I found myself worried that my renewed interest in photography was somehow GAS in disguise, that I wasn't authentically interested in photography at all. I wanted to make a responsible decision, both financially and creatively.</p> <p>Because gear doesn't matter. You can take great photos on bad cameras. And you can have a lot of fun doing it. Here is a photo I love, and the camera I used has an entire <em>two</em> shutter speeds – plus bulb mode!</p> <div class="wide"> <p><img src="https://ashfurrow.com/blog/camera-time/paris.jpg" alt="Black and white photo of Paris taken on a fold-out camera" /></p> </div> <p>It's the photographer that matters, not the camera. (Of course, it's easier to say &quot;gear doesn't matter&quot; when you have nice gear. And I do have a nice film kit.) I started questioning whether I should buy a new digital camera at all. Wasn't my X100S enough?</p> <p>I sat with this for some time. I talked this over with a few people who know me. And I kept taking photos with the X100S. I started editing those photos in Apple Photos, then tried some more sophisticated tools like Photomator and ON1 Photo Raw, before (reluctantly) reactivating my Lightroom subscription. I had really been enjoying editing photos, in a way that I hadn't for a long time.</p> <p>Not suddenly, but slowly, I realized that my anxiety over a possibly &quot;inauthentic&quot; interest in photography was unfounded. I wasn't trusting myself. It does make sense to sit on a big purchase decision like this, but I had. I <em>had</em> thought it over. And I knew I didn't <em>need</em> it; I <em>wanted</em> it. (Confusing these two is an symptom of GAS.) I talked it over one last time with Ashley and then I hit the purchase button.</p> <p>That was a month ago. So which camera did I get?</p> <p>&quot;Gear doesn't matter.&quot;</p> <div class="narrow"> <p><img src="https://ashfurrow.com/blog/camera-time/me.jpeg" alt="Photo of me taking a photo with a tripod" /></p> </div> <p>I'll be publishing more photo blog posts <a href="https://photos.ashfurrow.com/">over at my photo blog</a>. I'm exploring some new editing styles and I plan to write about that process over there. I don't really know where people are sharing their photos online anymore, to get photo critique; let me know if you have suggestions. See you there!</p>
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
<channel>
<title>
<![CDATA[ Ash Furrow's Blog ]]>
</title>
<link>https://ashfurrow.com</link>
<atom:link href="https://ashfurrow.com/feed.xml" rel="self" type="application/rss+xml"/>
<description>
<![CDATA[ Compassionate Software Developer ]]>
</description>
<language>en</language>
<item>
<title>
<![CDATA[ Five Years in New Brunswick ]]>
</title>
<link>https://ashfurrow.com/blog/five-years-in-new-brunswick/</link>
<pubDate>Fri, 31 Oct 2025 00:00:00 GMT</pubDate>
<guid>https://ashfurrow.com/blog/five-years-in-new-brunswick/</guid>
<description>
<![CDATA[ Today marks five years since my wife and I moved away from New York and back to New Brunswick. When I wrote about this last time, I seemed unhappy. I guess things hadn&#39;t worked out the way that I had envisioned them when we moved home – even if I didn&#39;t... ]]>
</description>
<content:encoded><p>Today marks five years since my wife and I moved away from New York and back to New Brunswick. <a href="https://ashfurrow.com/blog/four-years-in-new-brunswick/">When I wrote about this last time</a>, I seemed unhappy. I guess things hadn't worked out the way that I had envisioned them when we moved home – even if I didn't have a really clear vision for how things would go. I have a more optimistic view now.</p> <p>About a year ago, <a href="https://photos.ashfurrow.com/downtown-in-the-rain">I started taking photos again</a>. It started on my phone, but then I got out my old film cameras which <em>still had film in them from New York</em>. I finished the rolls and sent them off to be developed. When they came back, I found this:</p> <div class="wide"> <p><img src="https://ashfurrow.com/blog/five-years-in-new-brunswick/photo.jpg" alt="Double-exposure photo with New York on the left and Fredericton on the right" /></p> </div> <p>This is a double exposuree, with half the frame being taken in New York and the other half being taken here in Fredericton. <em>Five years apart!</em> From what I can piece together, what happened is:</p> <ol> <li>I took a photo in New York.</li> <li>Five years pass.</li> <li>At some point, the &quot;double exposure&quot; lever on my camera was activated.</li> <li>I advanced only halfway to the next frame.</li> <li>I took another photo in Fredericton.</li> </ol> <p>That's what I've pieced together, because this was not what I intended when I took either photo. One of the last photos I took in New York, and one of the first photos I took in Fredericton. <em>This was not what I envisioned.</em> (I also have <em>no idea</em> why one of the photos was taken <em>upside down!</em> What!?)</p> <p>Something I love about film photography – and digital, too – is the unexpected. In photography, you see a scene and you pre-visualize the shot, and then you try to realize your photographic vision. But unexpected things happen. And I think <em>good</em> photographers are open to that spontaneity. You can't always faithfully execute on your vision, but you can choose to work with whatever happens.</p> <p>In this case, I've <em>edited</em> the photo to look good. Without those edits, the original was kind of bleh:</p> <div class="wide"> <p><img src="https://ashfurrow.com/blog/five-years-in-new-brunswick/original.jpg" alt="The same photo, but less contrasty and not cropped. I looks faded." /></p> </div> <p>This is not what I envisioned, but I love what I made of it. This is probably my favourite photo that I've ever taken <em>ever</em>, and it was an accident.</p> <p>Things haven't gone the way I intended when I moved home, but that's okay. Part of being human is accepting the spontaneity of life and making something beautiful with it.</p> </content:encoded>
</item>
<item>
<title>
<![CDATA[ Joining Wealthsimple ]]>
</title>
<link>https://ashfurrow.com/blog/joining-wealthsimple/</link>
<pubDate>Tue, 14 Oct 2025 00:00:00 GMT</pubDate>
<guid>https://ashfurrow.com/blog/joining-wealthsimple/</guid>
<description>
<![CDATA[ I&#39;m excited to announce that today is my first day working at Wealthsimple! I&#39;ll be working as a staff developer on their mobile app. In a previous blog post, I teased that this role was a perfect fit for me. Today, I&#39;m excited to share some details. But... ]]>
</description>
<content:encoded><p>I'm excited to announce that today is my first day working at <a href="https://www.wealthsimple.com/">Wealthsimple</a>! I'll be working as a staff developer on their mobile app. <a href="https://ashfurrow.com/blog/floating-on/">In a previous blog post</a>, I teased that this role was a perfect fit for me. Today, I'm excited to share some details.</p> <p>But first we need some context and a little background on React Native.</p> <hr /> <p>I started working with React Native at Artsy. <a href="https://artsy.github.io/blog/2016/08/15/React-Native-at-Artsy/">Orta and Eloy were keen on adopting it in 2016</a>, but I was very skeptical. So skeptical, in fact, that I found myself working on non-mobile Artsy projects. That's when I learned React on the web, and <a href="https://ashfurrow.com/blog/the-case-for-react-native/">that's when I came around to React Native</a>. I got on board with the vision that the two of them had started building. I started contributing to that vision and eventually I worked up to <a href="https://artsy.github.io/blog/2020/09/29/becoming-mobile-first-at-artsy/">leading the team that owned the whole app</a>.</p> <p>One of the foundational principles that Orta and Eloy had established was that Artsy wouldn't use React Native where it led to a worse user experience; we'd use React Native only <em>where it made sense</em>, and use native iOS tech where <em>it</em> made sense. Our goal was to create a great app, and React Native couldn't do that on its own. As a concrete example, the navigation stack itself was still in Objective-C (while the view controllers were slowly migrated to React Native).</p> <p>That was (gosh) nearly a decade ago. React Native itself has gotten <em>much</em> better, especially as tools like <a href="https://expo.dev/">Expo</a> have taken off. It's now easy for developers to access underlying native SDKs from JavaScript (like photo pickers, Spotlight integration, even augmented reality). But! There still remains a &quot;last mile&quot; in React Native, where native technologies <em>must</em> be used <em>directly</em> in order to build the best user experience. In 2016, maybe you could get 70% to a great UX in React Native alone. By 2020, maybe that had reached 90%. Today, maybe it's around 95%, or so? But I don't believe it will ever reach 100% for two reasons.</p> <p>First is the platform vendors themselves. Apple and Google develop their own SDKs for building apps and would prefer you to use them. Now, React Native <em>uses</em> those SDKs under the hood, but React Native itself doesn't fit in certain restrictive runtimes. Take widgets, for example. Or push notification extensions, or smartwatch apps, or any number of the small-but-deeply-integrated features that elevate an app from <em>good</em> to <em>great</em>. (Even where it's <em>possible</em> to fit a React Native runtime into these environments, you might not actually want to. I helped a team at Shopify build an <a href="https://developer.apple.com/documentation/appclip">App Clip</a> in React Native; App Clips needed to archive down to under 10MB and fitting inside that constraint was a huge challenge. While the project was a technical success, the user experience wasn't great.)</p> <p>Second is the irreducible complexity of a cross-platform development tool like React Native. This kind of tool needs to work across all kinds of platforms while not <em>feeling</em> like a &quot;lowest common denominator.&quot; The React Native project itself has made a lot of improvements here over the years. In case you weren't aware, please let me blow your mind: there is now synchronous, two-way interoperability between React Native's JavaScript runtime and native code. JavaScript can now communicate <em>directly</em> with native code through object references 🤯 This has come a long way since React Native's original, asynchronous bridge where all communication was serialized over JSON. This advancement has led to huge performance gains that close the distance on that last mile – even if it can't close it entirely.</p> <p>However. This fancy <a href="https://reactnative.dev/architecture/landing-page">new architecture</a> comes with added complexity. You don't get end-to-end type-safe memory access between TypeScript and native runtimes without <em>at least a little bit</em> of C++. Any app developer who's serious about delivering the <em>highest-possible quality mobile user experience</em> will need to dive under React Native's JavaScript exterior and work in the underlying native stack, in C++, Swift, Kotlin... whatever it takes.</p> <p>That's where I come in.</p> <p>It's very rare to find a developer who is comfortable in <em>both</em> React Native <em>and</em> the underlying native SDKs. Mobile native developers tend to avoid React Native. On the other side, React Native developers tend to want to stay in JavaScript, avoiding native tech. There are exceptionally few developers out there with deep enough experience with native iOS that they could still write manual-retain-release Objective-C <em>and</em> who have extensive experience building React Native applications in JavaScript. <em>And</em> who enjoy working in both.</p> <p>What I have to offer is an unbiased perspective. (Or at least, a less biased one.) Someone to help make the right decision for the product, whether it's native or React Native. Someone who is confident contributing at any level of the stack. And someone to help scale up a larger team with those same skills. I can't wait!</p> <hr /> <p>My new role will have a narrower focus with more day-to-day coding and <a href="https://ashfurrow.com/blog/work-at-your-spikes/">I'm expecting a greater career satisfaction</a>. I've learned that I <em>can</em> do anything, but if I try to do <em>everything</em>, then my work suffers. I suffer. It's time to specialize in mobile UX again.</p> <div class="narrow"> <p><img src="https://ashfurrow.com/blog/joining-wealthsimple/wwdc2010.jpg" alt="Photo of (a younger) me at WWDC 2010." /></p> </div> <p>I'm also <em>really</em> excited to be working in native technologies more often. I've followed every WWDC since I attended my first in 2010, but if I'm being completely honest, it's been hard to feel as immersed as I used to in Apple technology without working in native iOS day-to-day. My Swift skills are a little rusty and my SwiftUI skills... well, let's just say that I'm looking forward to sparring with Xcode again. In some ways, this will be a return to native iOS for me. But I'm not &quot;going back&quot;, I'm using my experience to go forward.</p> <div class="narrow"> <p><img src="https://ashfurrow.com/blog/joining-wealthsimple/mdevcamp.jpg" alt="Photo of (a less younger) me speaking at mDevCamp." /></p> </div> <p>I'm really looking forward to ramping up with Wealthsimple. They have a great product for an underserved Canadian market. <a href="https://www.wealthsimple.com/en-ca/culture">Their stated culture</a> describes the exact kind of environment where I can do my best work. Also, I've opened personal bank accounts in three countries so I also get to bring my experience banking in the US and Europe. When I moved home to Canada, I was surprised to see how little the big banks had changed in the seven years I lived away. Wealthsimple is pushing Canada forward here. They've built a quality app and have already done a lot to cover that last mile of React Native user experience – I can't wait to pitch in!</p> </content:encoded>
</item>
<item>
<title>
<![CDATA[ Eleventy Launch ]]>
</title>
<link>https://ashfurrow.com/blog/eleventy-launch/</link>
<pubDate>Wed, 08 Oct 2025 00:00:00 GMT</pubDate>
<guid>https://ashfurrow.com/blog/eleventy-launch/</guid>
<description>
<![CDATA[ As I discussed previously, I&#39;ve been rewriting this blog in a new tool called 11ty (aka Eleventy - the project&#39;s devs aren&#39;t consistent so I won&#39;t be either). This is the first blog post written in the new blog engine, and the migration is complete! I... ]]>
</description>
<content:encoded><p><a href="https://ashfurrow.com/blog/yet-another-blog-rewrite/">As I discussed previously</a>, I've been rewriting this blog in a new tool called <a href="https://www.11ty.dev/">11ty</a> (aka Eleventy - the project's devs aren't consistent so I won't be either). <em>This</em> is the first blog post written in the new blog engine, and the migration is complete!</p> <p>I already mentioned my reasons for migrating off of Gatsby, but it's worth repeating <em>how much less complex</em> an 11ty implementation is. Gatsby's complexity led to long build times, which started exceeding Netlify's (free tier) deploy timeout. On my M2 MacBook Air, you can see a <strong>16x speedup on fresh builds</strong>:</p> <pre><code># Gatsby yarn build 329.83s user 28.18s system 257% cpu 2:19.14 total # Eleventy yarn build 57.01s user 4.42s system 387% cpu 15.863 total </code></pre> <p>I had let the project sit on the back burner for a while but <a href="https://ashfurrow.com/blog/floating-on/">recent events</a> have led me to have spare time to finish it. One of my first priorities was to get Netlify deploy previews working again, which was a great call. This helped me test end-to-end and verify that I would get back continuous (one of the goals of this project). To fully deploy the site from Netlify takes about a minute.</p> <p>Side note: I don't want to beat up on Gatsby but it's also clear that it hasn't been a good fit. Gatsby is great for complex sites with dynamic content, but <em>this</em> site is a static blog with hundreds of posts. My precious posts! When testing the build times, I saw the following warning:</p> <pre><code>Your GraphQL query in createPages took 28.522 seconds which is an unexpectedly long time. See https://gatsby.dev/create-pages-performance for tips on how to improve this. </code></pre> <p>Huh! Okay maybe the performance problems are on <em>my</em> side of the keyboard after all! Maybe I'm holding Gatsby wrong. I examined the query in question, and laughed out loud.</p> <pre class="language-graphql"><code class="language-graphql"><span class="token punctuation">{</span> <span class="token property-query">allMdx</span><span class="token punctuation">(</span><span class="token attr-name">sort</span><span class="token punctuation">:</span> <span class="token punctuation">{</span> <span class="token attr-name">order</span><span class="token punctuation">:</span> <span class="token constant">DESC</span><span class="token punctuation">,</span> <span class="token attr-name">fields</span><span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token property">frontmatter___date</span><span class="token punctuation">,</span> <span class="token property">frontmatter___title</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token object">edges</span> <span class="token punctuation">{</span> <span class="token object">node</span> <span class="token punctuation">{</span> <span class="token property-query">excerpt</span><span class="token punctuation">(</span><span class="token attr-name">pruneLength</span><span class="token punctuation">:</span> <span class="token number">250</span><span class="token punctuation">)</span> <span class="token property">body</span> <span class="token property">id</span> <span class="token object">frontmatter</span> <span class="token punctuation">{</span> <span class="token property">date</span> <span class="token property">title</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token object">siteSearchIndex</span> <span class="token punctuation">{</span> <span class="token property">index</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre> <p>All it's doing is querying blog posts, which are <em>just text</em>. Even the search index is <em>just processing text</em>. It's all just text! So I'm putting the blame here on Gatsby. I'm left wondering who this tool is for? Gatsby can't scale to <em>under a thousand text files</em> so it's not a good fit for a simple static site. Do you need something more complex? Then you probably want more than a static site, anyway.</p> <p>Counting lines of code isn't a perfect way to measure complexity, but in this case I think it's helpful for comparing the two implementations. Remember that Gatsby is a React site generated from Markdown using GraphQL with lots of other bells and whistles; more complex but more expressive. The 11ty implementation uses plain HTML, CSS, and JavaScript; simpler but more verbose.</p> <pre><code># Gatsby cloc --exclude-dir=node_modules,public,.netlify,blog,.cache, ------------------------------------------------------------------------------- Language files blank comment code ------------------------------------------------------------------------------- TypeScript 50 259 52 3143 Markdown 6 112 0 616 JavaScript 2 9 19 207 JSON 3 0 0 155 CSS 1 19 10 111 SVG 6 0 3 93 Text 2 13 0 61 diff 1 2 28 24 TOML 1 0 0 4 ------------------------------------------------------------------------------- SUM: 72 414 112 4414 ------------------------------------------------------------------------------- # 11ty cloc --exclude-dir=node_modules,public,.netlify,.husky --not-match-d=&quot;blog|fontawesome&quot; . ------------------------------------------------------------------------------- Language files blank comment code ------------------------------------------------------------------------------- CSS 7 86 54 1589 Nunjucks 17 76 17 1239 JavaScript 10 96 124 619 Markdown 5 86 0 179 Text 2 13 0 61 SVG 3 0 3 48 JSON 3 0 0 47 TOML 1 0 0 4 ------------------------------------------------------------------------------- SUM: 48 357 198 3786 ------------------------------------------------------------------------------- </code></pre> <p>Despite being less expressive, 11ty is still the &quot;smaller&quot; implementation. Which makes sense, since <em>you don't need GraphQL to render markdown into HTML</em>. In any case, I remain impressed at how much can be accomplished using only what we was once called &quot;Dynamic HTML.&quot; Gatsby's implementation used 24 dependencies (which get shipped to users reading the blog) and just as many build-time Gatsby plugins. 11ty used only <em>three</em> user dependencies and <em>four</em> build-time plugins. <code>package.json</code> has gone from 118 lines down to just 39.</p> <p>You might be asking about using plain JavaScript instead of TypeScript. I'm generally in favour of TypeScript, but you don't need to have a full build pipeline to benefit from it. In this project, TypeScript only helps with local development, it doesn't really prevent user-facing bugs. I don't think the tradeoff is worth it, so instead I used JSDoc comments to add types where I though they would help. Everything is a tradeoff, and I wanted the biggest benefit for the smallest complexity. That's why I wrote my own <code>groupBy</code> instead of using lodash.</p> <p>Overall, implementing the new site went smoothly with one exception. The thing that furstrated me the most was <a href="https://www.11ty.dev/docs/plugins/image/">11ty's Image plugin</a>. This is the most (only?) opinionated part of 11ty's stack. The project clearly wants developers to use new HTML features (like image source sets) to provide multiple resolutions of an image so browsers can choose the best one to display. That makes sense, and Gatsby actually does something similar (albeit using JavaScript). But I just couldn't really wrap my head around the plugin, it kept getting in my way. And due to <s>me being a stubborn ass</s> some hard constraints of my directory structure, I couldn't <em>not</em> use it.</p> <p>Eventually, I figured it out. Actually it was quite easy, once I started <em>actually using my brain</em>. I had been fighting the Image plugin by proxy, with Claude Code. This is probably a good time to talk about AI.</p> <p>I mentiond in the last post that Claude Code had accelerated this project. I think it's fair to say I would not have gotten this done if Claude Code hadn't automated some of the most tedious work. But Claude Code was <em>awful</em> at the start of the project; only when I completed the initial project setup myself was it helpful. Maybe I just needed the context to prompt it, but I didn't have that context without building the foundation. Near the end of the project, Claude Code became similarly frustrating, especially as I fought with the Image plugin. Once I <s>lost access to my former employer's Claude Code account</s> decided to valiantly complete the project on my own terms, it became a lot easier. I had to fully read the docs to understand what the Image plugin was trying to accomplish. Half an hour of using my brain was more rewarding and succesful than fighting with Claude Code.</p> <p>In summary, <em>AI tools seem most useful in the middle of a project</em>. I needed to give them a solid foundation to start from. Simiarly, at the end of the project, they could not polish work to my satisfaction. I think it's also helpful to be able to maintain this project <em>without</em> using AI tools; call me old fashioned, but <em>I want to understand the code</em>. I want to be able to maintain this project even if <s>the AI bubble bursts</s> my internet connection goes down.</p> <p><a href="https://github.com/ashfurrow/blog/pull/520">You can review the pull request here</a> for insights into my process (ignore the lines-of-code count, as prettier formatted thes blog posts once they were migrated from MDX to markdown).</p> <p>I've taken pains to make sure the RSS feeds still work as expected, but I always worry about changes that might affect my favourite readers, the RSS nerds. If you see any problems, anywhere on the site, <a href="https://github.com/ashfurrow/blog/issues/new">please open an issue</a>.</p> </content:encoded>
</item>
<item>
<title>
<![CDATA[ Work At Your Spikes ]]>
</title>
<link>https://ashfurrow.com/blog/work-at-your-spikes/</link>
<pubDate>Mon, 06 Oct 2025 00:00:00 GMT</pubDate>
<guid>https://ashfurrow.com/blog/work-at-your-spikes/</guid>
<description>
<![CDATA[ I want to discuss my career trajectory and a chronic issue I&#39;ve identified with my job satisfaction since becoming a staff developer. It&#39;s been subtle and I didn&#39;t notice it for years. Maybe this will resonate with you. After a lot of reflection, I&#39;ve... ]]>
</description>
<content:encoded><p>I want to discuss my career trajectory and a chronic issue I've identified with my job satisfaction since becoming a staff developer. It's been subtle and I didn't notice it for years. Maybe this will resonate with you.</p> <p>After a lot of reflection, I've identified a trend in my career direction that started when I first led Artsy's new Mobile Experience team in 2019. It was the perfect role for me, and I <em>crushed</em> it. But it also set me on a path where I would feel unfulfilled with my work. This trend that I've identified has followed me from Artsy to Shopify to Float. But now that I've identified it, I've got a better understanding of where I want my career to go next.</p> <p>The trend is not working at my &quot;spikes&quot;, doing more and more work that is only &quot;okay.&quot; Basically, the amount of my day-to-day time that's spent on tasks that aren't a distinguishing strength of mine.</p> <h2>Spikiness</h2> <p>&quot;Spiky&quot; people (also sometimes called &quot;<a href="https://en.wikipedia.org/wiki/T-shaped_skills">T-Shaped</a>&quot; people) refers to people who have <em>specific</em> areas of professional skill and experience. I'm spiky in mobile UX implementation, for example. Spikes are deep and narrow. Spiky people tend to have gaps, though. These are areas where they have neither the need or interest to improve. One of my gaps is low-level database optimization; it just doesn't interest me and I've never needed to learn it.</p> <p><img src="https://ashfurrow.com/blog/work-at-your-spikes/spiky.svg" alt="A star shape with big spikes and a small centre." /></p> <p>You can think of a spiky person as a contrast to a well-rounded person. These two ideas are at either ends of a gamut – no one is &quot;only spiky&quot; or &quot;only well-rounded.&quot; But it's a helpful metaphor for professional growth. Spiky people have gaps that well-rounded people don't have, but spiky people can have an outsized impact in their areas of expertise. So it's a tradeoff.</p> <p><img src="https://ashfurrow.com/blog/work-at-your-spikes/compared.svg" alt="Diagram comparing the same spiky star shape from above with another star shape. The new one is labelled &quot;well-rounded&quot; and its peaks are smaller than the spiky shape, but it's area is greater because it's centre is larger; it has fewer gaps." /></p> <p>I like being spiky. My spikes have helped me stand out and get opportunities that a more well-rounded version of myself wouldn't get. I prefer to <em>manage</em> my gaps rather than fill them in because filling them in would smooth down my spikes. After all, there is only so much time in a day and you have to choose where to spend your time and energy.</p> <p>Everything has an opportunity cost. Filling in my gaps would mean less time spent getting <em>even better</em> at my spikes. My spikes are also where my interests lie, so doing work in my gaps is already less interesting. Which would help me more? Spending time getting better at mobile UX implementation, or spending time getting better at low-level database optimization?</p> <p>There are tradeoffs to being spiky, of course. For example, I <em>need</em> a team to do my best work. Working solo, I can do a <em>good</em> job; working in a team where I can rely on and support others, I can do a <em>great</em> job. I like to work with other spiky people because we help mitigate each other's gaps. A team with a lot of spiky people can accomplish more than a team of generalists, in my experience.</p> <p>The thing is, though, I haven't been working at my spikes. For a while, I've been generalizing. <a href="https://ashfurrow.com/blog/perspective-of-the-polyglot/">I've written about how it's good and fun to branch out</a>, and it is! This is not a post <em>against</em> generalizing. But it's about the consequences and tradeoffs. (Spoilers: <a href="https://ashfurrow.com/blog/specializing-in-being-a-generalist/">I've also written about stretching myself out too thin</a>.) I've caught myself accepting that I was a generalist now. I accepted that I wouldn't get to do as much deep work at my spikes – mobile UX implementation – because there were <em>so many other things</em> that my job demanded needed me to do instead.</p> <p>Side note: a lot of staff/principal developers struggle with letting go of <em>coding</em> as their primary responsibility. At a certain level of seniority, your time is better spent helping your <em>whole team</em> be productive than it is spent on your own productivity. I (and many peers) do struggle with decoupling a sense of accomplishment from a number of pull requests or features built. But this is something different. Because I (and many peers) do find ways to be fulfilled by technical leadership work.</p> <p>The root of my issue is that I've allowed the needs of my employers to guide my career growth too much. I've become whatever the business needs me to be at the time. To be clear, this has been a successful career! From the business' perspective, it's <em>really</em> handy to have a staff-level mobile developer who can design UI themselves, who can manage their own projects, who can deploy their own microservices, who can even build their own dashboards! That kind of person can jump into any environment and be effective. Businesses love that.</p> <p>Consider that the Shop Minis SDK that I built didn't have an actual product manager for the first year of its existence. It was just me, organizing the small team of engineers and whatever design capacity we could borrow. Without many resources, I got <em>a lot</em> accomplished. The project was a success even without a PM.</p> <p>Those other skills, though – design, project management, backend, dashboards – they are not my spikes. I can do them, but... so, uh, the thing is my dashboards are not... exceptional, okay? They're fine, they're good. Dashboards are not a <em>gap</em> for me like database optimization, but they're not a spike either. They sit in-between.</p> <p><img src="https://ashfurrow.com/blog/work-at-your-spikes/detailed.svg" alt="A zoomed-in view of the spiky diagram, with three dots along one of the edges. The dot in the gap is labelled &quot;database optimization&quot;, the dot at the spike is labelled &quot;mobile UX&quot;, and the dot in between is labelled &quot;dashboards.&quot;" /></p> <p>I don't like making dashboards. I find the task tedious. And yet, I've spent more and more time on dashboards over the years. I've had to, to be an effective leader in my different roles. I now have enough &quot;experience in dashboards&quot; that I could credibly list it as a skill on my resume. Ugh.</p> <p>Upon reflection, I've found myself working further and further away from my spikes in a lot of different ways (not just dashboards). I'm doing many types of work not because I excel in those areas, but because <em>I can be effective working across many areas</em>. And <em>that</em> has been what my employers have needed. When I <em>do</em> get to work at my spikes, my work has still been of high enough quality that I can still get a lot of job satisfaction. The tradeoff has worked for me. Also, it feels <em>amazing</em> to be &quot;the fixer&quot; who can parachute in and help any team do any thing.</p> <p>But this trend has picked up and the balance has been broken. It led me to not really enjoy my work like I used to. This affected my motivation and the quality of my work.</p> <p>So what happened?</p> <h3>Early Stage Companies</h3> <p>There are a lot of things I enjoy about working for early-stage startups and one of the my favourite aspects is how you get to own a broad domain. To &quot;wear a lot of hats&quot;, so to speak. If you see a problem or opportunity, you get to own the solution. There actually aren't a lot of resources in early companies, so being able to handle a broad range of responsibilities is <em>really important to being successful</em> at a startup.</p> <p>However, such a resource-constrained setting can make it challenging to advocate for resources you <em>do</em> need. I can understand the business' perspective here: why allocate scarce resources to a team who's already so effective without them? There is a great reason, actually. Artsy's CTO <a href="https://code.dblock.org/about/">dB</a> once explained to me how startups need more and more engineers year-over-year <em>just to keep shipping at the same velocity</em>. As you build the product, its surface area grows which increases complexity and risk, which require more engineer time to manage. Not every company understands this.</p> <p>Over time (especially if you don't get more resources as your own surface area grows) you can easily become overstretched. You can get used to being overstretched, spending <em>so little</em> of your time working at your spikes that the time you <em>do</em> get to feels... almost like a chore? Work you once loved can feel like obstacle to doing the work your team needs... like building dashboards. You can lose your own sense of accomplishment and the sense of shared accomplishment that comes from enabling others.</p> <p>As your motivation drops, the quality of your work drops too. If you a person who is motivated by doing great work, this can easily become a self-reinforcing cycle where lowered quality leads to less motivation and even worse quality. The whole time, you feel worse and worse.</p> <h3>AI and the Push Towards Average</h3> <p>The other factor that accelerated my mid-career malaise was AI. LLM tools have had an impact on baseline expectations for many, many roles in the past few years. They let you &quot;do more with less.&quot; It's now pretty easy for <em>anyone</em> to make dashboards almost as good as mine! <em>Despite my years of experience!</em></p> <p>It's honestly really frustrating to me. Infuriating! I'm enraged! What is even the point?? If <em>anyone</em> can &quot;vibe chart&quot; then <em>why</em> the fuck am <em>I</em> doing it? AI tools have lifted up the &quot;floor&quot; of dashboard skills which has, in effect, brought me down closer to average. Average! Me! No way.</p> <p>Now, you could push back here and suggest that maybe <em>I</em> need to use the AI tools to become better at dashboards. Either improve the quality of the dashboards, or build them faster, or whatever. And that would be a fair pushback except <em>I already didn't want to be doing dashboards.</em> It's one of many skills that I picked up because various employers needed me to. Using AI to get better at dashboards would just be filling in my gaps ✨ but with AI ✨ and <em>still</em> at the expense of my spikes.</p> <p>(Besides, if I'm going to use AI tools to improve my skills, then why not use them at my spikes?)</p> <h2>Mid-Career Slump</h2> <p>I'm really glad that I specialized in mobile software so early in my career. It's been fun and rewarding. I'm also glad that I branched out a few years in. Being able to fit into whatever shape a business needs has been very lucrative. The problem is that I've spent the past six years fitting into other shapes that I've lost a connection to my own intrinsic shape.</p> <p>It feels a little ironic to end up back where I started, specializing again. But I'm not really &quot;back&quot; here because I'm not the same person I was in 2019.</p> <p><img src="https://ashfurrow.com/blog/work-at-your-spikes/meme.jpg" alt="The &quot;bell curve&quot; meme where the beginner and expert have the same opinion of &quot;it's good to specialize&quot; with the middle person saying &quot;nooooo u need generalized skills&quot;" /></p> <p>I'll offer some advice for software developers, advice I wish I had gotten sooner: specialize at first for a jump-start, then generalize quickly after that to accelerate your career. But re-specialize again as <em>soon</em> as possible. Once you become &quot;general enough&quot; to specialize again, do it. Do it <em>before</em> you feel ready.</p> <p>One of my best skills is being able to discern the most important thing I need to do for a business at any given time, and I've always prioritized the business need. Putting the business first is a great way to get rewarded, but I'm not working <em>just</em> to collect a paycheque. I want to do great work! I'm lucky enough to <em>get</em> to pursue a fulfilling career, so it's time to prioritize my own satisfaction. It's time to find a role where the business' needs overlap with my own.</p> <p>My hope is to use this reflection like a gravity assist, <em>approaching</em> a career as a generalist before spectacularly sling-shotting away towards a more specialized, more fulfilling career. Gravity assists are famously difficult courses to plot – you have to work backwards from the destination. My destination has been my mobile UX spike.</p> <p>I've found my next role in a larger organization where I'll have a narrower focus. I'll have an announcement about where I'm going soon. In my new role, I'll get to leverage my expertise as a specialist again. Fewer dashboards, more mobile UI implementation. Less average, more spiky. And hopefully, a happier me.</p> </content:encoded>
</item>
<item>
<title>
<![CDATA[ Floating On ]]>
</title>
<link>https://ashfurrow.com/blog/floating-on/</link>
<pubDate>Fri, 26 Sep 2025 00:00:00 GMT</pubDate>
<guid>https://ashfurrow.com/blog/floating-on/</guid>
<description>
<![CDATA[ It&#39;s with mixed emotions that I&#39;m announcing today is my last day working at Float. I&#39;ve accomplished a lot here and I&#39;m grateful for the opportunity to help shape such a young company and product team. I&#39;m sad to say goodbye to my coworkers and I wish... ]]>
</description>
<content:encoded><p>It's with mixed emotions that I'm announcing today is my last day working at <a href="https://floatfinancial.com/">Float</a>. I've accomplished a lot here and I'm grateful for the opportunity to help shape such a young company and product team. I'm sad to say goodbye to my coworkers and I wish everyone the best.</p> <p>Whatever job I'm in, I always learn something – that's just how I practice product development. But I was surprised by how much I learned <em>about myself</em> at Float. I've worked in early-stage startups before and so I <em>thought</em> I had an idea of what to expect. There were two curve balls I didn't anticipate.</p> <p>The first is Float's distinct ferocity: <em>everyone</em> at the company cares deeply about Float's success. They work harder than anyone to earn customers' business, to fight for their market position. I care a lot about my work, so a company full of other people who care about <em>their</em> work was a perfect fit for me. The unexpected part was the intensity. Float is the most ferocious company I have ever worked for. While I'm proud of how I rose to that challenge, I also learned where some of my own limits are.</p> <p>The other difference is me. <em>I'm</em> different. At other startups I've joined, my role was (at first) to build apps. I grew into leadership positions, but Float was my first time I <em>joined</em> an early company <em>as a leader</em>. That brought a whole new set of challenges. I worked more closely with company leadership, I learned more about the business than I had at other startups, and I exercised my autonomy appropriately. That's a lot of extra context to absorb and execute on.</p> <p>I'm proud of my accomplishments here, as both a technical leader and as an organizational leader. Building an app from scratch is always a lot of fun, and the team I led launched the app <em>only 99 days after our initial commit!</em> Scaling a mobile app within a product organization is always an interesting challenge, and I led the Float mobile app to get contributors from <em>every</em> product team. Being part of a high-growth engineering team is always thrilling, and I've successfully modelled my practice of product development through curiosity and empathy. I joined Float to build a great app, and customers have said the app is their favourite part of Float's product. What a compliment! I'm proud of what I've done and how I've done it.</p> <p>Failure has always been my greatest teacher. Float is a company where you cannot succeed without taking risks and making mistakes, and I've been successful enough here to have made some of my most interesting mistakes. I'm proud of those mistakes. I treasure them.</p> <p>Deciding to leave a company is never easy for me, and particularly so with Float. It's a unique company and I'm sure it will continue to make waves. I wish Float and my coworkers well.</p> <p>I keep a small box of what I call &quot;captain's trinkets.&quot; Picard had his flute, Sisko had his baseball, and Freeman had her flag of the California Republic. In my office, I keep a small collection of objects that symbolize meaningful times of my career. Float's first product was in corporate credit cards so I feel it's appropriate to retire my own Float card to the captain's trinkets box.</p> <p><img src="https://ashfurrow.com/blog/floating-on/trinkets.jpeg" alt="A box with old Artsy business cards, a UNB keychain, a Series 0 Apple Watch, an old passport, and other items." /></p> <p>I have an exciting new opportunity that I'm starting after some time off. When I've described the role to people who've worked with me, they've nodded and said something along the lines of &quot;oh yeah, that sounds perfect for you.&quot; I'm excited to share more. Until then, take care!</p> </content:encoded>
</item>
<item>
<title>
<![CDATA[ Yet Another Blog Rewrite ]]>
</title>
<link>https://ashfurrow.com/blog/yet-another-blog-rewrite/</link>
<pubDate>Tue, 26 Aug 2025 00:00:00 GMT</pubDate>
<guid>https://ashfurrow.com/blog/yet-another-blog-rewrite/</guid>
<description>
<![CDATA[ In 2019, I rewrote this blog with Gatsby. I outlined my reasons in that post, but basically I wanted to use similar technology to build my blog as I used day-to-day at work. Middleman, Bootstrap, and jQuery seemed old and busted. Gatsby, React, and... ]]>
</description>
<content:encoded><p><a href="https://ashfurrow.com/blog/gatsby-for-great-good/">In 2019, I rewrote this blog with Gatsby</a>. I outlined my reasons in that post, but basically I wanted to use similar technology to build my blog as I used day-to-day at work. Middleman, Bootstrap, and jQuery seemed old and busted. Gatsby, React, and TypeScript seemed so much more fun.</p> <p>When I launched the rewrite, someone on social media cautioned me &quot;I hope you don't regret this.&quot; At the time, I resented it. But unfortunately I do regret the decision.</p> <p>Gatsby is large, cumbersome, and slow. Its dependencies constantly change. It breaks under the weight of my many posts, to the point that Netlify is no longer able to build the site without a timeout.</p> <p>It turns out, you don't need GraphQL to turn markdown into markup.</p> <p>I looked into going back, to Middleman, but the dependencies are just so outdated and the code <em>is</em> pretty janky, that it made more sense to move forward, to something new.</p> <p>I chose <a href="https://www.11ty.dev/">11ty</a>, which is a JavaScript-based static site generator with a focus on simplicity and API stability. I wrote the old blog in 2014 using Bootstrap and jQuery, with a CSS preprocessor; the progress of browser standards means I don't need any of that anymore. (CSS Grids are amazing!)</p> <p>Now, 11ty doesn't really do as much as Gatsby. But I value the simplicity of maintainence over the Gatsby's promises of client-side performance. My blog just doesn't need the powerful features that Gatsby can provide.</p> <p>All I have to do is port the existing GraphQL implementation. Or, should I port the Middleman implementation? Why not both!</p> <p>So yeah. I'm using Claude Code for this project, and it's gone really well. It turns out AI coding assistants are really great at porting code between languages. I pointed Claude Code at the Gatsby and Middleman implementations, and have worked through an implementation plan piece by piece. This was actually a great project for me to really dive into the capabilities of agentic coding tools, since this is a project I've built twice before.</p> <p>I am concerned about code quality, especially plain CSS. AI is great at spewing out a lot of hard-to-maintain-code, and that seems extra true with CSS. To mitigate this, I'm running an experiment. I threw a weekend or two at the project two months ago to get it about 90% complete. Then, I just let it sit there. I wanted to forget the code so I can revisit it later, to dispassionately evaluate it without the thrill of &quot;getting so much done with AI&quot; clouding my judgement.</p> <p>But honestly, the main site is only 1000 lines of CSS. That's for a fully responsive design. And I'm not that great at CSS, so the bar that Claude has to clear is pretty low. I've actually learned quite a bit about web standards, scrutinizing the code that Claude had spit out.</p> <p>Unlike previous rewrites, I'm blogging about this one ahead of time. <a href="https://github.com/ashfurrow/blog/pull/520">The pull request is here</a>, if you're interested. GitHub's UI shows this as a massive increase in lines of code, only because Prettier formatted seven hundred markdown posts for the first time. I'll have exact numbers once I've finished, but 11ty has a lot less configuration and coding to accomplish the same task. My entire site builds locally in about ten seconds, compared with minutes on Gatsby.</p> <p>I still have a ways to go. The PR has an open task list, but it's mostly &quot;feature complete.&quot; Next steps are things like making sure the RSS feeds' permalinks match, validating the HTML and CSS, and testing. I know that the last twenty percent of a project tends to be eighty percent of the effort, but again, I've done this a few times before so I have a pretty good idea of what I'm doing.</p> <p>I just hope I don't regret this.</p> </content:encoded>
</item>
<item>
<title>
<![CDATA[ The Murderbot Blog ]]>
</title>
<link>https://ashfurrow.com/blog/the-murderbot-blog/</link>
<pubDate>Tue, 12 Aug 2025 00:00:00 GMT</pubDate>
<guid>https://ashfurrow.com/blog/the-murderbot-blog/</guid>
<description>
<![CDATA[ I&#39;ve been a huge fan of The Murderbot Diaries series by Martha Wells for a few years now, and was very excited to see it adapted to television on Apple TV+. Every adaptation of a story to a new medium has to make creative choices and tradeoffs; it&#39;s fun... ]]>
</description>
<content:encoded><p>I've been a huge fan of <a href="https://en.wikipedia.org/wiki/The_Murderbot_Diaries"><em>The Murderbot Diaries</em> series by Martha Wells</a> for a few years now, and was very excited to see it adapted to television on Apple TV+. Every adaptation of a story to a new medium has to make creative choices and tradeoffs; it's fun to pick apart the work to identify what's been changed, think about why that might have been done, and examine the impact on the story.</p> <p>As a fan of the books, I'm thrilled to see them adapted <em>at all</em> and I don't want anyone thinking that I dislike the show. It was a joy to see <em>The Rise and Fall of Sanctuary Moon</em> show-within-a-show come to life.</p> <p>This is an ensemble show, based on a single-person narrative novella. That was always going to be hard to adapt, so it makes sense that the production uses an ensemble cast to tell a larger story. More points of view makes it easier to tell a more complete story, and gives the audience more characters to relate to. But <em>too many</em> characters can create confusion, too. The show combined a few characters together and rearranged some of the relationships, to keep the story focused.</p> <p>So we have this ensemble cast telling a story from multiple perspectives, adapted from a very first-person limited-perspective book. The tradeoff here is that you get less time with the titular protagonist, who is admittedly a weirdo. It could be difficult for audiences to relate to SecUnit, especially in a visual format.</p> <p>These changes from the source material seem motivated to me, and so I find it easy to accept them and have fun with the story. Even as I wish we could spent more time with the inner life of SecUnit, I understand how that would be very difficult to portray.</p> <p>The story itself also had to be adapted to fit into ten episodes. This change was less effectively executed than the character changes, in my opinion. The pacing of the show would speed up and slow down so quickly that it felt kind of clumsy. Life-or-death action scenes would be punctuated by relationship drama. The seams of the adaptation were visible.</p> <p>The television show also nerfed the characters. This was a bummer, honestly. The human characters and SecUnit all make poor decisions and get themselves into unnecessary trouble. And I kind of see why. It's hard to tell a compelling story when all the characters are hyper-competent (that's part of why <em>Star Trek Voyager</em> is the way it is). Having the characters make mistakes also allows for more a more dynamic story, making it easier to adapt to television. This was harder for me to roll with, but I see the utility in it from a production and storytelling perspective.</p> <p>I've given these examples as a way to show that <em>motivated changes</em> can lead to a story that works better for a television audience, even as I (a fan) would have preferred something different. I'm not saying that the motivation is good or bad, or that the motivation makes the changes good or bad. I'm saying that I understand it, so I find it easy to roll with as a viewer.</p> <p>But there was one story shift that I don't understand that's been bothering me.</p> <p>In the books, sprawling corporations fight each other for power and control of a lot of human-occupied space called the Corporation Rim. It's a place ruled by contracts and force. The Corporation Rim is home to multigenerational indentured labour contracts, massive amounts of suffering, and wanton death – all for the sake of profit.</p> <p>Our humans, in the Preservation Alliance, exist outside the Corporation Rim. But they do interact with it, and it disgusts them. This is a key thing I love about the books: Preservation Alliance is depicted as an <em>actual, functioning utopia</em>. The planetary alliance has built a society where everyone has access to food and shelter, where menial labour has been automated, and where violent crime does not exist.</p> <p>By depicting Preservation Alliance this way, the books implicitly show that the cruelty and suffering of the Corporation Rim <em>is a choice</em>. It is optional. Something that our human characters avoid.</p> <p>So it really bothered me when the television adaptation depicted Preservation Alliance as so hapless and resource-starved that they were considering joining the Corporation Rim. I don't understand the motivation behind it. Granted, it's a <em>relatively minor</em> change that <em>doesn't necessarily</em> contradict anything in the books. But it does contradicts the story in my head. This was one of the most important background details of the setting to me and it kind of hurt to see it thrown away.</p> <p>Adaptations and creators don't owe anyone explanations about the story choices they make. But if I ever got the chance to ask the show runners a question, I know what I would ask.</p> </content:encoded>
</item>
<item>
<title>
<![CDATA[ Bias Towards Helpfulness ]]>
</title>
<link>https://ashfurrow.com/blog/bias-towards-helpfulness/</link>
<pubDate>Mon, 23 Jun 2025 00:00:00 GMT</pubDate>
<guid>https://ashfurrow.com/blog/bias-towards-helpfulness/</guid>
<description>
<![CDATA[ I&#39;ve been using Cursor for coding tasks lately, trying to explore what kinds of work it performs well and poorly. It&#39;s pretty good at most simple tasks. It&#39;s good-to-okay at some complicated tasks. But then, some simple tasks can stump it – usually in... ]]>
</description>
<content:encoded><p>I've been using Cursor for coding tasks lately, trying to explore what kinds of work it performs well and poorly. It's pretty good at most simple tasks. It's good-to-okay at some complicated tasks. But then, some simple tasks can stump it – usually in very niche domains. Other tasks are <em>so big</em> that they need to be broken into smaller pieces first – a classic project management problem.</p> <p>I ran into this last kind of problem recently, when I tried to prototype a large idea for this blog, my personal website. I told Cursor what we're doing and it started strong. It was making great progress when suddenly it got stuck, in a loop, on a <em>very</em> simple change to a config file.</p> <p>My approach had been too much, too fast. To refine my approach, I tried using a conversational LLM instead of Cursor. I've generally not used conversational LLMs like ChatGPT until a few months ago, because I hadn't found them to be that useful and because it's rational to be skeptical of tech hype. But people <em>are</em> using them, for all kinds of things. Conversational LLMs are replacing search, in terms of user behaviour. I had heard of developers using them to help think through ideas and plans, so why not try?</p> <p>I talked my idea through with the LLM and... it was actually pretty helpful! It was a bit like &quot;rubber duck debugging&quot; if the rubber duck could answer you. And lookup GitHub issues, and quote documentation, etc. I was pretty impressed. It validated my idea was a good idea and suggested some alternatives.</p> <p>The next day, I was meeting another developer for a coffee and my idea came up in our conversation. I explained my idea, asked his opinion, and the <em>first</em> thing he said <em>didn't answer my question at all</em>. Instead, he responded with a question of his own. (A <em>really good</em> question, too. Incisive.) I gave him my answer, and he asked a very good followup question: how much time was I interested in spending on this idea? Only when he understood the full context and my motivation did he give me his perspective.</p> <p>Conversational AI's have a <em>bias towards helpfulness</em>. That may sound absurd, but it's true: LLMs have been trained on helpful conversations from the internet (StackOverflow, for example). LLMs are given system prompts instructing them to answer user questions. They &quot;want&quot; to help us and it's important to be aware of that. This bias prevents LLMs from being able to distinguish prompts that are vague on purpose (users looking for general answers) and vague incidentally (users needing followup questions and/or pushback). LLMs are designed to help users <em>by answering their prompts</em>, not telling them when they're trying to do something really stupid.</p> <p>It's as though LLMs are bound by a local maxima of helpfulness. Sure, they're helping users with their requests. But they can easily, silently fail to consider the bigger picture. People are messy and they have messy problems.</p> <p>The developer I spoke to had the experience, expertise, and relationship with me to cut straight to the heart of my question. I hadn't meant this as an experiment, but it's interesting to think about: when asked the same question, the LLM responded with an answer but the developer responded with a question of his own. I think this is another case of learning what tasks an LLM can help with, or rather, learning the limitations of using an LLM for this kind of task.</p> <p>I want to clarify my stance here because I don't want to be labelled as either a hater or a booster. (Or labelled at all, thanks.) LLMs <em>do</em> have limitations, they <em>have</em> improved, and I <em>am</em> open to the idea that an LLM could be built that is capable of this kind of intentional, selective <em>un</em>helpfulness. To ask clarifying questions or push back on bad ideas. That an LLM product could even use previous interactions with me as context to tailor responses, similar to how a coworker or collaborator might. Indeed, <em>a lot</em> of companies are spending <em>a lot</em> of time and money trying to build AI assistants which develop a &quot;relationship&quot; with users. Maybe they will build something genuinely as helpful and incisive as another skilled human. But I would have to use it to believe it.</p> <p>Incidentally, both the developer and the LLM ultimately arrived at the same answer. But, the developer was better company.</p> </content:encoded>
</item>
<item>
<title>
<![CDATA[ Foresight ]]>
</title>
<link>https://ashfurrow.com/blog/foresight/</link>
<pubDate>Sun, 22 Jun 2025 00:00:00 GMT</pubDate>
<guid>https://ashfurrow.com/blog/foresight/</guid>
<description>
<![CDATA[ Imagine you are a software developer. It&#39;s the early 1970&#39;s and you make a living writing Basic Assembly Language to build software for the System/360 mainframe. You are great at your job and you enjoy it. You keep hearing about new &amp;quot;high level&amp;quot;... ]]>
</description>
<content:encoded><p>Imagine you are a software developer. It's the early 1970's and you make a living writing Basic Assembly Language to build software for the System/360 mainframe. You are great at your job and you enjoy it.</p> <p>You keep hearing about new &quot;high level&quot; programming languages that would allow you to write code in a way that could be &quot;compiled&quot; to run on different kinds of computers. In theory, this would be a huge benefit over writing assembly for just one kind of computer. But there's a catch: these compilers aren't reliable. The code they produce has bugs that wouldn't have existed if a human had written the equivalent application in assembly. The code is inefficient, it is a mess to debug, and you have to use a whole new tool, a compiler.</p> <p>Compilers introduce a layer of abstraction. Another build step. Another cost. Another skill. Using a compiler would <em>mediate the work of programming</em>, alienating a programmer from both their craft and their labour. <strong>Compilers come with tradeoffs</strong>. You don't really like these tradeoffs, personally, and decide to stick with BAL.</p> <p>But you keep an eye on new compilers.</p> <p>Over time, compilers become more reliable, more stable, more performant. There are a lot of new languages and tools and it's hard for you to know which ones to invest time into learning. (We all remember what happened to PL/I, am I right?)</p> <p>You decide to learn a new language named C in your spare time.</p> <p>You have a long and prosperous career.</p> <p>The End.</p> <hr /> <p>Imagine you are a software developer who considers themselves to be a moral person. It's the early 1970's and you make a living writing Basic Assembly Language to build software for the System/360 mainframe. You are great at your job and you enjoy it.</p> <p>You keep hearing about new &quot;high level&quot; programming languages that would allow you to write code in a way that could be &quot;compiled&quot; to run on different kinds of computers. In theory, this would be a huge benefit over writing assembly for just one kind of computer.</p> <p>But there's a catch: <strong>these compilers are cursed</strong>.</p> <p>Compilers are conjured by programmers wearing dark cloaks, chanting under the cover of a new moon. It's an eldritch ceremony. No one <em>really</em> understands how a compiler works, other than... <em>the cost</em>. Every time a programmer compiles a program, <em>the cost</em> is extracted. Every time a programmer compiles a program, someone – somewhere – suffers. Someone suffers just a little bit, and the programmer doesn't get to see it.</p> <p>(Also compilers are slow, unreliable, hard to debug, etc. All the same tradeoffs readers are familiar with, they're just <em>also</em> cursed.)</p> <p><strong>Compilers come with tradeoffs</strong>. You don't really like these tradeoffs, personally, and decide to stick with BAL.</p> <p>But you keep an eye on new compilers.</p> <p>Over time, compilers become more reliable, more stable, more performant. The curse remains. You see the enormous value in using a compiler, you see how much more productive you could be if you used this tool.</p> <p>You try using one compiler, and it doesn't work. You wait a while, and you try another. A new one. It <em>does</em> work. In fact, it <em>exceeds your wildest expectations</em>. You feel conflicted.</p> <p>You consider yourself a moral person. You know about the curse. You see other programmers declining to make the switch, correctly pointing to the tradeoffs.</p> <p>&quot;Compilers aren't worth it,&quot; the other programmers assert. &quot;The curse is an unacceptable tradeoff! We refuse to use a compiler!&quot;</p> <p>But here's the thing. Programmers aren't the ones who get to decide what is worth the cost.</p> <p>You can see ahead. You see jobs writing assembly getting harder to come by. They don't <em>entirely</em> disappear, but... you see the industry moving on. You see an entire new generation of programmers entering the workforce who have <em>never not</em> used a compiler.</p> <p>You have bills to pay, a career to think about, and you can see ahead. And, these compilers are actually pretty fun and useful. You find yourself excited about all the cool things you could build with them.</p> <p>You still consider yourself a moral person. And you make a decision.</p> </content:encoded>
</item>
<item>
<title>
<![CDATA[ Camera Time ]]>
</title>
<link>https://ashfurrow.com/blog/camera-time/</link>
<pubDate>Sat, 31 May 2025 00:00:00 GMT</pubDate>
<guid>https://ashfurrow.com/blog/camera-time/</guid>
<description>
<![CDATA[ Recently, I published my first photo blog post since 2018. (Yes I have a separate photo blog, because of course I do.) So what&#39;s up with that? Nothing better than a blog post about another blog post. I haven&#39;t really been doing a lot of photography since... ]]>
</description>
<content:encoded><p>Recently, I published <a href="https://photos.ashfurrow.com/downtown-in-the-rain">my first photo blog post since 2018</a>. (Yes I have a separate photo blog, because of course I do.) So what's up with that? Nothing better than a blog post about another blog post.</p> <p>I haven't really been doing a lot of photography since the pandemic, but I had been increasingly drawn to it over the past six months. Creativity is actually something I've found to be missing in my life – when I found a renewed interest in photography, I decided to follow it. I started taking more photos on my iPhone, then I got out my film cameras since that's what I <em>had</em> been mainly shooting. But film wasn't working for me, so I got out my digital camera, a FujiFilm X100S from 2014. And I loved it.</p> <p>But, that camera has some limitations I was hitting. First, it's a fixed focal length and I felt myself wanting something with more reach. I've only used prime lenses since 2014 and I enjoyed their limitations. Prime lenses helped me improve my composition skills, but now I'm ready for a zoom. The X100S is also from 2014, which means it's from near the <em>very beginning</em> of the industry's transition to mirrorless. So, it's fiddly.</p> <p>Don't get me wrong – I've taken some of my favourite shots with the X100S. I have a large canvas print of <a href="https://photos.ashfurrow.com/losing-myself-in-tokyo/photos/2580931">a long exposure of Tokyo taken from Roppongi Tower</a> hanging in my office, and I took that with the X100S. Back when I used to travel a lot, The X100S was exactly what I needed. But as I rediscover photography in Atlantic Canada, I started to feel its limitations. I kept shooting with it anyway.</p> <div class="wide"> <p><img src="https://ashfurrow.com/blog/camera-time/tokyo.jpg" alt="Photo of Tokyo just after sunset" /></p> </div> <p>I started looking around and realized that you can buy really nice used DSLRs for not that much. I had a sick DSLR kit and I daydreamed about recreating that same setup. But it felt weird to invest in a DSLR kit when they are on their way out. And in the decade since I bought my last digital camera, the X100S, mirrorless cameras have gotten really good. They have some distinct advantages over DSLRs.</p> <p>Mirrorless cameras are smaller and weigh less than DSLRs – and their lenses too. They often have a tilting LCD screen and I was interesting in using it as a waste-level viewfinder (like my TLR camera). And unlike DSLRs, mirrorless cameras can be adapted to work with my film lenses. My (only) tattoo is an optical diagram of my favourite lens, the Leica Summicron 50mm f/2. The idea of using my Summicron lens on digital really tickled me.</p> <div class="narrow"> <p><img src="https://ashfurrow.com/blog/camera-time/tattoo.jpeg" alt="Photo of my tattoo" /></p> </div> <p>I was concerned about some of the downsides to mirrorless cameras, like shorter battery life and feeling more like a computer than a camera. But the thing I was most concerned about was having to use an electronic viewfinder. I'm used to being able to see, optically, the actual scene that I'm shooting. I was reluctant to give that up. So as an experiment, I started using my X100S with its electronic viewfinder. (In over ten years, I had barely used it.) The refresh rate was kind of laggy but I got used to it pretty quickly. I was actually enjoying the way the EVF gave me an exposure preview of the photo that the camera was actually going to record when I hit the shutter button – that's something that DSLRs just can't do. I figured that if the older X100S was usable, then a newer mirrorless camera would be great (spoilers I was right).</p> <p>So then the question was: which camera system to get? Usually when a photographer picks a camera system, they're either just getting started or they're experienced and switching systems. I was in a distinct position to knowing what I wanted <em>but also</em> starting fresh. So let me outline my thinking.</p> <p>Canon and Nikon had both initially missed the boat on mirrorless. Sony, FujiFilm, Olympus, and other manufacturers hadn't been caught in the same &quot;innovator's dilemma&quot; as the two market-leading DSLR makers, and so they had had a huge head start. Canon was also being weird about letting third party lens manufacturers not build on its new mirrorless lens mount, which gave me a bad vibe. And to be honest, Nikon digital cameras have always given me a bad vibe.</p> <p>So I ruled out the giants. I considered Micro Four Thirds but decided against it. That narrowed it down to Sony or FujiFilm. I spent a lot of time researching opinions online and thinking about what I actually wanted in a camera.</p> <p>Primarily, I wanted a camera that I would feel inspired by. When I was shooting on my walk to-and-from work in Manhattan every day, I didn't need much inspiration. Photography was automatic. Now, working from home in Fredericton, photography is a decision. It's something I go and do. I've been know to struggle with creative motivation so I was looking for a tool that would get me excited to use it.</p> <p>I tried some cameras out in-person. <em>By far</em>, the FujiFilm cameras I tried were the clear winners. The Sony cameras reminded me that I'm using a computer, while the FujiFilm cameras felt like old film cameras. Many FujiFilm cameras have physical dials for shutter speed and ISO, and their lenses usually have aperture rings. It felt natural. After some more research, I made a decision on a model. Normally, I would buy a used camera and lens, but FujiFilm's used market is currently overinflated (due to a lot of factors). So I picked a current model.</p> <p>But before I bought anything, I hit a wall. I became preoccupied with anxiety that all this excitement was just Gear Acquisition Syndrome. When I first got into photography, I compulsively and continuously upgraded my gear. Over the years, I have bought cameras that I didn't really need and that I quickly moved on from. Nerds call this GAS, and I've worked hard to get it under control. Now I found myself worried that my renewed interest in photography was somehow GAS in disguise, that I wasn't authentically interested in photography at all. I wanted to make a responsible decision, both financially and creatively.</p> <p>Because gear doesn't matter. You can take great photos on bad cameras. And you can have a lot of fun doing it. Here is a photo I love, and the camera I used has an entire <em>two</em> shutter speeds – plus bulb mode!</p> <div class="wide"> <p><img src="https://ashfurrow.com/blog/camera-time/paris.jpg" alt="Black and white photo of Paris taken on a fold-out camera" /></p> </div> <p>It's the photographer that matters, not the camera. (Of course, it's easier to say &quot;gear doesn't matter&quot; when you have nice gear. And I do have a nice film kit.) I started questioning whether I should buy a new digital camera at all. Wasn't my X100S enough?</p> <p>I sat with this for some time. I talked this over with a few people who know me. And I kept taking photos with the X100S. I started editing those photos in Apple Photos, then tried some more sophisticated tools like Photomator and ON1 Photo Raw, before (reluctantly) reactivating my Lightroom subscription. I had really been enjoying editing photos, in a way that I hadn't for a long time.</p> <p>Not suddenly, but slowly, I realized that my anxiety over a possibly &quot;inauthentic&quot; interest in photography was unfounded. I wasn't trusting myself. It does make sense to sit on a big purchase decision like this, but I had. I <em>had</em> thought it over. And I knew I didn't <em>need</em> it; I <em>wanted</em> it. (Confusing these two is an symptom of GAS.) I talked it over one last time with Ashley and then I hit the purchase button.</p> <p>That was a month ago. So which camera did I get?</p> <p>&quot;Gear doesn't matter.&quot;</p> <div class="narrow"> <p><img src="https://ashfurrow.com/blog/camera-time/me.jpeg" alt="Photo of me taking a photo with a tripod" /></p> </div> <p>I'll be publishing more photo blog posts <a href="https://photos.ashfurrow.com/">over at my photo blog</a>. I'm exploring some new editing styles and I plan to write about that process over there. I don't really know where people are sharing their photos online anymore, to get photo critique; let me know if you have suggestions. See you there!</p> </content:encoded>
</item>
</channel>
</rss>