<?xml version="1.0" encoding="UTF-8"?><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[Paul Stamatiou]]></title>
        <description><![CDATA[PaulStamatiou.com - Technology, Design and Photography]]></description>
        <link>https://paulstamatiou.com</link>
        <image>
            <url>https://paulstamatiou.com/favicon.svg</url>
            <title>Paul Stamatiou</title>
            <link>https://paulstamatiou.com</link>
        </image>
        <generator>RSS for Node</generator>
        <lastBuildDate>Wed, 11 Nov 2026 00:17:02 GMT</lastBuildDate>
        <atom:link href="https://paulstamatiou.com/posts.xml" rel="self" type="application/rss+xml"/>
        <copyright><![CDATA[All rights reserved 2005-2026]]></copyright>
        <item>
            <title><![CDATA[The Leica reset]]></title>
            <description><![CDATA[<img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09267.jpg" alt="Holding the Leica M EV1 on Mt. Tamalpais" width="4000" height="2665" /><br /><small>With a 75mm and Owlkrown grip on Mt. Tam.</small><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC08952.jpg" alt="Leica M EV1 body with a Leica body cap on a wooden table" width="4000" height="2769" /><br /><small>Leica M EV1 just unboxed.</small><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/IMG_4197.jpg" alt="Holding the Leica M EV1 over a running track" width="4000" height="2680" /><br /><small>M EV1 with the 28mm, Owlkrown grip, and Peak Design wrist strap.</small><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09294.jpg" alt="Leica M EV1 on a tripod on a dry, grassy hillside on Mt. Tamalpais" width="3999" height="2621" /><br /><small>Shooting on Mt. Tam.</small><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09264.jpg" alt="Leica M EV1 resting in dry grass above the hills of Marin" width="4000" height="2665" /><br /><small>M EV1 on Mt. Tamalpais.</small><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09154.jpg" alt="Leica M EV1 and Voigtlander primes from above, close up" width="4000" height="2665" /><br /><small>M EV1 with Voigtlander prime lenses.</small>
<p>I&#x27;ve always admired Leica cameras, especially their flagship Leica M. The iconic and minimal design, excellent build quality, consistent shooting experience, and brand legacy have always intrigued me.</p>
<p>I&#x27;ve primarily shot with Sony mirrorless cameras over the years (with some small pit stops with Canons and Fujis)<sup><a rel="footnote" href="#footnote-1" id="r1">1</a></sup>. I used to prioritize camera features over everything else. The latest <a href="https://turbo.paulstamatiou.com/gear/leica-m-ev1">Leica M EV1</a> is a bit more opinionated and like other M models lacks features that cameras a fourth the cost have.</p>
<p>I won&#x27;t bore you with the details, but it doesn&#x27;t even have a video mode. It doesn&#x27;t have IBIS (in-body image stabilization, basically standard on any high-end mirrorless camera), the screen doesn&#x27;t even tilt, it doesn&#x27;t have weather sealing, and of course it doesn&#x27;t have autofocus. And it has the ergonomics of a brick; people usually buy third-party cases and grips to make it tolerable.</p>
<p>Leica M models have always had premium pricing and this latest M EV1 is no exception, selling for around $9,000 for just the body. With that stratospheric price they&#x27;ve only been a warm thought for me, not something I could justify spending on myself for a hobby. That is, up until now. My lovely wife Katherine recently got me one for my 40th birthday.</p>
<p>This article isn&#x27;t really a camera review; I&#x27;ll leave that to the professionals. This is more of a reset in how I&#x27;m approaching photography now.</p>
<img src="https://media.paulstamatiou.com/photostream/2026/09/27/2026-09-27-223300-clv9jfw/original.jpg" alt="The Sausalito waterfront on a clear day" width="4000" height="2657" /><br /><br /><img src="https://media.paulstamatiou.com/photostream/2026/08/09/2026-08-09-205900/original.jpg" alt="Sutro Tower above the fog at the end of a San Francisco street" width="2657" height="4000" /><br /><br /><img src="https://media.paulstamatiou.com/photostream/2026/07/26/2026-07-26-031600/original.jpg" alt="The Golden Gate Bridge silhouetted between houses at sunset" width="3500" height="2325" /><br /><br /><img src="https://media.paulstamatiou.com/photostream/2026/08/01/2026-08-01-220600/original.jpg" alt="Golden grass against a blue sky on Mt. Tamalpais" width="4000" height="2657" /><br /><br /><img src="https://media.paulstamatiou.com/photostream/2026/08/01/2026-08-01-221800/original.jpg" alt="Trees on a grassy Mt. Tamalpais ridge above the Pacific" width="4000" height="2657" /><br /><br /><img src="https://media.paulstamatiou.com/photostream/2026/09/11/2026-09-11-000900-9ky82sx/original.jpg" alt="Charlie the poodle lounging on the couch" width="4000" height="2657" /><br /><br /><img src="https://media.paulstamatiou.com/photostream/2026/08/01/2026-08-01-223400/original.jpg" alt="A windswept tree on a golden Mt. Tamalpais hillside" width="4000" height="2657" /><br /><br /><img src="https://media.paulstamatiou.com/photostream/2026/06/28/2026-06-28-042800/original.jpg" alt="Palm trees along a rocky shoreline at dusk" width="2844" height="3000" /><br /><br /><img src="https://media.paulstamatiou.com/photostream/2026/07/22/2026-07-22-191700/original.jpg" alt="Charlie in his favorite spot, looking out a sunlit window" width="3000" height="1994" /><br /><br /><img src="https://media.paulstamatiou.com/photostream/2026/07/26/2026-07-26-025400/original.jpg" alt="A lone figure at the crest of a Pacific Heights street at golden hour" width="3499" height="2325" /><br /><br /><img src="https://media.paulstamatiou.com/photostream/2026/07/26/2026-07-26-030100/original.jpg" alt="Sunset over the Bay through the trees along the Baker Street steps" width="3500" height="2742" /><br /><br /><img src="https://media.paulstamatiou.com/photostream/2026/08/09/2026-08-09-201200/original.jpg" alt="Sutro Tower rising out of the fog" width="2657" height="4000" /><br /><br /><img src="https://media.paulstamatiou.com/photostream/2026/08/09/2026-08-09-211000/original.jpg" alt="Dolores Park with the San Francisco skyline behind" width="4000" height="2657" /><br /><br /><img src="https://media.paulstamatiou.com/photostream/2026/08/09/2026-08-09-212500/original.jpg" alt="A busy street corner outside Tartine Bakery" width="4000" height="2657" /><br /><br /><img src="https://media.paulstamatiou.com/photostream/2026/07/05/2026-07-05-164400/original.jpg" alt="Victorian houses on a sunny San Francisco street corner" width="4000" height="2659" /><br /><br /><img src="https://media.paulstamatiou.com/photostream/2026/08/01/2026-08-01-222400/original.jpg" alt="Forested hills on Mt. Tamalpais with the ocean beyond" width="4000" height="2657" /><br /><br /><img src="https://media.paulstamatiou.com/photostream/2026/07/26/2026-07-26-022700/original.jpg" alt="Looking down the Lyon Street Steps toward the Palace of Fine Arts and the Bay" width="4000" height="2657" /><br /><br /><img src="https://media.paulstamatiou.com/photostream/2026/08/01/2026-08-01-223200/original.jpg" alt="A winding road along Mt. Tamalpais above the Bay" width="4000" height="2657" /><br /><br /><small>Shot on the Leica M EV1.</small>

<h3>Overoptimizing my hobby</h3>
<p>I haven&#x27;t shot much at all in the last seven years; phone shots aside of course. I sort of ruined my relationship with photography by making it too buttoned up and having too high a bar for my output. It went from being a fun way to capture what I see and experience to being too precise and too tiring to create anything that felt good enough to publish and share.</p>
<p>When I first got into photography in the early 2000s, I was shooting with a few Sony point-and-shoots like the <a href="https://paulstamatiou.com/gear/sony-cybershot-dsc-p9">P9</a>, W1, and T1. I then got my first DSLR camera, a Nikon D90. Then I shifted to mirrorless with the NEX-5 in 2010 before exploring some Canon and Fuji cameras. These photos were much more casual, largely just posting them on Flickr, Facebook, and the occasional product shots for my blog posts. It was definitely a simpler time.</p>
<p>I changed that in the 2010s as I began shooting with increasingly more prosumer Sony mirrorless cameras (a7S, <a href="https://paulstamatiou.com/gear/sony-rx1r">RX1R</a>, and a bunch of a7R models). I shot <a href="https://paulstamatiou.com/photos/japan/two-weeks-in-japan">this Japan trip</a> entirely on the RX1R. Trips became less about enjoying travel and more about the pursuit of content that I could manicure into bespoke photosets — basically mini-websites I would design and build myself from scratch to tell the story of my trips. It began as a fun way to stretch not only my photography skills but also design and web development skills with each photoset and countless subsequent redesigns.</p>
<p>The stakes got higher with each trip. I <em>had</em> to make an even better photoset. I got more gear to help with it. Bigger, heavier lenses. ND filters, variable grad ND filters, Kaesemann circular polarizers. Travel tripods, carbon fiber tripods, and monopods. Reflectors. Diffusers. Studio lighting. Phone-controlled smart intervalometers. A water-cooled and overclocked <a href="https://paulstamatiou.com/building-a-windows-10-lightroom-photo-editing-pc">faster photo-editing machine made for Lightroom</a>.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2016/03/pstam_sirui_t025x_auckland-2000.jpg" alt="Sony camera on a Sirui travel tripod next to a camera backpack, overlooking the Auckland skyline in New Zealand" width="2000" height="2227" /><br /><br /><img src="" alt="undefined" width="undefined" height="undefined" /><br /><br /><img src="https://turbo.paulstamatiou.com/p/sets/africa-2018/south-serengeti/copyright-paulstamatiou_com-DSC2888-2000.jpg" alt="Leopard peering out from between tree branches in the Serengeti" width="2000" height="2000" /><br /><br /><img src="https://turbo.paulstamatiou.com/p/sets/africa-2018/north-serengeti/copyright-paulstamatiou_com-DSC4646-2000.jpg" alt="Close-up of an elephant&#x27;s face and trunk in the Serengeti" width="2000" height="2629" /><br /><br /><img src="https://turbo.paulstamatiou.com/p/sets/africa-2018/north-serengeti/copyright-paulstamatiou_com-sony-a7riii-safari-setup-DSC9913-2000.jpg" alt="Sony a7R III and telephoto lens resting on a safari vehicle, aimed at a lion on a rock outcrop" width="2000" height="1500" />
<small>Shooting with my Sony gear years ago in <!-- --><a href="https://paulstamatiou.com/photos/new-zealand/nelson-lakes-wharariki-beach">New Zealand</a><!-- --> (2016) and <!-- --><a href="https://paulstamatiou.com/photos/africa">Africa</a><!-- --> (2018).</small>
<p>After the photos were captured the work began. I would spend months of spare time reviewing thousands of photos; one trip resulted in over 800GB of photos, videos, HDR shots, and timelapses. The hours in Lightroom got longer and longer, endlessly paging through shots, dragging sliders back and forth, then back again to find some aesthetic sweet spot I&#x27;d never quite find.</p>
<p>I also had to deal with the aftermath of this hobby: terabytes of RAW photos and videos. I&#x27;ve gone through a handful of different organization and <a href="https://paulstamatiou.com/gear/owc-express-4m2-nvme-ssd-enclosure">backup setups</a>. The vast majority of this content I would never touch again after a decade.<sup><a rel="footnote" href="#footnote-2" id="r2">2</a></sup></p>
<p>The bar I&#x27;d set for those photosets kept climbing until nothing felt worthy of the effort. When Covid came around I wasn&#x27;t going on any big trips, so I focused my spare time on other endeavors like learning iOS development and building a <a href="https://paulstamatiou.com/stocketa">side-project app</a>.</p>
<p>When the world recovered and travel ramped up again, I found myself content with shooting with only my phone (albeit in RAW, paired with the Darkroom app).</p>
<p><strong>I had optimized my photography hobby to death.</strong> I never lost complete interest in photography. I still loved that feeling of holding a camera and snapping off a shot with an interesting composition, but letting it consume my life as much as it did felt wholly unappetizing.</p>
<h3>Leica</h3>
<p>I had always told myself that if I ever got back into photography, it had to be different: a more compact camera setup, no marathon editing sessions, and publishing individual shots instead of curated travel photosets.</p>
<p>I&#x27;m not going to sit here and posture that that sort of shooting ethos can only be done with a pricey Leica. You can do that with many far more affordable cameras, your phone, and even a disposable film camera. As far as I&#x27;m concerned, digital cameras have pretty much all been amazing for close to a decade now. Everything we&#x27;ve added since feels so very incremental, often just adding minor creature comforts. For example, I shot <a href="https://paulstamatiou.com/photos/africa">this leopard photo</a> eight years ago and I can&#x27;t think of anything a modern camera would have done to significantly improve upon it.</p>
<p>I like to surround myself with and use simple, elegant, and well-designed tools. They&#x27;re a source of inspiration. They&#x27;re often stripped down to only the essentials to focus on the task at hand. I love my heavy and large <a href="https://turbo.paulstamatiou.com/gear/heath-mugs">Heath mugs</a>. My solid copper <a href="https://turbo.paulstamatiou.com/gear/baronfig-squire-pen">Baronfig pen</a>. I love glancing at my <a href="https://turbo.paulstamatiou.com/gear/apple-imac-g3">iMac G3</a> and <a href="https://paulstamatiou.com/revisiting-the-apple-ipod">original iPod</a> while working in my office. If I were more into audio gear, I&#x27;m sure I would have a few Teenage Engineering items like the elegant TP-7 field recorder.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09072v2.jpg" alt="Leica M EV1 with a Voigtlander lens, straight on" width="4000" height="2776" />
<p>I&#x27;ve always appreciated Leicas from a distance. I&#x27;ve rarely used them. Just the occasional checking out a friend&#x27;s Q or shooting a single shot with an M10. But I remember the feeling. The sturdy, cold metal frame with no humps or sculpted grips, just a clean rounded rectangle. The typeface on the frame and in the menus. And of course the shock that what I was holding was full-frame and remained remarkably compact.</p>
<p>Even looking at my Leica M now as I&#x27;m writing this, I&#x27;m most inspired by the amount of restraint they&#x27;ve had over the years. Pick up an M from four decades ago and you can still tell it&#x27;s the same camera and formula. Sure, this particular model is the most controversial, opting for an EVF over an optical rangefinder, but aside from that there&#x27;s so much they&#x27;ve held off on touching over the years. That alone is a near-impossible feat for any product to achieve today, especially in software in our current age of AI development where it&#x27;s all <a href="https://paulstamatiou.com/2025-year-in-review#restraint-in-ai">too easy to keep adding more</a> and more.</p>
<h3>The M EV1</h3>
<p>I took notice when Leica launched the <a href="https://turbo.paulstamatiou.com/gear/leica-m-ev1">M EV1</a> last year. It drops the optical rangefinder and replaces it with an EVF (electronic viewfinder), something previously only available as a bulky $955 add-on. That single change was huge news in the world of Leica M enthusiasts. It dramatically simplifies the shooting experience if you ask me.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC08932.jpg" alt="Leica M EV1 with the Voigtlander APO-Skopar 75mm, straight on" width="3999" height="3200" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09123.jpg" alt="Leica M EV1 with the Voigtlander primes" width="4000" height="2665" />
<p>It&#x27;s that change that made the M EV1 really catch my attention and feel more approachable. It&#x27;s also the most controversial part of this camera. Some enthusiasts say it&#x27;s not a true Leica M. But to understand that, you need to understand a bit more about what a rangefinder is, and why the new M EV1 is no longer a rangefinder camera. It&#x27;s also important to note the M EV1 is not a replacement for the regular M models; it&#x27;s its own distinct product line. It&#x27;s basically an M11 with an EVF.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC08979.jpg" alt="Holding the Leica M EV1 with a Voigtlander lens" width="4000" height="2665" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09077v2.jpg" alt="Leica M EV1 three-quarter view" width="4000" height="2613" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09105v2.jpg" alt="Rear of the Leica M EV1, showing the built-in EVF window and screen" width="4000" height="2665" /><br /><br /><small>No hump with the EVF built into the body.</small>
<h3>What is a rangefinder?</h3>
<p>While all Leica M models are manual-focus only, all previous generations were also rangefinders. With most high-end modern digital cameras you&#x27;re accustomed to, when you look into the EVF, you see exactly what the sensor sees: a real preview of your exposure and depth of field. And since it&#x27;s a real preview, that also means there&#x27;s no <em>parallax</em>. That&#x27;s something you&#x27;ll hear often when it comes to previous Leica M models. Parallax refers to the optical rangefinder being physically offset from the lens, so that at closer distances what you see in the viewfinder differs from what the lens captures.</p>
<p>Since the rangefinder is entirely separate from your lens, it also means you don&#x27;t have the same focal length. For example, if you&#x27;re shooting with a 50mm lens, the area you&#x27;ll capture will only be a small portion inside what you see in the rangefinder viewfinder. To deal with that, rangefinder Leicas employ <em>framelines</em> (illuminated projected lines to indicate frame rectangles) inside the viewfinder to indicate where various focal ranges would capture. Some people really appreciate the rangefinder style of composing your shot as you can also see what&#x27;s <em>about</em> to enter your frame.</p>
<h3>Leica M rangefinder example</h3>
<p>It&#x27;s a bit of a tricky concept to talk about, so I built this interactive preview to illustrate how rangefinders work.</p>
<p>Here&#x27;s how it works:</p>
<ul>
<li><strong>Framelines:</strong> Leicas have a few different sets of frameline pairs. The ones you see depend on what lens you have attached. If you have a 50mm lens, your Leica M rangefinder will load the framelines for 50mm and 75mm lenses. The outer framelines are for the wider focal length, so in this case 50mm.</li>
<li><strong>Composition:</strong> What appears within the framelines for your lens is roughly what will be captured when you take a photo. The actual frame is usually a little larger than the lines show. The viewfinder here is not a real preview of your photo. It won&#x27;t show exposure or bokeh the way an EVF does, since an EVF previews through the lens.</li>
<li><strong>Focusing:</strong> There&#x27;s a small, rectangular focusing rangefinder patch showing a ghosted/double image in the middle of the viewfinder. You place that patch over your subject and focus until the two images align and that patch is sharp. If they&#x27;re not in focus, you&#x27;ll see two images on top of each other, offset horizontally. It can be a challenge to nail, and rangefinder photographers tend to find areas of contrast in the subject to focus on, then recompose as needed.</li>
</ul>
<div>Please read <a href="https://paulstamatiou.com/the-leica-reset/" title="The Leica reset">this article</a> in a browser to try the interactive rangefinder demo.</div>
<p>In this demo, I provided a few example photos so you can see how focusing can become more challening when there&#x27;s less contrast in the middle of the frame.</p>
<p>Optical rangefinders make it hard to frame your composition with wide-angle lenses, telephoto lenses, and physically large lenses. Lenses wider than the viewfinder&#x27;s widest framelines need an external viewfinder, large lenses block a corner of your view, and telephoto lenses leave you with only a tiny sliver of a preview.</p>
<h3>The Leica M EV1 is not a rangefinder</h3>
<p>Now it becomes a bit clearer why adding an EVF is such a big deal. It&#x27;s still manual focus, but now you see exactly what the lens sees. To aid in focusing you may rely on digital features like focus peaking (highlighting high-contrast edges in a bright color) and magnification to nail focus. This means you&#x27;re free to use a lens of any focal length you want without worrying about a particularly challenging focusing and viewfinder experience.<sup><a rel="footnote" href="#footnote-3" id="r3">3</a></sup></p>
<img src="https://turbo.paulstamatiou.com/uploads/2026/09/IMG_4347.jpg" alt="Live view of a San Francisco street on the Leica M EV1&#x27;s screen" width="3024" height="4032" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/IMG_4372.jpg" alt="Framing a hillside sunset on the Leica M EV1" width="4000" height="3390" />
<p>EVF aside, I personally think the Leica M recipe is still there. Great build quality paired with iconic, minimal design inside and out. And with recent rumors of Leica being acquired by a private equity and venture capital firm, I was even more keen on buying a Leica in case future models diminish in quality with a new owner.</p>
<h3>Unboxing</h3>
<p>This is my first Leica, so I can&#x27;t really tell you how this compares to unboxing an M11 or a Q3, but it&#x27;s significantly more elevated than unboxing a Sony a7 body. It&#x27;s closer to unboxing a watch than a mirrorless camera. It&#x27;s more along the lines of something you keep for years, if not pass down through generations, rather than a gadget you replace when the new version rolls around.</p>
<p>Before you get to the actual camera box, there&#x27;s a thin cardboard layer with a label indicating the model. Unfortunately this outer box is too thin to provide any real protection to the inner box. My inner box arrived dented, as B&H Photo does a poor job packaging five-figure orders.</p>
<img src="" alt="Opening the kraft outer box of the Leica M EV1" width="1440" height="1080" /><br /><small>Opening the outer Leica box.</small><br /><br /><img src="" alt="Lifting the lid off the inner box to reveal the Leica M EV1" width="1460" height="1920" /><br /><small>Revealing the M EV1.</small>
<p>It pops open from all sides like a clamshell revealing its pearl. Sorry, I know that sounds cheesy but it was a neat feeling seeing it for the first time. It was clearly an intentional effect and feeling that Leica was going for.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC08879.jpg" alt="Leica M EV1 inner box with its printed sleeve, inside the opened kraft outer box" width="3588" height="4000" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC08882.jpg" alt="Tone-on-tone Leica logo debossed into the matte black lid" width="4000" height="2709" />
<p>The inner box is a matte black cube wrapped in a sleeve printed with product details. You can tell someone paid attention to the layout and typography on this sleeve between the "LEICA M EV1" font perfectly sized to span the sleeve&#x27;s width, and the red Leica logo placed at the same location as the tone-on-tone Leica logo debossed into the lid below.</p>
<p>Lifting the lid of the matte black cube is a slow, two-handed affair similar to Apple&#x27;s product packaging with tight clearances to make the opening more of a ritual.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC08880.jpg" alt="Leica M EV1 body sitting upright on its white pedestal inside the box" width="4000" height="3183" />
<p>The M EV1 body is the first thing you see upon lifting off the top of the box. There&#x27;s no protective overwrap shielding it from view. The M EV1 is poised upright on a white pedestal, looking more like a gallery display piece than a digital camera.</p>
<p>The bright red Leica logo first drew my attention to the timeless, restrained rectangular form with gently rounded edges. There&#x27;s no traditional protruding viewfinder hump like you see on other cameras. Instead the viewfinder is fully within the body to maintain its graceful figure. That design detail really makes it feel more stealthy. A few more notches in the direction of a point-and-shoot feel; a few notches away from feeling like you&#x27;re a professional photographer. My old Sony RX1R that I loved had a similar style.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09377.jpg" alt="Close-up of the Leica M EV1 top plate, red dot, and lens" width="4000" height="2665" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09072v2.jpg" alt="Leica M EV1 with a Voigtlander lens, straight on" width="4000" height="2776" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09085v2.jpg" alt="Leica M EV1 side profile" width="4000" height="2665" />
<p>The smooth matte black paint finish looks great in person, especially coming from years of the slightly bumpy, textured finish on Sony a7 bodies.</p>
<p>The top of the body is all black, with the exception of a small model name written on the hot shoe. The rest of the body is wrapped in diamond-checked leatherette like the Q. I personally prefer this pattern over the faux-grain leatherette on the M11.</p>
<p>Lifting the magnesium and aluminum alloy body out, I was immediately amazed at how light it is for a full-frame camera body. Of course there&#x27;s no battery or lens in it yet to weigh it down, but this is already a night and day difference from my Sony body. I carefully placed my fingers in places that wouldn&#x27;t leave noticeable fingerprints, but I quickly learned the camera does a nice job of avoiding that anyways.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC08896.jpg" alt="Holding the Leica M EV1 body for the first time" width="4000" height="2665" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09173.jpg" alt="Leica M EV1 main menu showing the Lens Detection setting" width="4000" height="2665" />
<p>Looking around the M EV1 body, I quickly noticed another thing. There are no little plastic flap doors on the side hiding a ton of ports and memory card slots. Instead, there&#x27;s just a single USB-C port on the bottom, and the SD card slot lives inside the battery compartment. It&#x27;s stripped to the essentials. No ports for video out or flash sync; that&#x27;s not the vibe for a camera geared toward street photographers.</p>
<p>The only less-than-ideal thing is that the USB-C port is on the bottom, which means you have to do some gymnastics to charge it, or place it screen-down on a soft surface to avoid scratches. Definitely reminds me of the Apple Magic Mouse charging location. And the USB-C port is exposed with no flap or door protecting it. A not-so-subtle reminder this camera is not weather sealed, which I definitely found surprising for such an expensive camera.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC08891.jpg" alt="Opened Leica M EV1 box with the certificate card and the camera on its pedestal" width="3507" height="4000" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC08890.jpg" alt="Leica quality certificate card inside the box" width="4000" height="2665" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC08894.jpg" alt="Strap compartment in the bottom of the Leica M EV1 box" width="4000" height="3111" />
<p>Below the body there&#x27;s a folded white card that verifies the camera has been hand-assembled and met Leica&#x27;s stringent QA and mechanical testing in Wetzlar, Germany.</p>
<p>Continuing below, there are two compartments housing the battery, strap, and USB cable. Leica continues with the trend of not having any small plastic pouches to rip open. Everything is already at home in its own little compartment.</p>
<p>At this point I was pretty motivated to pop the battery in and get things going. But due to my own paranoia, the first thing I do with any new camera is place a screen protector on it. After researching a bit, I actually found that a third-party screen protector (the brand "Expert Shield") had better reviews than Leica&#x27;s own display protector accessory, so I went with that.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09114v2.jpg" alt="Leica M EV1 with the battery released, showing the SD card slot" width="4000" height="2665" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09116v2.jpg" alt="Close-up of the Leica M EV1 battery compartment and SD card slot" width="4000" height="2665" />
<p><strong>Battery design detail</strong><br/>
Leica&#x27;s quest to avoid unnecessary doors on the M continues with the battery compartment. Instead of having a battery door, the battery itself serves as the bottom of the camera once the battery is inserted. The battery sits in there, spring-loaded. One satisfying pull of the machined silver release latch, however, does not pop the battery out onto the floor. Instead the battery jumps out about an inch but requires one more press before it can be removed. It&#x27;s an absolutely brilliant mechanism, although it did confuse me at first.</p>
<p>With the battery and screen protector installed, I first made sure to get the latest firmware update. It was a smooth process initiated from the Leica FOTOS app. I was glad I didn&#x27;t have to install some clunky software on my computer to update the firmware.</p>
<img src="" alt="Leica M EV1 powering on for the first time" width="720" height="720" /><br /><small>Leica M EV1, first boot.</small><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC08899.jpg" alt="Leica M EV1 showing the Leica FOTOS pairing screen next to an iPhone finding the camera" width="4000" height="3576" /><br /><small>Pairing with the Leica FOTOS app.</small>
<h3>Lenses</h3>
<p>It may not be immediately apparent, but the Leica M mount system is one of the best things about this camera. There are a few reasons for that:</p>
<ul>
<li>The M EV1&#x27;s built-in EVF means you don&#x27;t need to feel limited in your lens selection, be it ultrawide or telephoto lenses.</li>
<li>The M mount has been around since 1954(!), so you have a deep bench of new and old glass to choose from. Then there&#x27;s the Leica Thread Mount (LTM) that has been around since 1930 and you can easily use LTM lenses on an M with a slim adapter.</li>
<li>There&#x27;s also a great selection of third-party lenses for the M mount like Zeiss, Voigtlander, and Minolta as well as some more niche Chinese brands like 7Artisans, TTArtisan, Light Lens Lab, and Thypoch.</li>
<li>And finally, since we&#x27;re talking about manual focus lenses here, it&#x27;s much easier to find an affordable and thin mount adapter so you can use lenses made for other camera mounts too.</li>
</ul>
<img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09154.jpg" alt="Leica M EV1 and Voigtlander primes from above, close up" width="4000" height="2665" />
<p>Lens selection is a task often guided deeply by personal preference and taste. How much do size, weight, cost, and speed matter? What do you shoot most often? Are you chasing pristine edge-to-edge sharpness and frame-wide consistency? Do you prefer modern rendering, or are you more drawn to vintage character that may include some vignetting, spherical-aberration glow, visible focus transitions, and lively "creamy" bokeh?</p>
<p>This notion of character is something you hear a lot about with Leica, in no small part due to there being a rich history of older lenses where many of these rendering characteristics were initially engineering limitations. There were some exceptions, like the Leica Thambar 90mm f/2.2, built with intentional spherical aberration for more flattering (less clinically crisp) portraits with a dreamy glow. Even today, you&#x27;ll see M mount lens manufacturers maintain separate vintage or classic lines of lenses in addition to more modern options. Modern lenses usually reference ASPH or APO optical technologies that correct spherical aberration and chromatic aberration, respectively.</p>
<img src="https://media.paulstamatiou.com/photostream/2026/07/26/2026-07-26-031600/original.jpg" alt="The Golden Gate Bridge silhouetted between houses at sunset" width="3500" height="2325" /><br /><br /><img src="https://media.paulstamatiou.com/photostream/2026/08/09/2026-08-09-205900/original.jpg" alt="Sutro Tower above the fog at the end of a San Francisco street" width="2657" height="4000" /><br /><br /><img src="https://media.paulstamatiou.com/photostream/2026/07/26/2026-07-26-032300/original.jpg" alt="People strolling past a sculpted wooden bench at Presidio Tunnel Tops at dusk, the Palace of Fine Arts dome in the distance" width="4000" height="2657" /><br /><br /><img src="https://media.paulstamatiou.com/photostream/2026/07/26/2026-07-26-025400/original.jpg" alt="A lone figure at the crest of a Pacific Heights street at golden hour" width="3499" height="2325" /><br /><br /><img src="https://media.paulstamatiou.com/photostream/2026/08/09/2026-08-09-201200/original.jpg" alt="Sutro Tower rising out of the fog" width="2657" height="4000" /><br /><br /><img src="https://media.paulstamatiou.com/photostream/2026/08/09/2026-08-09-212500/original.jpg" alt="A busy street corner outside Tartine Bakery" width="4000" height="2657" /><br /><br /><small>Shot on the Leica M EV1.</small>
<p>I typically shoot landscapes, architecture, nature, and city life. Occasionally people and close-up objects too, but generally not portraits. Even with my landscape shots I do often like to have a medium-telephoto option at hand so I can capture more detail and not strictly be shooting something like a 28mm or 35mm scene.</p>
<p>I also wanted to prioritize relatively compact lenses. My whole thing with this Leica setup is changing my shooting habits coming from my large Sony setup, so I don&#x27;t want to be adding huge lenses that will make me less likely to bring the camera out at all. I&#x27;m also not chasing absolutely flawless edge-to-edge image clarity. This is just a hobby for me. I will gladly trade some clarity for a smaller and lighter lens. I also knew off the bat that I was only considering prime lenses, not zoom lenses. Zoom lenses aren&#x27;t really a thing with Leicas anyway.<sup><a rel="footnote" href="#footnote-4" id="r4">4</a></sup></p>
<p>Fortunately, just about every Leica M lens feels <em>dramatically</em> more compact than the equivalent full-frame Sony FE lens I&#x27;ve been used to. There are a few reasons for that:</p>
<ul>
<li><strong>Manual focus only</strong> means no room taken up by autofocus motors, no internal focusing group designed to be moved by them, no optical image stabilization, or any other electronics. Just a simple mechanical aperture ring.</li>
<li><strong>M mount lenses historically traded quality for size.</strong> In the past, Leica M mount lenses were happy to accept a little vignetting, corner softness, and field curvature in favor of fewer optical elements. Of course, today there are slightly larger modern lenses you can opt for if you want to prioritize the best image quality.</li>
</ul>
<img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09123.jpg" alt="Leica M EV1 with the Voigtlander primes" width="4000" height="2665" /><br /><small>M EV1 with Voigtlander prime lenses.</small><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09149.jpg" alt="Leica M EV1 and Voigtlander primes from above" width="4000" height="3143" /><br /><small>M EV1 with Voigtlander prime lenses.</small><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09398v4.jpg" alt="Leica M EV1 surrounded by the four Voigtlander primes" width="4000" height="2533" /><br /><small>M EV1 with Voigtlander prime lenses.</small><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09403v2.jpg" alt="Leica M EV1 and the four Voigtlander primes" width="4000" height="2665" /><br /><small>M EV1 with Voigtlander prime lenses.</small><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC08872.jpg" alt="The four Voigtlander primes lined up in front of their boxes on a wooden table" width="4000" height="2423" /><br /><small>Voigtlander 28mm, 35mm, 50mm, and 75mm lenses.</small>
<h3>The four primes I picked</h3>
<p>I landed on a set of four prime lenses: <strong>28mm</strong>, <strong>35mm</strong>, <strong>50mm</strong>, and <strong>75mm</strong>. The easiest decision was a fast 50mm for strong bokeh and great low-light performance. With every camera I&#x27;ve ever owned, a fast 50 has been my most used lens. It&#x27;s a versatile focal length, and being able to shoot wide open for stronger background separation is always welcome.</p>
<p>I wanted to keep things light, so I paid attention to each lens&#x27;s weight. With some M mount lenses you might see that they&#x27;re offered in both aluminum and brass versions. I went aluminum where I could to save weight. And since I wasn&#x27;t sure whether I&#x27;d prefer modern-style lenses or classic-style ones with more character, I got some of both.<sup><a rel="footnote" href="#footnote-5" id="r5">5</a></sup></p>
<img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09416v2.jpg" alt="Leica M EV1 next to the 28mm, 35mm, and 75mm Voigtlanders" width="4000" height="2221" />
<small>The 28mm, 35mm, and 75mm next to the M EV1. All remarkably compact.</small>
<ul>
<li><strong><a href="https://turbo.paulstamatiou.com/gear/voigtlander-leica-m-lenses">Voigtlander Nokton 50mm f/1.5 II MC</a>:</strong> Fast, compact, and with smooth bokeh. I use this lens most often.</li>
<li><strong><a href="https://turbo.paulstamatiou.com/gear/voigtlander-leica-m-lenses">Voigtlander Nokton 35mm f/1.5</a>:</strong> Another fast Nokton, also in the Vintage Line like the 50mm.</li>
<li><strong><a href="https://turbo.paulstamatiou.com/gear/voigtlander-leica-m-lenses">Voigtlander 28mm f/2.8 Color-Skopar</a>:</strong> Remarkably compact. This thing is tiny. Makes the Leica M just about able to be put in a jacket pocket.</li>
<li><strong><a href="https://turbo.paulstamatiou.com/gear/voigtlander-leica-m-lenses">Voigtlander 75mm f/2.8 APO-Skopar VM</a>:</strong> The smallest and lightest M mount medium-telephoto prime I&#x27;ve seen at just 1.7 inches long and 191 grams. I absolutely love shooting with this.<sup><a rel="footnote" href="#footnote-6" id="r6">6</a></sup></li>
</ul>
<p>None of these are lenses are made by Leica. I didn&#x27;t start out thinking I would go down this path. I considered starting with a lens like the Leica 50mm f/1.4 Summilux-M or 35mm f/2 Summicron-M, each going for $4,000-$5,000. While researching lenses I kept seeing strong recommendations for Voigtlander&#x27;s offerings; some even best the equivalent Leica glass (for example the APO-Lanthar series is highly rated for absurdly sharp, low-aberration, modern lenses).</p>
<p>I decided to go with all Voigtlander<sup><a rel="footnote" href="#footnote-7" id="r7">7</a></sup> lenses to start. I&#x27;d rather have more focal lengths to play with than feel constrained if I had only purchased one or two Leica primes.</p>
<p>In hindsight I was a bit too quick to pull the trigger all at once on these. I were to do it again I probably would have gotten the 50mm and 75mm and taken more time to explore a variety of lenses, particularly some older used lenses.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC08844.jpg" alt="Holding the Voigtlander Nokton 50mm f/1.5" width="4000" height="2869" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09433v2.jpg" alt="Leica M EV1 with the Voigtlander Color-Skopar 28mm f/2.8 attached" width="4000" height="2999" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09426v2.jpg" alt="Rear three-quarter view of the Leica M EV1 showing the screen and top dials" width="3999" height="3000" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09350v2.jpg" alt="Rear of the Leica M EV1, showing the screen, EVF, and buttons" width="4000" height="2999" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09386v2.jpg" alt="Close-up of the Leica M EV1 and lens" width="4000" height="2913" />
<p><strong>The beauty of the M mount is its maturity.</strong> You can find all sorts of inventory available for it from Leica and many other brands. A few lenses I have on my list to checkout later:</p>
<ul>
<li>Older pre-ASPH Summicron-M 35mm lenses, particularly the 4th-generation 7-element versions (1979-1997) that are colloquially referred to as <em>King of Bokeh</em>.</li>
<li>A 90mm like the Leica APO-Summicron-M 90mm f/2 ASPH, Voigtlander APO-Ultron 90mm f/2, and Voigtlander APO-Skopar 90mm f/2.8. Some of the older Leica 90mm lenses are rather affordable but they are pretty heavy at over 600 grams depending on the generation.<sup><a rel="footnote" href="#footnote-8" id="r8">8</a></sup></li>
<li>Various 50mm lenses to get a better sense of the different styles. Mandler has a highly rated and affordable 50mm f/1.4, and on the complete opposite end of the spectrum there&#x27;s the expensive and revered older 50mm Noctilux f/1.0 (there&#x27;s also a $14k f/0.95 modern ASPH version).</li>
</ul>
<p>There are a lot of places to keep an eye on when looking for well-maintained pre-owned lenses: KEH, <a href="https://www.fredmiranda.com/forum/board/10/">FredMiranda forums</a> (trusted hobbyists, I&#x27;ve sold on there before), <a href="https://www.reddit.com/r/photomarket/">r/photomarket</a>, and even Facebook (Marketplace can be risky but I&#x27;ve seen some solid options on there, and there are various Leica groups for buying and selling).</p>
<h3>Lens coding</h3>
<p>There is one minor trade-off you have to make when you use a third-party lens. Since these Leica M lenses are all entirely mechanical, they have no way to electronically tell the camera what lens is attached.</p>
<p>Instead, what they do is employ what is essentially a tiny barcode on the lens. Modern Leica M cameras (starting with the M8 in 2006) have a small optical reader on the bottom right of the lens mount to read those six black or white markings. The camera then uses that to determine what lens is attached so it can save that to EXIF data, and apply any lens-specific image optimizations.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09055.jpg" alt="Close-up of the Leica M mount and 6-bit lens code reader" width="4000" height="2665" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09057.jpg" alt="Leica M EV1 body with a lens resting beside it" width="4000" height="2418" />
<p>Newer Leica M lenses come with these markings built in (this is called a "coded lens" vs an uncoded one), but for third-party lenses you have to code them manually.<sup><a rel="footnote" href="#footnote-9" id="r9">9</a></sup> This means you get a black Sharpie and mark the lens in a specific area with the required pattern to match the Leica-equivalent lens you&#x27;re shooting with.</p>
<p>You need to know the exact position to mark, so you can either <a href="https://akaralabs.com/products/leica-m-mount-lens-6-bit-encoder">purchase a template</a> or <a href="https://www.thingiverse.com/thing:3728955">3D print one</a> yourself. There are <a href="https://akaralabs.com/pages/lens-codes">lens code tables</a> to help you figure out the markings you need to draw. For example, for my Voigtlander 50mm f/1.5 lens, all I needed to draw was a single black line in the first position for my camera to think a Summilux-M 50mm f/1.4 ASPH is attached (the closest equivalent to my Voigtlander 50mm).</p>
<p>Aside from that annoyance, there are some downstream effects of the photo EXIF data showing that a different lens was used. Photo editing software will try to apply a lens correction for the Leica lens it thinks was used, which you wouldn&#x27;t want to apply to when using different third-party lenses. Fortunately it&#x27;s just EXIF data and this isn&#x27;t too hard to automate to fix if you so desire.</p>
<h3>Lens filters and hoods</h3>
<p>With any new lenses I purchase I consider what kind of filters I need and if I need a lens hood. Personally, I have <em>always</em> put on a UV filter the moment I unbox a new lens while it&#x27;s pristine and dust-free. UV filters are a bit controversial among photographers. You don&#x27;t get a UV filter to change your image, you get it to protect the glass on your expensive lens from damage. It&#x27;s much easier to replace a cracked or scratched UV filter than an entire lens.</p>
<p>The controversial part among some purists is that you&#x27;re ever so slightly affecting image quality by putting another piece of glass in front of your lens. I&#x27;m a bit stuck in my ways about this, though at least now I always avoid stacking filters<sup><a rel="footnote" href="#footnote-10" id="r10">10</a></sup>. That&#x27;s why you don&#x27;t want to get a cheap UV filter if you plan to use one.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC08864.jpg" alt="B+W filters, Urth caps, lens caps, and the square Tahusa hood laid out with the four Voigtlander lenses" width="4000" height="2665" /><br /><small>Filters and Voigtlander lenses</small><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09216v3.jpg" alt="Leica M EV1 with the 35mm and square Tahusa hood" width="4000" height="3260" /><br /><small>With the 35mm Voigtlander and Tahusa hood</small>
<p>Many Leica shooters will only use a lens hood for protection and not bother with a UV filter. To that, I say why not both? When possible I like having a hood as well, but it&#x27;s not easy when shooting with a circular polarizing filter (CPL) that you need to constantly rotate to adjust its position, particularly if you&#x27;re alternating shooting between landscape and portrait orientation.</p>
<p>As for CPL filters, I try to use one whenever I&#x27;m outdoors, especially when there&#x27;s sky, water, or glass and other surface reflections involved. A good CPL filter makes a big difference and is a great tool to have on hand.</p>
<p>I ended up getting these filters (in 39mm and 43mm for my lenses):</p>
<ul>
<li><a href="https://www.amazon.com/dp/B09JB1WKP1?&linkCode=ll2&tag=paulstamatiou-20&linkId=0c8003758d2cd9e3c8cb609a917bfc87&language=en_US&gaOptInStatus=true&ref_=as_li_ss_tl">B+W Master UV Haze MRC Nano 010M filter</a></li>
<li><a href="https://www.amazon.com/dp/B09JB788S3?&linkCode=ll2&tag=paulstamatiou-20&linkId=9ea1ccd0acb64d4896da6c29943f1e0b&language=en_US&gaOptInStatus=true&ref_=as_li_ss_tl">B+W Master High Transmission Kaesemann Circular Polarizer MRC Nano Glass Filter</a></li>
<li><a href="https://amzn.to/4iEMMaL">Urth metal lens filter caps</a>: for compact protection storing filters, instead of carrying around a larger plastic case. After living with these for a while I give them a mixed review as it does had quite a bit of time to unscrew and screw which is a bit annoying when you&#x27;re out shooting.</li>
</ul>
<p>My 28mm and 75mm Voigtlander lenses came with lens hoods, so I purchased the Voigtlander hood for my 50mm<sup><a rel="footnote" href="#footnote-11" id="r11">11</a></sup>. For the 35mm I wanted to try a <a href="https://shop.tahusa.co/products/square-lens-hood-for-voigtlander-35mm-f1-5-aspherical-black-aluminum-regular-shipping-only?variant=50814896275730">square lens hood and cap</a> from a brand called Tahusa. I ended up loving it, in particular the metal lens cap, which is the perfect upgrade over those cheap little plastic lens caps that are far too easy to bump off.</p>
<h3>Shooting</h3>
<p>The Leica M EV1 is the most demanding camera I&#x27;ve owned. There&#x27;s no grip to hold onto, no IBIS to lean on, and no autofocus to bail me out, so I&#x27;m constantly thinking about my settings (e.g., aperture, focus, and shutter speed) before every shot. What I get in return is a camera small enough to carry everywhere without much thought.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2026/09/IMG_3832.jpg" alt="Holding the Leica M EV1 on the beach at sunset" width="4284" height="5229" /><br /><br /><img src="" alt="undefined" width="undefined" height="undefined" />
<small>The M out with me in HI, TX, and CA.</small>
<p>The first thing I had to come to grips with (pun intended) was the camera&#x27;s <strong>complete lack of ergonomics</strong>. There&#x27;s a tiny sliver of a thumb rest on the back, and nothing on the front to keep your fingers comfortable while holding on. I got wrist pain after roaming around with it for a while. Even the shutter button, designed for a threaded mechanical cable release, feels too low. As a result shutter presses never felt satisfying.<sup><a rel="footnote" href="#footnote-12" id="r12">12</a></sup></p>
<p>I&#x27;ve had occasional wrist pain<sup><a rel="footnote" href="#footnote-13" id="r13">13</a></sup> for a decade now, so sorting this out was going to be my first challenge. I ended up getting some <a href="https://paulstamatiou.com/gear/peak-design-form-rope-camera-straps">comfortable rope straps from Peak Design</a>, both a longer strap and a shorter wrist strap. There are many other strap options out there and I spent entirely too long looking at fancy leather straps before prioritizing what I actually cared about.<sup><a rel="footnote" href="#footnote-14" id="r14">14</a></sup> I don&#x27;t love how bulky the anchor connectors are, but they do work well.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC08993.jpg" alt="Leica M EV1 with a body cap, wrapped in a black rope strap" width="4000" height="3333" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09001.jpg" alt="Top-down view of the Leica M EV1 on a black rope strap" width="4000" height="2665" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09005.jpg" alt="Leica M EV1 lying on its back with an olive rope wrist strap" width="4000" height="2665" />
<small>Peak Design Form Rope strap and, bottom right, the Form Rope wrist strap.</small>
<p>While first looking for a front grip I quickly discovered a brand called <a href="https://www.owlkrown.com">Owlkrown</a> that makes a variety of well-crafted Leica accessories. I ended up purchasing a few products like their <a href="https://www.owlkrown.com/products/shutter-topper-cupcake-brass-black-chrome">shutter topper</a> to add a better feel to the shutter, a <a href="https://www.owlkrown.com/products/flexgrip-m11-m-ev1">front grip</a>, <a href="https://www.owlkrown.com/products/hotgrip-for-leica-m10-m11-m-ev1-black-chrome">thumb grip</a>, and <a href="https://www.owlkrown.com/products/eyekup-for-leica-m-ev1-m-series-requires-a-hotgrip">EyeKup</a> (reduces glare). There are other options out there but I loved the build quality with these, and the front grip&#x27;s base doubles as both a hidden AirTag holder and an Arca-compatible tripod mount.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09456v2.jpg" alt="Leica M EV1 with the Owlkrown grip and a Voigtlander lens, straight on" width="4000" height="2665" /><br /><small>Increasing ergonomics with third-party grips and shutter button.</small><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09040v2.jpg" alt="Leica M EV1 with the Owlkrown grip and the Nokton 50mm" width="4000" height="2825" /><br /><small>Increasing ergonomics with third-party grips and shutter button.</small><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09176v3.jpg" alt="Leica M EV1 with the Owlkrown grip and a lens hood" width="4000" height="2665" /><br /><small>Increasing ergonomics with third-party grips and shutter button.</small><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09434v2.jpg" alt="Leica M EV1 with the Owlkrown grip, three-quarter view" width="4000" height="2665" /><br /><small>Increasing ergonomics with third-party grips and shutter button.</small><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09440v2.jpg" alt="Rear three-quarter view of the Leica M EV1 with the Owlkrown thumb grip and EyeKup" width="4000" height="2778" /><br /><small>Increasing ergonomics with third-party grips and shutter button.</small><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09469v2.jpg" alt="Leica M EV1 side profile with the Owlkrown grip and EyeKup" width="4000" height="2665" /><br /><small>Increasing ergonomics with third-party grips and shutter button.</small><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09199v3.jpg" alt="Rear of the Leica M EV1 with the Owlkrown thumb grip and EyeKup" width="4000" height="2665" /><br /><small>Increasing ergonomics with third-party grips and shutter button.</small><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09216v3.jpg" alt="Leica M EV1 with the Owlkrown grip, the 35mm and square Tahusa hood" width="4000" height="3260" /><br /><small>Increasing ergonomics with third-party grips and shutter button.</small><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09224v2.jpg" alt="Leica M EV1 with the Owlkrown grip from a high angle" width="4000" height="2991" /><br /><small>Increasing ergonomics with third-party grips and shutter button.</small><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09218v3.jpg" alt="Leica M EV1 with the Owlkrown grip, straight on" width="4000" height="2665" /><br /><small>Increasing ergonomics with third-party grips and shutter button.</small>
<p>I don&#x27;t love how much larger it makes the Leica feel, but it is absolutely worth the boost in ergonomics. It&#x27;s so much easier to hold and shoot for longer periods with these add-ons. If I had to get only one, I&#x27;d start with the thumb grip.</p>
<p>On another one, when I take the M out shooting in a busy area I like to cover up the bright red Leica dot. While Leicas are especially recognizable and make you an obvious target for theft, I&#x27;ve done this for years with even my Sony cameras. A little piece of easily removable black gaffer tape is all it takes. Others permanently swap out the emblem with either a nondescript replacement or a black version of the Leica logo.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2026/09/IMG_4516.jpg" alt="Leica M EV1 with its red dot taped over, resting on a rock above San Francisco" width="4000" height="3000" />
<small>Hiding the Leica dot with gaffer tape, especially in busier parts of the city.</small>
<h3>Focus</h3>
<p>Let&#x27;s start with the electronic viewfinder (EVF) since it&#x27;s what&#x27;s so different and controversial about this camera. As you&#x27;d expect, you look through it and see a live preview—with accurate exposure, ISO, depth of field, focus, et cetera—of what you&#x27;re going to shoot. It&#x27;s a crisp, high-resolution 0.5-inch OLED display, though it only runs at 60fps so panning can feel a little less fluid than if it was refreshing at 120fps like I expected for a high-end camera.<sup><a rel="footnote" href="#footnote-15" id="r15">15</a></sup></p>
<p>Beyond the refresh rate, the EVF display itself is great, though it would be nice if there was a way to see what&#x27;s just outside your frame to help with composition like you get on rangefinders. Fuji, for example, approaches this with a hybrid viewfinder that combines an optical viewfinder with an EVF to create what they call an Electronic Rangefinder (ERF) so you get the best of both worlds: OVF with framelines to compose your shot and an EVF preview of your focus and exact composition.<sup><a rel="footnote" href="#footnote-16" id="r16">16</a></sup></p>
<p>The M EV1 is <em>just</em> a regular EVF. It&#x27;s still a strong addition that unlocks a lot, as I mentioned earlier. A minor issue I&#x27;ve had with the EVF at times was some glare, especially while wearing glasses and when shooting with the sun behind me. I mitigated that with the <a href="https://www.owlkrown.com/products/eyekup-for-leica-m-ev1-m-series-requires-a-hotgrip">Owlkrown EyeKup</a>, which adds some depth to the viewfinder to reduce glare significantly.<sup><a rel="footnote" href="#footnote-17" id="r17">17</a></sup></p>
<img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC08925.jpg" alt="Leica M EV1 with a Voigtlander lens, straight on, on a wooden table" width="4000" height="2665" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09297.jpg" alt="Leica M EV1 on a tripod above the hills and ocean of Mt. Tamalpais, its rear screen showing the live view" width="4000" height="3609" />
<p>The addition of the EVF brings more possibility, making it much, much easier to use longer focal lengths without having to suffer through missed focus or needing to add a viewfinder magnifier.</p>
<p><strong>But who is the EVF good for?</strong> Is it really an improvement if you&#x27;re not shooting with longer lenses? To understand that, I think we have to dive into the subjective nature of focus when it comes to photography.</p>
<p>Leica M cameras historically have been all about street photography where shooting speed is often critical to capturing a fleeting moment. Manual focusing is not generally compatible with that if you want tack-sharp photos. I <em>want</em> to say that the EVF is for people who want sharp photos and demand precision, but it&#x27;s more about being there to assist when you need it. Not that it&#x27;s a required way to shoot properly or anything like that.</p>
<p>This is where it gets subjective: what counts as acceptable focus varies from photographer to photographer. A slightly out-of-focus photo can still be a powerful capture and tell a story about a moment in time without provoking a second thought about the focus itself. Out-of-focus shots can evoke different emotions or convey a certain mood about how the photo was taken.</p>
<p>Some street photographers employ a manual focusing technique called <strong>zone focusing</strong>. It creates a zone of acceptable sharpness where your subject will be in focus. You control how deep this zone is by setting the aperture. Shooting with zone focusing means you don&#x27;t need to raise your camera to your eye each time, so it&#x27;s more discreet and draws less attention to the photographer.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09212v2.jpg" alt="Top-down view of the Leica M EV1 with a hooded lens" width="4000" height="2582" />
<small>Lens showing distance and depth-of-field scales.</small>
<p>It&#x27;s a rather neat technique and once you learn how it works you&#x27;ll understand what all the lines on your lenses mean: the focus distance and depth-of-field markings. This shooting method is not unique to Leicas. However, the key phrase here is that it helps you with <em>acceptable focus</em>. You won&#x27;t easily get tack-sharp photos shooting with zone focusing.</p>
<p>I&#x27;m not saying focus isn&#x27;t important, just explaining how we got here with the Leica M: a manual-focus-only camera in 2026, without IBIS, that only just got an EVF.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2026/09/IMG_4512.jpg" alt="Holding the Leica M EV1 on a hilltop overlooking San Francisco" width="4000" height="3000" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/IMG_4374.jpg" alt="Composing a Golden Gate Bridge sunset on the Leica M EV1&#x27;s rear screen" width="2963" height="3337" />
<p>The EVF is there for when you want to prioritize capturing sharp photos in any condition. I find it remarkably useful with any type of lens. Even if I&#x27;m not trying to spend 10 seconds finding flawless focus for a single shot, it&#x27;s still a great, quick preview. Of course, you can still skip the EVF and zone focus or shoot at the hyperfocal distance.</p>
<p>This is still a manual-focus camera, so if you&#x27;re seeking perfect focus, it&#x27;s slower. It&#x27;s just like driving a manual transmission car. On the right road, it can be a blast. In the wrong conditions, however, it&#x27;s a huge nuisance. You know what I mean if you&#x27;ve ever crept up an extremely steep San Francisco hill in traffic doing repeated hill starts with the help of your parking brake.</p>
<h3>How I shoot</h3>
<p>I find shooting with manual focus to be a welcome ritual. I love the tactile controls and shooting with the M EV1 makes it clear how much I&#x27;ve missed having a lens with a physical aperture ring like my old Sony RX1R had.</p>
<p>When I pick up the camera I usually start by setting the aperture to where I think I might need it in advance, as well as the focus. I don&#x27;t really use zone focusing but as I&#x27;m walking around I like to set the focus to roughly where I expect I&#x27;ll need it. When I&#x27;m shooting landscapes this typically means setting it to the <a href="https://en.wikipedia.org/wiki/Hyperfocal_distance">hyperfocal distance</a> and then fine-tuning from there.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2026/09/DSC09187v2.jpg" alt="Leica M EV1 top plate and lens from above" width="4000" height="2665" />
<p>When I find my subject, shooting usually looks like this:</p>
<ul>
<li>When I move the focus ring, I have the M EV1 set to automatically punch in 3x or 5x (controllable with the thumb wheel).</li>
<li>The focus peaking feature helps as I do this, but using it effectively is a bit of an art and it&#x27;s not bulletproof.<sup><a rel="footnote" href="#footnote-18" id="r18">18</a></sup></li>
<li>When I&#x27;ve achieved focus, I usually half-press the shutter to go back to a 100% preview to ensure I like my composition, then shoot.</li>
</ul>
<p>I&#x27;m very comfortable with this flow, but it&#x27;s not the fastest, so it isn&#x27;t ideal for every situation.</p>
<video controls="true" poster="https://turbo.paulstamatiou.com/uploads/2026/09/m-ev1-manual-focusing-poster.jpg">
      
      <source src="https://turbo.paulstamatiou.com/cdn-cgi/media/mode=video,width=800,fit=scale-down/https://turbo.paulstamatiou.com/uploads/2026/09/m-ev1-manual-focusing.mp4" type="video/mp4">
      Your browser does not support the video tag.
    </video>
<small>Manual focusing with focus peaking on the M EV1.</small>
<p>I&#x27;ve now shot over 1,500 photos with the M EV1 and while I definitely have the hang of it, I have dealt with some annoying bits.</p>
<p>On the M EV1 when you&#x27;re focusing and you need to punch in to make it easier to find focus, it zooms into the magnification point that you manually set by either touching the screen or using the directional pad (which is another bit of feedback: I wish it had a joystick instead).</p>
<p>This is all fine and good if your magnification point is just in the center of the frame and that&#x27;s also where your subjects tend to be. If that&#x27;s not the case you need to manually move the magnification point, or deal with focusing and recomposing. I generally do the latter so I don&#x27;t have to deal with constantly moving the magnification point.</p>
<p>It&#x27;s not a huge issue but it&#x27;s definitely an inconvenience when you realize other cameras like the Nikon Zf can detect subjects (for example for a portrait, it will select eyes) and automatically set that as the magnification point. And then they have a focus indicator to tell you when that point has been correctly focused, or is in front of or behind the subject. Needless to say, the M EV1 lost some points there from me. I&#x27;m holding out hope that a firmware update one day could change this.</p>
<p>Aside from that magnification annoyance, focus peaking could be better. It does not work well in low-light situations, with low-contrast subjects, and accuracy also varies depending on the lens and aperture<sup><a rel="footnote" href="#footnote-19" id="r19">19</a></sup>. I can&#x27;t blame the M EV1 here entirely, though; these are largely limitations of focus peaking itself. What I can blame the M EV1 for is how laggy the EVF&#x27;s live view gets in low-light situations.<sup><a rel="footnote" href="#footnote-20" id="r20">20</a></sup></p>
<h3>Unexpected things</h3>
<p>There are a few unexpected things I&#x27;ve had to get used to with the M EV1 aside from manual focus. First off, there are the things I thought I would miss but ended up being non-issues: having a fixed screen that doesn&#x27;t tilt, and not having a video mode. I just love that Leica has been able to put a stake in the ground and say that this is a tool for photography, that&#x27;s it. Why bother making a mediocre video mode if that&#x27;s not their focus?</p>
<ul>
<li>
<p><strong>Being constantly aware of your shutter speed</strong></p>
<p>There&#x27;s no in-body image stabilization (IBIS) or any form of in-lens optical stabilization, which means that handheld shooting got a bit harder. You need to be extra aware of your shutter speed to ensure your shots stay sharp. This is especially true with the longer focal lengths you can now use with the M EV1 and its EVF as compared to rangefinder M models.</p>
<p>This is, of course, common knowledge but it&#x27;s easy to forget how powerful modern IBIS systems have become. For comparison, the IBIS system in the Sony a7R VI can give up to around 8 stops (realistically 3-5). That&#x27;s a pretty significant improvement, especially if you shoot in low light.</p>
</li>
<li>
<p><strong>Being constantly aware of your ISO</strong></p>
<p>Similarly, it feels like ISO on the M EV1 loves to jump to high ISO very quickly. In what seems like adequate light to me it will often jump to 6400. For now I keep it capped at ISO 4000, but I wish it were easier to change the Max ISO setting for Auto ISO in the menus as I often want to adjust it depending on what I&#x27;m shooting.</p>
<p>The M EV1 lacks a dedicated ISO dial like the M11 had (it was removed to make room for the EVF), so you&#x27;re more reliant on Auto ISO working well so you don&#x27;t need to dig into menus constantly.</p>
<p>That being said, I don&#x27;t actually mind some noise grain in the shots.</p>
</li>
<li>
<p><strong>Finicky metering</strong></p>
<p>I also found that the exposure metering feels a bit more finicky, even with the new Multi-field setting only available on the M11 / M EV1. Slight changes in the composition more dramatically affect the exposure than I&#x27;m used to with my Sony.</p>
<p>I can control it more with the Spot metering setting, but I expected the default Multi-field metering setting to just work.</p>
</li>
</ul>
<h3>Color science</h3>
<h3>Punchy and dimensional, with selectively rich colors</h3>
<p>I&#x27;ve talked about Leica lenses and the character they can bring to photos, but what about the contrast and color produced by the camera itself? Leica color is often referred to with some reverence, but it&#x27;s tricky to describe. Older digital Leicas like the M240 tend to be known for warmer tones, with more recent models like the M10 being slightly more neutral<sup><a rel="footnote" href="#footnote-21" id="r21">21</a></sup>. The M11 and M EV1 share the same sensor and lean more magenta, so much so that Leica even added a White Balance Adjustment setting in a recent firmware update.<sup><a rel="footnote" href="#footnote-22" id="r22">22</a></sup></p>
<p>As for contrast, the M EV1 feels punchier with deeper darks, albeit with photos feeling a tad darker compared to what I&#x27;ve become accustomed to with Sony cameras. Leica seems to bias toward protecting highlights, so to me images look about 0.5 to 1 stop darker. That&#x27;s not a huge deal as I can adjust the exposure compensation accordingly.</p>
<p>One minor note I should add is about micro-contrast, something Leicas are often known for. It&#x27;s the subtle separation of fine detail and texture that adds to a dimensional look or "3D pop." However, that is mostly a property of a lens<sup><a rel="footnote" href="#footnote-23" id="r23">23</a></sup>, not the camera&#x27;s sensor, so I&#x27;m not digging into it much here. Again, this is not a scientific review, just my quick take.</p>
<p><strong>Comparisons</strong><br/>
This is by no means a scientific comparison, but I shot a few different scenes with my Sony a7R IV with a 55mm lens set to f/2.0 and did the same with my M EV1 with a 50mm set to f/2.0. I also kept all settings at default and reset my Leica&#x27;s white balance adjustment. The photos shown below are the JPEG previews embedded in the RAW files directly from the camera. They haven&#x27;t been processed by me in any way. More on what that means in a bit.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2026/09/comparison_01_Sony.jpg" alt="Sunlit citrus leaves shot on the Sony" width="1616" height="1080" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/comparison_01_Leica.jpg" alt="Sunlit citrus leaves shot on the Leica M EV1" width="2500" height="1662" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/comparison_02_Sony.jpg" alt="Lemons on a backlit tree shot on the Sony" width="1616" height="1080" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/comparison_02_Leica.jpg" alt="Lemons on a backlit tree shot on the Leica M EV1" width="2500" height="1662" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/comparison_03_Sony.jpg" alt="Gray tiled wall with a purple light fixture beside a wood deck, shot on the Sony" width="1616" height="1080" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/comparison_03_Leica.jpg" alt="Gray tiled wall with a purple light fixture beside a wood deck, shot on the Leica M EV1" width="2500" height="1662" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/comparison_04_Sony.jpg" alt="Textured plaster wall in low light shot on the Sony" width="1616" height="1080" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/comparison_04_Leica.jpg" alt="Textured plaster wall in low light shot on the Leica M EV1" width="2500" height="1662" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/comparison_05_Sony.jpg" alt="Looking up at windows set in brown wood siding, shot on the Sony" width="1616" height="1080" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/comparison_05_Leica.jpg" alt="Looking up at windows set in brown wood siding, shot on the Leica M EV1" width="2500" height="1662" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/comparison_06_Sony.jpg" alt="Gray and copper panels meeting at a seam, shot on the Sony" width="1616" height="1080" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/comparison_06_Leica.jpg" alt="Gray and copper panels meeting at a seam, shot on the Leica M EV1" width="2500" height="1662" />
<p>For the most part, the Sony shots feel more clinical and neutral, perfect for a workflow relying on post-processing. Leica&#x27;s punch and deeper blacks do mean I often find myself lifting the shadows to bring back detail.</p>
<p>These comparisons were done with in-camera processed JPEG previews, not RAW files processed in a traditional pipeline like you would with Lightroom, Capture One, Aphera, and others. That&#x27;s where things can change much more significantly depending on your profile, for example Adobe Color, Portrait, Landscape, Vivid, et cetera.</p>
<h3>Post-processing</h3>
<h3>Doing more with less</h3>
<p>As I mentioned in the beginning of this article, I had previously optimized my photography hobby to death. I had set such a high bar for myself for what a good shot was that I spent so much time in Lightroom Classic culling and editing. Zooming in all the way to remove imperfections. Using masks to selectively adjust light, shadows, and saturation on parts of an image... post-processing was a burden and it started to feel like it was all about editing, not capturing.</p>
<p>I&#x27;ve vowed to change my relationship with photography as I get back into it with the Leica. As part of that, I began looking for a better way to cull and post-process my photos. I didn&#x27;t want to touch Adobe Lightroom anymore. I looked at Capture One<sup><a rel="footnote" href="#footnote-24" id="r24">24</a></sup>... wrong direction, way too many controls. The opposite of what I was looking for.</p>
<p>Along the way I discovered a new photo editor called <a href="https://aphera.co/">Aphera</a> from a few folks I had seen around online for some years. It was <em>exactly</em> what I&#x27;ve been looking for.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2026/09/aphera-editing-paul-stamatiou-2.jpg" alt="Aphera showing a photo of trees on a golden hillside, with photo groups on the left and keyboard shortcuts for Balance and Looks on the right" width="3830" height="2202" /><br /><small>Aphera&#x27;s default photo view. No sliders in sight.</small><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/aphera-editing-paul-stamatiou-1.jpg" alt="Aphera editing a photo of a winding road through golden hills, with Looks on the left and a waveform, grading controls, and white balance on the right" width="3830" height="2202" /><br /><small>Aphera&#x27;s detailed editing view for when you need more control.</small><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/aphera-editing-paul-stamatiou-3.jpg" alt="Aphera&#x27;s photo grid showing landscape thumbnails with file names, camera settings, and star ratings, alongside photo groups and editing controls" width="4026" height="2488" /><br /><small>Cull and edit with shortcuts while in grid view.</small>
<p>It does less, better. I love that it&#x27;s opinionated. For example, when you click into a photo detail view there&#x27;s no sidebar filled with sliders to endlessly tweak every little thing. While that advanced functionality is available, it&#x27;s tucked away out of sight until you really need it. Instead, you have a few controls and presets<sup><a rel="footnote" href="#footnote-25" id="r25">25</a></sup> you can fiddle with, all via keyboard shortcuts.</p>
<p>After importing my photos<sup><a rel="footnote" href="#footnote-26" id="r26">26</a></sup>, I tend to quickly cull through the shots, zooming in to check focus, then usually assigning a star rating if it&#x27;s decent. Then I&#x27;ll filter the view to only show the decent shots and go through them, adjusting things like exposure, shadows, and contrast, and sometimes tweaking a preset to achieve the look I&#x27;m going for. All done relatively quickly with my keyboard.</p>
<img src="" alt="undefined" width="undefined" height="undefined" /><br /><br /><img src="https://media.paulstamatiou.com/photostream/2026/08/09/2026-08-09-205900/original.jpg" alt="Sutro Tower above the fog at the end of a San Francisco street" width="2657" height="4000" /><br /><br /><img src="https://media.paulstamatiou.com/photostream/2026/07/26/2026-07-26-030100/original.jpg" alt="Sunset over the Bay through the trees along the Baker Street steps" width="3500" height="2742" /><br /><br /><img src="https://media.paulstamatiou.com/photostream/2026/07/26/2026-07-26-031600/original.jpg" alt="The Golden Gate Bridge silhouetted between houses at sunset" width="3500" height="2325" /><br /><br /><img src="https://media.paulstamatiou.com/photostream/2026/06/28/2026-06-28-042800/original.jpg" alt="Palm trees along a rocky shoreline at dusk" width="2844" height="3000" /><br /><br /><img src="" alt="undefined" width="undefined" height="undefined" />
<p>I&#x27;ve been using it for several months now and can&#x27;t see myself ever going back to <a href="https://paulstamatiou.com/building-a-windows-10-lightroom-photo-editing-pc">Lightroom</a>. The team behind Aphera is small and extremely responsive. I&#x27;ve emailed them quite a few times about feature requests and issues, and they&#x27;ve been quick to ship updates.</p>
<p>The only annoying part about this process isn&#x27;t related to Aphera. It&#x27;s importing photos from the Leica. When you connect the M to a Mac, it does not appear as a regular USB storage device. Instead, it only uses PTP mode, requiring you to use the native macOS Image Capture app to fetch the photos. It&#x27;s a minor inconvenience but once your SD card has tons of photos, Image Capture isn&#x27;t the fastest as it tries to load metadata and previews for all the shots before you can interact.<sup><a rel="footnote" href="#footnote-27" id="r27">27</a></sup></p>
<p>I did also want to mention the Leica FOTOS app. It connects to the Leica over Wi-Fi to let you update firmware, manage photos, and also geotag photos. It even has a Darkroom app integration. It&#x27;s quite a nice little app compared to the horrendous Sony mobile apps I&#x27;m familiar with. Geotagging, however, isn&#x27;t exactly automatic. I tend to have to go out of my way to ensure the Leica and my iPhone are connected over Bluetooth. It&#x27;s great when it works though.</p>
<h3>Sharing</h3>
<p>The final piece of this photography reset is arguably the most important: creating a new way for me to share one-off photos that feels effortless. The travel photosets I used to make were lovely artifacts after a trip, but I don&#x27;t plan on creating photosets like that again. They were a ton of work, from custom-designing and building them to continuing to set a high bar for each photoset so that every photo was worthy of sharing.</p>
<p>I decided to build my own <a href="https://paulstamatiou.com/photostream">photostream</a>. It&#x27;s a place for me to share single photos whenever I please.</p>
<video controls="true" poster="https://turbo.paulstamatiou.com/uploads/2026/09/photostream-demo-poster.jpg">
      
      <source src="https://turbo.paulstamatiou.com/uploads/2026/09/photostream-demo.mp4" type="video/mp4">
      Your browser does not support the video tag.
    </video>
<p>Previously, all my photosets were static files. I&#x27;d create a new MDX post file, which would generate the post during the build process on deploy. Not quite an effortless process. My goal with the photostream was to be database-backed instead so I could just log into an admin dashboard and upload new photos without any deploys.</p>
<p>Here&#x27;s the current shape of what I built:</p>
<ul>
<li><strong>Design:</strong> The design is a basic masonry-style photo grid where every photo keeps its original aspect ratio without cropping. I wanted to keep the chrome pretty minimal. I don&#x27;t ever really care to see loads of EXIF data and details for photos, so I treated that info like an optional, expandable header title pill that shows more info when needed.</li>
<li><strong>Smooth motion:</strong> I spent a good bit of time on the animation that occurs when opening a photo from the photostream grid and closing an open photo to go back to the grid view. I needed absolutely no flicker when attempting to swap views. To achieve this, I actually ditched my usual approach of running more intricate animations with the Motion library and opted for a more bare-bones Web Animations API approach to animating transforms. This was done using the FLIP method in a way where the browser never needs to recalculate the layout during the animation, and the grid is memoized. This means that on a modern browser on a modern machine, opening and closing a photo should run at about 120fps.</li>
<li><strong>Liquid Glass-ish:</strong> With the header buttons, I attempted to make a Liquid Glass-like effect. It only works on desktop Chrome for now (with a regular blur fallback), but it uses signed distance fields (SDFs) to create an SVG filter to provide the refracting effect.</li>
<li><strong>Tech stack:</strong> I built this with TanStack Start, which the rest of my site uses. I recently migrated away from Next.js and Vercel and moved to hosting directly on Cloudflare Workers. I wanted to try something new and kept hearing good things about running TanStack Start on Cloudflare. Just recently the team at <a href="https://www.youtube.com/watch?v=CkGY-wtQ0Q0">Lovable also migrated their sites</a> to TanStack Start on Cloudflare from Next.js.</li>
</ul>
<p>I also spent time diving into overall performance:</p>
<ul>
<li>Each photo has a tiny blur preview embedded to reduce the loading feeling upon first open before the larger image loads. Original images are stored on R2 while smaller variants are generated via Cloudflare Image Transformations.</li>
<li>Lots of caching and preloading throughout. I wanted to make sure, for example, that if I&#x27;m on a photo detail view I could hold down the left/right arrow keys and have it rapidly flip through photos, even if the photos themselves weren&#x27;t loaded.</li>
<li>I initially built this with a Neon Postgres database, accessed via Cloudflare Hyperdrive for connection pooling, but I later simplified and rebuilt it to use Cloudflare&#x27;s D1 database, hooked up with a Cloudflare Workers KV cache. The KV cache means most requests never hit the database at all, and photos still load even if the database goes down. Everything (D1, KV, R2, and a container) is bound directly to a Worker, so I don&#x27;t have a separate database host or connection pooling to deal with.</li>
</ul>
<p>Setting up something like this is a lot more than just the frontend. To be able to upload large original-sized processed JPEGs that can exceed 30MB (not that I always do, but I wanted to support it), I had to create a Cloudflare Container running Sharp where images have sensitive EXIF data stripped (like GPS data; I don&#x27;t want to accidentally upload my home address), and tiny blur preview images are generated along with the resized JPEG that&#x27;s used for the image transformations.</p>
<p>I also built an admin dashboard to manage everything, including bulk EXIF editing controls, and automatic database backups, though Cloudflare D1 already has a nice Time Travel feature. I also needed to add some Leica-specific logic to override the lens the EXIF data says was used, which is not accurate when using a third-party lens like my Voigtlanders, even with the 6-bit <a href="#lens-coding">lens coding</a>. I could have also done this directly in the RAW files, but it felt easier to just do it when uploading. Without this fix, my Voigtlander 50mm would show up as a Leica Summilux 50mm.</p>
<p>Overall, I&#x27;m really pleased with this sharing setup; it&#x27;s exactly what I was looking for. Lightweight and elegant. No real burden to generate any other content aside from just uploading the photo with minimal metadata.</p>
<h3>Closing thoughts</h3>
<h3>Hard to justify, easy to love</h3>
<p>This was not meant to be a clinical review of the Leica M EV1, but more of a dive into how I&#x27;m trying to reboot my relationship with photography. The M is astonishingly expensive at well over $10k for a primitive setup with a few lenses. It doesn&#x27;t do nearly as much as cameras at less than half the price.</p>
<p>It does, however, accomplish exactly what I want. It&#x27;s more than capable of handling the type of photography I shoot while being remarkably compact and well-built. Most camera reviews divide functionality by cost. By that math, the M EV1 will consistently lose.<sup><a rel="footnote" href="#footnote-28" id="r28">28</a></sup> That&#x27;s not how I think about it. As a designer, I tend to place a lot more value on the build quality, aesthetic, and heritage of a product.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2026/09/IMG_3819.jpg" alt="Leica M EV1 resting on a table by the beach" width="3024" height="3478" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2026/09/IMG_4516.jpg" alt="Leica M EV1 resting on a rock above San Francisco" width="4000" height="3000" />
<p>I love to have well-designed tools around me. Even just sitting on my desk unused, the Leica brings me the same joy as using my treasured <a href="https://turbo.paulstamatiou.com/gear/heath-mugs">Heath ceramic mugs</a>, sitting in my decade-old <a href="https://turbo.paulstamatiou.com/gear/eames-lounge-chair-ottoman">Eames lounge chair</a>, writing with my favorite <a href="https://turbo.paulstamatiou.com/gear/baronfig-squire-pen">Baronfig pen</a>, or looking at my original <a href="https://turbo.paulstamatiou.com/gear/apple-ipod">iPod</a> and <a href="https://turbo.paulstamatiou.com/gear/apple-imac-g3">iMac G3</a>. I view this camera like those objects, as something I hope to own for a decade or more, not as tech that I&#x27;ll immediately sell and upgrade to the next version.</p>
<p>However, I don&#x27;t think Leica can rest on its laurels much longer. Photographers are beginning to think the company is becoming more of a luxury and lifestyle brand than a camera company. Updates are too incremental, with headlines focused more on special editions and limited colors than on a marked increase in functionality. You&#x27;re definitely paying for the heritage and craftsmanship over bleeding-edge specs with Leica, but the gap is starting to get too wide.</p>
<p>The M EV1 is not perfect, but I&#x27;ve loved using it for the past several months. It&#x27;s so much smaller than my Sony setup that I take it out with me much more often (including with a few lenses). I&#x27;ve landed on a setup I&#x27;m really happy with, especially combined with my new approach to lightweight culling and editing with Aphera, and sharing photos with my <a href="https://paulstamatiou.com/photostream">new photostream</a>.</p>
<p>There is, however, one downside no one mentions. The manual-focus-only Leica is great if you are the photographer. But when you&#x27;re with family and want someone else to use the M to take a photo of you... good luck. I think it took about 20 shots to get one that was passable.</p>
<small>No AI was used to write this post (<!-- --><a href="https://turbo.paulstamatiou.com/uploads/2026/09/pangram-no-ai.jpg">Verified by Pangram</a><!-- -->), only to flag typos and grammatical issues.</small>
<br><br><br><hr><br><h3>Footnotes</h3><p><a href="#r1">1</a><!-- --> <!-- -->I&#x27;ve tried to make Fuji work. Similar formula—compact camera and lenses, albeit not full-frame—but it just feels like all plastic.</p><p><a href="#r2">2</a><!-- --> <!-- -->I only recently started pruning my RAW archives: deleting unneeded files and converting RAWs to smaller JPEGs.</p><p><a href="#r3">3</a><!-- --> <!-- -->One side effect of spherical aberration is something called focus shift. It&#x27;s where the sharpest point of focus moves as you stop down the aperture. This is another benefit of an EVF over a rangefinder. You see a live preview so you can adjust as needed.</p><p><a href="#r4">4</a><!-- --> <!-- -->Leica tries to match the framelines in the optical viewfinder, so the few zoom lenses Leica offers are actually multi-focal, not continuous zoom, switching between three different focal lengths (for example the Tri-Elmar-M 28-35-50mm f/4 ASPH.)</p><p><a href="#r5">5</a><!-- --> <!-- -->Though to be clear, these are new lenses, so not exactly the same output you&#x27;d get from pre-ASPH older lenses.</p><p><a href="#r6">6</a><!-- --> <!-- -->Shooting with a 75mm on a rangefinder Leica M11 would have been more of a hassle but it really pays off with the M EV1.</p><p><a href="#r7">7</a><!-- --> <!-- -->Voigtlander is owned by Japanese optical-glass maker Cosina.</p><p><a href="#r8">8</a><!-- --> <!-- -->The Voigtlander 75mm is 191 grams for comparison.</p><p><a href="#r9">9</a><!-- --> <!-- -->For older Leica lenses you can either manually do the 6-bit coding too, or select the lens manually in the camera&#x27;s Lens Detection menu.</p><p><a href="#r10">10</a><!-- --> <!-- -->For example, removing a UV filter when putting on a polarizer, instead of applying the polarizing filter on top of the UV filter, which also doesn&#x27;t help vignetting.</p><p><a href="#r11">11</a><!-- --> <!-- -->Which I now almost never use because I&#x27;m usually shooting with a polarizer on when I&#x27;m outside.</p><p><a href="#r12">12</a><!-- --> <!-- -->I purchased an Owlkrown shutter topper to get a more satisfying and responsive shutter feel.</p><p><a href="#r13">13</a><!-- --> <!-- -->It&#x27;s why I use a <!-- --><a href="https://turbo.paulstamatiou.com/gear/moergo-glove80-keyboard">Glove80 keyboard</a><!-- -->, wrist brace for long sessions, a <!-- --><a href="https://turbo.paulstamatiou.com/gear/logi-lift">vertical mouse</a><!-- -->, and use voice AI dictation tools often.</p><p><a href="#r14">14</a><!-- --> <!-- -->Something comfortable that doesn&#x27;t need to be worn in first, and rounded so it wouldn&#x27;t matter how I wear it.</p><p><a href="#r15">15</a><!-- --> <!-- -->The cheaper and older Leica Q3 has a 120fps EVF which makes this a particularly annoying situation.</p><p><a href="#r16">16</a><!-- --> <!-- -->You can toggle between only the OVF or EVF, or merge them so you see a small EVF preview window in the corner. And while less interesting, some Fuji cameras that don&#x27;t have this ERF have a Dual Display mode where you can see both a magnified view of your focus point alongside a preview of the entire composition with just an EVF.</p><p><a href="#r17">17</a><!-- --> <!-- -->I also now tend to remove my glasses and look directly through the EVF as I can see up close just fine and this gives an even better preview. It&#x27;s quite annoying to do frequently but worth the hassle at times.</p><p><a href="#r18">18</a><!-- --> <!-- -->Focus peaking is a feature to help visualize the focused parts of an image by adding colored outlines (you can change the color but I like it in red) to the parts of the image that are sharp.</p><p><a href="#r19">19</a><!-- --> <!-- -->The more you stop down, the more of your composition triggers focus peaking, so it&#x27;s hard to tell what&#x27;s <em>truly</em> the sharpest of the bunch.</p><p><a href="#r20">20</a><!-- --> <!-- -->Unfortunately, I think this is due in large part to the M EV1 using the older Leica Maestro III processor instead of the IV found on the M11-P, Q3, and SL3.</p><p><a href="#r21">21</a><!-- --> <!-- -->And the even older CCD-based sensor on the M9 had a large following for it&#x27;s film-like tones.</p><p><a href="#r22">22</a><!-- --> <!-- -->Easy enough to fix. I ended up adjusting mine to be seven clicks toward yellow (left), seven clicks toward green (up).</p><p><a href="#r23">23</a><!-- --> <!-- -->It&#x27;s closely related to a lens&#x27;s Modulation Transfer Function (MTF), which measures how well a lens keeps tiny details looking distinct instead of letting them blur together.</p><p><a href="#r24">24</a><!-- --> <!-- -->Leica also pushes Capture One and provides a free trial.</p><p><a href="#r25">25</a><!-- --> <!-- -->You can also import LUTs to use.</p><p><a href="#r26">26</a><!-- --> <!-- -->I usually store my imported RAW files on my <!-- --><a href="https://paulstamatiou.com/gear/owc-express-4m2-nvme-ssd-enclosure">SSD array</a><!-- --> which is automatically backed up via an open-source tool called restic.</p><p><a href="#r27">27</a><!-- --> <!-- -->Now I usually just take the SD card out and plug it directly into my MacBook Pro or Mac mini via an external reader.</p><p><a href="#r28">28</a><!-- --> <!-- -->It&#x27;s why I stopped caring about mass-market consumer product reviews like Wirecutter. They really don&#x27;t value aesthetics and design the way I do. And that&#x27;s fine, it&#x27;s just not for me. I remember them <!-- --><a href="https://x.com/Stammy/status/1197911590668029955">recommending a hideous collapsible water bottle</a><!-- --> and calling it quits.</p>]]></description>
            <link>https://paulstamatiou.com/the-leica-reset</link>
            <guid isPermaLink="true">https://paulstamatiou.com/the-leica-reset</guid>
            <dc:creator><![CDATA[Paul Stamatiou]]></dc:creator>
            <pubDate>Sun, 08 Nov 2026 16:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[2025]]></title>
            <description><![CDATA[<p>This isn&#x27;t my usual deep-dive article where I unpack a specific subject such as <a href="https://paulstamatiou.com/stocketa">an app I built</a>, my <a href="https://paulstamatiou.com/craft">obsession with craft</a>, or <a href="https://paulstamatiou.com/revisiting-the-apple-ipod">revisiting an old iPod</a>. I set out to share a few reflections and musings on a year marked by personal and professional change. This was a year of stripping back to the essentials: where I live, how I work, and what I build.</p>
<p><strong>I&#x27;ve been running <a href="https://paulstamatiou.com/timeline">this site</a> for just over 20 years now.</strong> I began writing it in my dorm room at Georgia Tech, hosted on a G4 Mac Mini<sup><a rel="footnote" href="#footnote-1" id="r1">1</a></sup>, as a way for me to share technical how-to guides and news. I used WordPress for the first handful of years, then the Ruby static site generator Jekyll for a decade. It wasn&#x27;t until 2024 that I redesigned and rebuilt this site from scratch using Next.js.<sup><a rel="footnote" href="#footnote-2" id="r2">2</a></sup></p>
<p>I&#x27;ll be turning 40 years old in 2026, which is still surreal to me. For my entire career, I was always the younger one on the team, and what feels like a sudden shift means that&#x27;s no longer true. In many ways, that change is actually a clarifying feeling.</p>
<p>I&#x27;m more focused and fired up to do great work than I&#x27;ve ever been. I&#x27;m driven by the desire to craft great products: things I can be proud of working on. My framing shifted from "Can I help this team build this product?" to "Is this the problem I want to spend my best years on?" I&#x27;ve developed a visceral aversion to working in any environment where I don&#x27;t feel like I can do the best work of my career.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2025/12/sesame-office-view.jpg" alt="The view from the Sesame office in San Francisco" />
<small>The <!-- --><a href="https://x.com/Stammy/status/1980688519397077398/">view from the Sesame office</a><!-- --> in San Francisco where I now work</small>
<p>My taste and judgment have compounded over these years. I&#x27;ve been through similar experiences that I can draw from across whatever I&#x27;m working on. Even on minor UI challenges alone, I&#x27;m still surprised at how often I pull inspiration from my time at Twitter where density was king and compact timelines ruled everything. I always try to keep that as just one input though, especially working in AI when so much is continually changing and you can&#x27;t bring assumptions with you.<sup><a rel="footnote" href="#footnote-3" id="r3">3</a></sup></p>

<h3>My 2025 at a glance</h3>
<ul>
<li>Sold my house.</li>
<li>Left my role as Co-Founder and Head of Design at Limitless (née Rewind AI).</li>
<li>Took 4 months off. Traveled, talked to 30+ founders, companies, and investors as I explored new opportunities.</li>
<li>Started a new role as Head of Design at <a href="https://sesame.com">Sesame</a>.</li>
<li>Started working in an office full-time. After years working remotely, I&#x27;m loving it.</li>
<li>Bought a car after 7 years without one, and learned my lesson about buying a new redesign generation car.</li>
<li>Limitless was acquired by Meta.</li>
<li>Personal resets:
<ul>
<li>Stopped consuming caffeine entirely. Decaf coffee only, not even green tea.</li>
<li>Had my second year of no alcohol.</li>
<li>Stopped wearing my Apple Watch (got annoyed with notifications, wanted to simplify.)</li>
<li>Mostly stopped wearing contact lenses in favor of <a href="https://turbo.paulstamatiou.com/gear/edc">my glasses</a><sup><a rel="footnote" href="#footnote-4" id="r4">4</a></sup>.</li>
</ul>
</li>
</ul>
<h3>Selling my house</h3>
<p>The year started with me finally selling the one-bedroom condo I had purchased a decade earlier. <strong>I completely regret purchasing that place.</strong> Not because it had major maintenance issues or anything like that, but because it was a horrible investment. I had it for 10 years and still <em>lost</em> money on it once you factor in the lower sale price, prep work to sell (staging, floor upgrades, painting), and associated fees.</p>
<p>It was a relatively new building in a bustling shopping and restaurant area in Nob Hill near Russian Hill. The entire building was only nine years old when I bought my unit, so I only had minor maintenance tasks over the years. I loved living there. The unit was modern, had a good HOA, no issues with neighbors, and had 500/500 Webpass as the ISP (this was before fiber was commonplace and before Google Fiber purchased Webpass).</p>
<img src="https://turbo.paulstamatiou.com/uploads/2025/12/stammy-condo-1.jpg" alt="San Francisco - Nob/Russian Hill - condo living room and kitchen" width="1500" height="999" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2025/12/stammy-condo-2.jpg" alt="San Francisco - Nob/Russian Hill - condo living room and interior" width="1344" height="999" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2025/12/stammy-condo-3.jpg" alt="San Francisco - Nob/Russian Hill - condo interior" width="1344" height="999" />
<small>The condo staged for sale.</small>
<p>Why did I buy this place to begin with? I got it in 2015 when I was 29. I had been at Twitter for a few years and made some money from the Twitter IPO. I hated having roommates, and the alternative of paying $4,000–$5,000 a month to rent my own apartment didn&#x27;t feel like a good idea. And at the time, it felt like you couldn&#x27;t go wrong buying in San Francisco. More and more companies were becoming SF-based instead of Silicon Valley, and many friends and coworkers around me were buying homes too.</p>
<p>I purchased it with 25% down and a 2.75% 7-year ARM mortgage from First Republic Bank (RIP, they were great). I figured seven years was plenty of time to either sell or refinance before the rates increased. That didn&#x27;t help either.</p>
<p>I <a href="https://paulstamatiou.com/new-york">moved to New York</a> in 2019 and rented out my condo through a property management company that handled everything while I was out of state. I was in NYC for four years and lost money every month renting it out. Not to mention the property management company was horrible and a pain to deal with. My 7-year ARM&#x27;s fixed period ended in mid-2022 while I was in New York while the rate was increasing monthly. By the time I sold the unit, my expired 2.75% ARM mortgage had exceeded 7.5%. It wasn&#x27;t worth refinancing by then, I knew I wanted to sell it soon.</p>
<p>My wife and I came back to San Francisco in 2023. That same horrible property management company forgot to have the tenant sign a lease (you had one job..), and the tenant ended up moving out unexpectedly a few months in. It lined up perfectly with the end of our apartment lease in New York, so we decided to head to San Francisco for a few months to fix up the condo, sell it, then head back to NYC.</p>
<p>When we got back in January 2023, it wasn&#x27;t a great time to sell, so we stayed. We didn&#x27;t mind escaping the New York winter for a while, and the AI boom was starting to make SF feel alive again. We still love New York, but at the moment it really feels like if you work in tech and AI, you <em>need</em> to be here. The energy is palpable.</p>
<p>We eventually got around to selling it at the start of 2025. I always thought selling it would be a hassle and that I would need to do upgrades to make it enticing. Well, it ended up being so much easier to sell than I expected.</p>
<p>A former coworker introduced me to a small real estate agency; they were perfect. I dropped off the keys and they took it from there. They refinished the floors, upgraded some things in the bathroom, updated the heating system, painted, and staged. In less than two months, it sold. I received 11 offers: four competitive and three all cash. Even though I lost money on the sale all things considered, I had expected it to sell for considerably less given it was listed in January instead of the ideal time in spring.</p>
<p>I learned my lesson with this place. I don&#x27;t see myself purchasing a house in San Francisco anytime soon. The opportunity cost of the down payment alone stings. It would have tripled in a basic total U.S. stock market ETF over those 10 years.</p>
<p>We&#x27;ve since been renting in Noe Valley for the last year. I finally have enough space and my own garage, so I moved over all of my stuff that had been stored with family: my <a href="https://turbo.paulstamatiou.com/gear/eames-lounge-chair-ottoman">Eames chair</a>, <a href="https://paulstamatiou.com/gear/apple-pro-display-xdr">Pro Display XDR</a>, and <a href="https://x.com/Stammy/status/1972400342097903642">old gear</a> like this original <a href="https://turbo.paulstamatiou.com/gear/apple-isight">iSight</a>.</p>
<p>Finding this rental was a huge challenge. Every evening for what felt like a year was spent scouring rental sites before we eventually found it off-market through a friend. At one point there was an apartment in Pacific Heights we loved so much we wrote a love letter (more common with purchases, not rentals), offered many months of cash up front, and even extra rent. There was just too much competition.</p>
<p>I frequently hear from people saying they&#x27;re moving to San Francisco in a month or two. My advice is always the same: start looking for your apartment as early as possible!</p>
<h3>Leaving Limitless</h3>
<p>2025 started with an itch. After two and a half years of working on <a href="https://web.archive.org/web/20231221114250/https://www.rewind.ai/">Rewind</a>, then through its evolution to Limitless and the <a href="https://www.wired.com/story/taking-baby-steps-toward-the-ai-meeting-singularity/">Limitless Pendant</a>, I needed a change. I needed a new design and product challenge.</p>
<p>In my time there, we really embodied what a startup is all about. We had a <a href="https://x.com/Stammy/status/1638995043263578112">true customer focus</a>, endless product iteration, countless product strategy refinements, and long hours sweating the details. We were a remote team of ~15-20 people in recent years. I was the only designer for a period and wrote about what this was like in <a href="https://paulstamatiou.com/the-startup-designer">The Startup Designer</a>.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2025/12/rewind-limitless-team-1.jpg" alt="Rewind/Limitless team" width="2500" height="1842" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2025/12/rewind-limitless-team-2.jpg" alt="Rewind/Limitless team" width="2500" height="2499" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2025/12/rewind-limitless-team-3.jpg" alt="Rewind/Limitless team" width="2500" height="1875" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2025/12/rewind-limitless-team-4.jpg" alt="Rewind/Limitless team" width="2500" height="2034" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2025/12/rewind-limitless-team-5.jpg" alt="Rewind/Limitless team" width="2500" height="2431" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2025/12/rewind-limitless-team-6.jpg" alt="Rewind/Limitless team" width="2500" height="1875" />
<small>The Limitless team at various offsites.</small>
<p><strong>We built a lot of stuff as we searched for product-market fit</strong>. Rewind was a native Mac app that captured everything you&#x27;d seen (via screen capture), said and heard (via opt-in meeting and audio recording), compressed it, and made it actionable. You could visually rewind time as well as search or ask AI to find anything you&#x27;ve seen.</p>
<p>I loved that it had a local-first approach, private by design, and was a bit uncanny until you got used to it. An app that records your screen all the time? Crazy. But it worked.</p>
<p>I would tell people that making Rewind was probably a similar user and marketing challenge to what the team at 1Password likely went through when they were starting out in the mid-2000s. "You want me to put all my passwords into this one app I&#x27;m supposed to trust with my digital life?" Crazy. But it worked.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2025/12/rewind-mac-1.jpg" alt="Rewind Mac app - Ask Rewind feature" width="1922" height="1372" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2025/12/rewind-meetings.jpg" alt="Rewind Mac app - Rewind meeting recording and summarization" width="3612" height="2008" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2025/12/rewind-search.jpg" alt="Rewind Mac app - Rewind search results UI" width="2000" height="1252" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2025/12/rewind-site-1.jpg" alt="Rewind website" width="1916" height="3246" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2025/12/rewind-site-2.jpg" alt="Rewind website - Private by design" width="1914" height="3236" />
<small>The Rewind Mac app. <strong>Bottom right</strong>: Rewind website I designed and built.</small>
<p>We also made <a href="https://x.com/Stammy/status/1684279648019189761">Rewind for iOS</a>, then I spent some time diving into Windows development with C# and WinUI as we worked on a <a href="https://www.youtube.com/watch?v=-80W4f103lE">Windows app focused on using a local LLM</a>.</p>
<p>While the product had some challenges with search quality due to limitations from the local approach, I still think the Rewind concept is solid. Microsoft famously thought so too and created the Rewind-inspired <a href="https://arstechnica.com/gadgets/2024/05/microsofts-new-recall-feature-will-record-everything-you-do-on-your-pc/">Recall feature</a>. There are some things I&#x27;d approach differently if Rewind were rebuilt from the ground up today: prioritize task-based workflows over pure recall, and explore using lightweight visual models for data classification.</p>
<video controls="true" poster="">
      
      <source src="https://turbo.paulstamatiou.com/uploads/2025/12/lenny-rewind.mp4" type="video/mp4">
      Your browser does not support the video tag.
    </video>
<small>Rewind described on <!-- --><a href="https://youtu.be/2ezz4KJe7kA?t=3686">Lenny&#x27;s podcast</a></small>
<p>We then pivoted to a cloud-based product called Limitless, largely as a result of feeling limited by what we could achieve with Rewind&#x27;s local-based approach. There was the cross-platform Limitless web and desktop app, and then the React Native mobile app.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2025/12/limitless-site-1.webp" alt="Limitless website" width="2919" height="2894" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2025/12/limitless-site-2.webp" alt="Limitless website" width="2924" height="2768" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2025/12/limitless-site-4.webp" alt="Limitless website" width="2716" height="3025" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2025/12/limitless-site-3.webp" alt="Limitless website" width="2924" height="2899" />
<video controls="true" poster="https://turbo.paulstamatiou.com/uploads/2025/12/limitless-website-poster.jpg">
      <source src="https://turbo.paulstamatiou.com/uploads/2025/12/limitless-website.webm" type="video/webm">
      <source src="https://turbo.paulstamatiou.com/uploads/2025/12/limitless-website.mp4" type="video/mp4">
      Your browser does not support the video tag.
    </video>
<small>The Limitless.ai website I designed and built <!-- --><a href="https://x.com/Stammy/status/1779860940541808935">with lots of design details</a><!-- -->. My favorite detail was custom animating cursors when you selected a new Pendant color.</small>
<p>Limitless started with meeting recording and summary functionality. That was a recurring use case people had with Rewind. While I personally felt that functionality wasn&#x27;t the most exciting thing to work on, nor did it have staying power with countless meetings-focused competitors working on the exact same thing, we had an ambitious roadmap. The goal was to continually add more data sources over time for context.</p>
<p>One of those data sources was to be our own hardware, <a href="https://ammunitiongroup.com/projects_pt/pendant/">the Limitless Pendant</a>, to capture in-person meetings and conversations to help differentiate us from competitors.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2025/12/limitless-iphone-app.webp" alt="Limitless app for Pendant on iPhone" width="3990" height="2266" />
<small>Early versions of Limitless for iPhone I designed.</small>
<p>The Pendant was a bold bet, but after a year of building its companion app and dogfooding it, <strong>I realized it wasn&#x27;t a product for me.</strong> I take privacy extraordinarily seriously and lean introverted, so I wasn&#x27;t exactly comfortable wearing a recording device out of the house and asking for consent every time I encountered someone new. On top of that, my wife wasn&#x27;t comfortable with me wearing it at home either. The product had real use cases, and we heard about that consistently from customers, but it wasn&#x27;t for me.</p>
<p>Meanwhile, the tech industry was exploding as LLM capabilities improved at a rapid clip and I felt like I was watching from the sidelines. Agents, deep research, multimodal models, new interaction paradigms... I wanted to be at the forefront of that. The opportunity cost felt too high. My heart wasn&#x27;t in it, and I decided to leave.</p>
<h3>Acquired by Meta</h3>
<p>The Rewind and Limitless story came to a close some months later at the end of 2025 with <a href="https://www.reuters.com/business/meta-acquires-ai-wearables-startup-limitless-2025-12-05/">a Meta acquisition</a>. It felt like a great time for the team to join a larger company with the means to really compete with AI hardware and services coming out across the industry. It was a well-deserved exit for the team.</p>
<p>Financially, I received a modest sum for shares I had early exercised, and for my vested in-the-money stock options. I had also previously sold some equity<sup><a rel="footnote" href="#footnote-5" id="r5">5</a></sup> right after the company&#x27;s last public round.</p>
<p>I&#x27;ll likely put some of it toward a few angel investments. I&#x27;ve done several angel investments in the past, mostly in crypto companies like <a href="https://rainbow.me/">Rainbow</a> and <a href="https://xmtp.org/">XMTP</a> (the messaging protocol now used by Coinbase Base and World). However, I&#x27;ve declined to do them more regularly because I feel that to do a good job, you need to have the time and bandwidth to stay on top of deal flow—seek it, meet the founders, and maybe you end up investing in 1 out of every 10+ teams you come across.</p>
<h3>Time off</h3>
<p>After leaving Limitless, I gave myself permission to slow down before jumping into something new. I ended up taking four months off, though it didn&#x27;t really feel like time off at all. I was meeting with founders, companies, and VCs for weeks, and also spent time I was working on my design portfolio.In hindsight I went overkill on the portfolio—I had two versions, the most comprehensive of which was 177 slides—but the act of doing it was a great way to reflect on how I worked, what gave me energy, and what drained it.</p>
<p>My wife made the most of me no longer working nights and weekends, and we ended up taking a few trips. First to <a href="https://x.com/Stammy/status/1908877984490205577">Germany</a> and <a href="https://x.com/Stammy/status/1907755587359899709">Austria</a>, then later to Milan and <a href="https://x.com/Stammy/status/1929600296700805413">Lake Como</a> for a friend&#x27;s birthday.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2025/12/austria-1.jpg" alt="Austria" width="3024" height="4032" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2025/12/austria-2.jpg" alt="Austria" width="3024" height="4032" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2025/12/austria-3.jpg" alt="Austria" width="3024" height="4032" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2025/12/austria-4.jpg" alt="Austria" width="3024" height="4032" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2025/12/austria-5.jpg" alt="Austria" width="3024" height="4032" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2025/12/austria-6.jpg" alt="Austria" width="3024" height="4032" />
<small>Altaussee and Hallstatt, Austria. I haven&#x27;t traveled with my <!-- --><a href="https://paulstamatiou.com/photos/">big Sony a7R IV</a><!-- --> in some years. I get by with my iPhone, shooting in RAW and minor edits in Darkroom app.</small>
<p><strong>I stopped consuming caffeine entirely</strong> in 2025. It was during the trip to a medical health resort called MayrLife on Lake Altaussee, Austria that made that happen. This place was strict: a set schedule with strict meal times along with no caffeine or alcohol. The alcohol part was fine, but getting off of caffeine was a challenge.</p>
<p>I had zero alcohol in all of 2024 and maybe just 5 drinks for all of 2025. I just don&#x27;t really care for it anymore, and never loved the feeling of feeling <em>something</em> the next morning even if I only had two cocktails the night before. After the first full year of zero alcohol, it&#x27;s like I was rewired and completely don&#x27;t even care for alcohol anymore. I&#x27;ll have some non-alcoholic beers and mocktails at times, of course.</p>
<p>I had been used to having a 2-3 strong cups of coffee every day. I ended up having about 4 or 5 days of caffeine withdrawal migraines as I went cold turkey. After that, I decided I didn&#x27;t want to go back to my normal coffee routine. I still love coffee and have a cup of decaf every morning though. I&#x27;ve learned all about the different kinds of decaf processes like Swiss Water Process (chemical free; the lowest caffeine but the worst taste) and Ethyl Acetate (best taste). My current decaf favorite is by Perc Coffee, but I&#x27;m still trying out others I&#x27;m discovering on the r/decaf subreddit.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2025/12/lake-como-1.jpg" alt="Lake Como" width="3024" height="4032" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2025/12/lake-como-2.jpg" alt="Lake Como" width="3072" height="4096" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2025/12/lake-como-3.jpg" alt="Lake Como" width="3024" height="4032" />
<small>Lake Como, Italy. Went for my friend <!-- --><a href="https://www.vermilion.fund/about">Ashley</a><!-- -->&#x27;s birthday.</small>
<p>After the initial withdrawal issues, staying off of caffeine wasn&#x27;t that bad. Decaf coffee doesn&#x27;t dehydrate you during the day, which is something I could feel. I used to rely on melatonin and sometimes magnesium to more easily fall asleep at night after a day of coffees, but now I don&#x27;t need that either. The biggest downside is that while I love the flavor of coffee it&#x27;s harder to find good decaf options at coffee shops. If they do have decaf, it&#x27;s likely just one kind and only served as an americano, not pour over or brewed.</p>
<p>I also took the time to hit reset and simplify a few other things in my life. On the nerdy side, I <strong>got rid of the two servers I had been running</strong> for a while. I had one server that managed this website&#x27;s email newsletter, that I publish to very infrequently. I had been using a self-hosted web app called Sendy that uses AWS SES to send emails cheaply. I ditched that in favor of <a href="https://x.com/Stammy/status/1881046251984077177">Kit</a>. But between that and my other server I used to host my personal Mastodon instance, I hated having to login every few weeks to install an update or fix something. It&#x27;s a small thing, but it freed up mental space.<sup><a rel="footnote" href="#footnote-6" id="r6">6</a></sup></p>
<p>I <strong>stopped wearing my Apple Watch too</strong>. I was constantly annoyed by all the useless notifications and buzzing on my wrist. While I appreciated the health tracking functionality, I wanted to simplify. It didn&#x27;t start as an overnight consciousness decision. I got a <a href="https://paulstamatiou.com/gear/casio-f91w-watch">simple Casio F-91W watch</a>, changed the strap and started wearing it some days. Eventually that became everyday. Half of what I appreciate is that it&#x27;s not a smartwatch. The other half I appreciate is that it&#x27;s just so small and lightweight.</p>
<h3>Exploring what&#x27;s next</h3>
<p>I wrote down what was critical to me as I started thinking about what I wanted in a new role. At the end of the day, I wanted to work with an <strong>exceptionally talented team</strong>, at the <strong>forefront of AI</strong>, with leadership and a CEO who <strong>genuinely care about quality</strong>, and <strong>as little organizational friction as possible</strong> between us and an <strong>outstandingly well-crafted product</strong>.</p>
<p>I wasn&#x27;t in a rush to find the next thing. I had time and wanted to optimize for seeing what was out there first. I&#x27;m often reminded of <em><a href="https://blog.samaltman.com/how-to-be-successful">How To Be Successful</a></em> by Sam Altman, where he writes:</p>
<blockquote>
<p>“I am willing to take as much time as needed between projects to find my next thing. But I always want it to be a project that, if successful, will make the rest of my career look like a footnote.”</p>
</blockquote>
<p>Being in San Francisco and being public about the fact that I was looking for my next thing was like a cheat code for that process. My days were filled as I met with several dozen founders, companies, VCs and friends.</p>
<p>Every founder and team I met with had a unique perspective on where the world is heading, and they were fighting through the ambiguity to get there. It&#x27;s still wild to me that this level of energy and ambition is just par for the course in San Francisco.</p>
<p>I&#x27;m grateful to folks who took time to chat with me:</p>
<ul>
<li><strong>Investors:</strong> A16Z, NEA, First Round Capital, Felicis Ventures, Bain Capital Ventures, Sutter Hill Ventures, Lightspeed Venture Partners, <a href="https://x.com/marcbhargava">Marc Bhargava</a> from GC and others.</li>
<li><strong>Companies:</strong> Cursor, Perplexity, Notion, Hooglee, Arcade AI, Microsoft AI, Sesame, LM Studio, OpenAI, Anthropic, Figma, World Labs and more.</li>
<li><strong>Friends:</strong> I reconnected with friends and acquaintances from Physical Intelligence, Vercel, Shortwave, Luma Labs, Streak CRM, Visual Electric, Humane/HP IQ, Variant.ai, Shopify, Macroscope, Agora.xyz, Adam Lisagor, Ulf Schwekendiek, Jake Jolis and others.</li>
</ul>
<h3>What I Learned</h3>
<p>A few things crystallized from all these conversations:</p>
<ul>
<li>Some founders are really, really good at talking about their company. They have a clear view of the future and make the steps to get there feel obvious, almost expected. Almost like Steve Jobs&#x27;s "reality distortion field." Their energy is infectious.<sup><a rel="footnote" href="#footnote-7" id="r7">7</a></sup></li>
<li>Builders are back. Thanks in no small part to AI, teams are doing more with far less. Orgs are extremely flat. ICs are preferred over managers. Designers who code aren&#x27;t a nice-to-have anymore: they&#x27;re the norm. The era of bloated teams shipping slowly feels firmly behind us.<sup><a rel="footnote" href="#footnote-8" id="r8">8</a></sup> The <a href="https://www.implications.com/p/insights-on-collapsing-the-talent">talent stack</a> has collapsed.</li>
<li>The best designers, engineers, and product managers who weren&#x27;t already working closely with AI were thinking about leaving their companies.</li>
</ul>
<h3>What I Wanted</h3>
<p>All of this helped me articulate exactly what I wanted next after talking with small teams and large teams.</p>
<p>I&#x27;m happiest, most productive, and most ambitious working on 0→1 products and bold bets that scratch at something new in AI, where there&#x27;s a shared understanding of quality. I would much rather be the first designer tasked with creating an app or site from scratch than a designer or manager on a team of dozens responsible for just a sliver of an app. Not on a team of dozens optimizing something that already exists. I wanted to stay close to the craft while also growing a team.</p>
<p>When I began this process, I actually thought I wanted to optimize for compensation and go to a late-stage, pre-IPO, or public company. I had always felt like you wanted to alternate between riskier early-stage startups and late-stage companies in your career so you wouldn&#x27;t get "behind" with savings and investments. It became clear to me that was not where my heart was at all. I needed to work on something I was beyond passionate about with a team that shared that desire.</p>
<h3>Joining Sesame</h3>
<p><a href="https://sesame.com">Sesame</a> ended up being everything I was looking for and more. It&#x27;s been phenomenal across the board: the shared appreciation and ambition for excelling at craft, the remarkable team comprised of industry veterans, and the bold bets we&#x27;re making on the product we&#x27;re building. Yes… I know everyone says this about their company when they join, but that&#x27;s really how I feel.</p>
<p>I&#x27;ve never worked somewhere that truly cared about craft and understood it <em>this</em> much. A lot of that is due to the CEO, <a href="https://x.com/brendaniribe">Brendan Iribe</a>, who was one of the founders of <a href="https://en.wikipedia.org/wiki/Reality_Labs">Oculus VR</a>. Brendan reached out after I published <em><a href="https://paulstamatiou.com/browse-no-more">Browse No More</a></em>. He&#x27;s one of those founders I was alluding to in the previous section: someone who&#x27;s really, really good at speaking about the importance of what the team is building, about taste, and about how great products are made.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2025/12/sesame-2.jpeg" alt="Sesame team" width="2884" height="2623" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2025/12/sesame-4.jpeg" alt="Sesame team" width="2451" height="2794" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2025/12/sesame-1.jpeg" alt="Sesame office" width="4096" height="3112" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2025/12/sesame-3.jpg" alt="Sesame team" width="2500" height="1875" />
<small>Sesame team offsite in Skamania, Washington</small>
<p>I&#x27;ve been on enough teams to know that it really doesn&#x27;t matter if various executives on the leadership team say quality matters. In my experience, it <em>has</em> to come directly from the CEO too. Brendan gets it; for software and for hardware. I later met the rest of the team, including the CPO <a href="https://twitter.com/natemitchell">Nate Mitchell</a> (also one of the founders of Oculus VR), and it was clear this was a team I needed to work with.</p>
<h3>What We&#x27;re Building</h3>
<p><strong>We&#x27;re building both software and hardware.</strong> On the software side, we&#x27;re building what we call personal agents. They&#x27;re not productivity assistants, they&#x27;re more like a collaborator and thought partner you just talk with. But even that description doesn&#x27;t do our ambitions here justice. They&#x27;re much more than that.</p>
<p>We&#x27;ve been focusing on making them remarkably lifelike. That comes across in their unique personalities and how they carry the conversation. It&#x27;s the sort of thing you need to experience to see what I mean: you can try our <a href="https://app.sesame.com/">research preview</a> released earlier in 2025 that over a million people have used. We&#x27;re also working on an iOS app—you can <a href="https://www.sesame.com/beta">get on the waitlist here</a>.</p>
<blockquote>
<p>"This is not another productivity assistant. It&#x27;s something different: a lifelike, expressive collaborator—designed to engage and evolve with its user over time."</p>
</blockquote>
<p>The second piece is hardware. We&#x27;re making <strong>the world&#x27;s best intelligent eyewear</strong>. They&#x27;re fashion-forward and made for all-day comfort. Sequoia has more details on both our software and hardware in their article <em><a href="https://sequoiacap.com/article/partnering-with-sesame-a-new-era-for-voice/">A New Era for Voice</a></em>.</p>
<p>The mission we talk about that I really love is that we&#x27;re working towards <strong>bringing the computer to life</strong> with our hardware and focus on voice-first AI. We&#x27;ve been saying "software is eating the world" for 15 years now. Now as AI is eating software, hardware is becoming the new distribution and interaction frontier for AI. I&#x27;m not saying we won&#x27;t have phones in 5 years (I still absolutely love mine), but I&#x27;m eager to spend time collaborating with the team here to see what these new interfaces will enable.</p>
<blockquote>
<p>"Hardware becomes a more popular moat (amid a surge of hardware startups). In a world where everyone can make their own software, unique products will emerge that tightly couple hardware and software."
—<a href="https://x.com/scottbelsky/status/2005639350554407187">Scott Belsky</a></p>
</blockquote>
<img src="https://turbo.paulstamatiou.com/uploads/2025/12/sesame-7.jpg" alt="Sesame team" width="2500" height="1875" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2025/12/sesame-6.jpg" alt="Sesame team" width="2500" height="1831" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2025/12/sesame-9.jpg" alt="Sesame team" width="2500" height="1875" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2025/12/sesame-5.jpg" alt="Sesame office" width="2037" height="2500" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2025/12/sesame-10.jpg" alt="Sesame team" width="2500" height="1562" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2025/12/sesame-11.jpg" alt="Sesame team" width="2500" height="1655" />
<small>Sesame San Francisco one week when the NYC and Bellevue teams were visiting. <strong>Top</strong>: I&#x27;m on the left</small>
<p>And after five years of almost entirely working from home, I&#x27;m thrilled to be back in an office. When covid started, I thought I&#x27;d never go back to the office. I loved having my own desk setup and being able to focus.</p>
<p>Now <strong>I just miss working with people, whiteboarding design ideas, and perfecting prototypes right next to teammates.</strong> Also, teams building hardware kind of need to be in person with the number of physical prototypes we&#x27;re continually crafting and testing out.</p>
<h3>Design @ Sesame</h3>
<p>It&#x27;s been six months since I joined as Sesame&#x27;s Head of Design, based out of our San Francisco office. My current day-to-day is heavy on design and code (Figma & Xcode for our iOS app)<sup><a rel="footnote" href="#footnote-9" id="r9">9</a></sup> and helping out with things across product, hardware, brand, and marketing.</p>
<p>We&#x27;ve got a lot in store for design this year across mobile, web, brand, and hardware. It&#x27;s always a fun design challenge to work beyond just software product design. <a href="https://basheer.co/">Basheer Tome</a> joined my team to focus on hardware design, interaction design, prototyping, and everything in between. He had previously worked on Google Glass, Google Pixel Buds, autonomous driving, and all sorts of projects spanning PM, ID and CMF at Fellow.</p>
<p>I&#x27;m looking forward to growing our design team this year. I&#x27;m the only software product designer at the moment<sup><a rel="footnote" href="#footnote-10" id="r10">10</a></sup>, and am looking to hire a seasoned <a href="https://jobs.ashbyhq.com/sesame/430ccfb7-2358-4ce9-9e00-fd84d4e28332">product designer</a> to work closely with me in our San Francisco office with a focus on visual design with a passion for craft and design engineering.</p>
<p><a href="https://www.sesame.com/team">We&#x27;re hiring</a> for quite a few different roles outside design too.</p>
<h3>How I worked in 2025</h3>
<p>I finally perfected my home office setup. For the two years prior I had a small desk in the bedroom at my previous place. Once we moved, I finally had space to build things out the way I wanted. I had room for my iMac G3 and vintage gadgets, a <a href="https://paulstamatiou.com/gear/uplift-standing-desk">much larger 72x30" standing desk</a>, and a lounge chair behind it. I also finally shipped my Pro Display XDR to San Francisco from where it had been in storage at my in-laws&#x27; house on the East Coast.</p>
<img src="https://turbo.paulstamatiou.com/gear/desk/stammy-desk-setup-DSC07675.jpg" alt="Uplift V2 Standing Desk" width="3000" height="2000" />
<small><a href="https://turbo.paulstamatiou.com/gear/apple-imac-g3">iMac G3</a><!-- -->, <!-- --><a href="https://turbo.paulstamatiou.com/gear/apple-studio-display">Studio Display</a><!-- -->, <!-- --><a href="https://turbo.paulstamatiou.com/gear/apple-pro-display-xdr">Pro Display XDR</a><!-- -->, <!-- --><a href="https://turbo.paulstamatiou.com/gear/moergo-glove80-keyboard">Glove80 keyboard</a><!-- -->, <!-- --><a href="https://turbo.paulstamatiou.com/gear/uplift-standing-desk">Uplift Standing Desk</a><!-- --> with <!-- --><a href="https://turbo.paulstamatiou.com/gear/diy-desk-led-lighting">custom LED lighting</a><!-- -->.</small>
<p>For the last decade, I&#x27;ve had occasional wrist pain during extended computing sessions, but I have it under control these days with a combination of an adjustable desk (kept low enough so my elbows are properly angled), the <a href="https://turbo.paulstamatiou.com/gear/moergo-glove80-keyboard">Glove80 split ergonomic ortholinear keyboard</a>, a Logi Lift vertical mouse, and a wrist brace for long sessions.</p>
<p>Using a keyboard like the Glove80 (or similar models like the Kinesis Advantage2 I used before it) takes some getting used to, but it&#x27;s worth it if you&#x27;re in a similar boat with wrist pain from RSI. Separately, I try to use AI voice dictation apps like <a href="https://aquavoice.com/share?code=PS-AKOL">Aqua</a> to speak instead of type when I can. I haven&#x27;t quite built that habit yet. I&#x27;ve been thinking about getting a gooseneck desk mic for the office, like some other coworkers have, to do this more often.</p>
<p>I&#x27;ve made a few other additions to my gear recently, but the standouts are my <a href="https://turbo.paulstamatiou.com/gear/apple-imac-g3">333MHz Revision D iMac G3 from 1999</a>, my <a href="https://x.com/Stammy/status/1985174125963550959">original iSight camera</a>, and my new <a href="https://turbo.paulstamatiou.com/gear/owc-express-4m2-nvme-ssd-enclosure">OWC 4-bay M.2 SSD RAID enclosure</a>. With the latter I&#x27;ve also started using <a href="https://immich.app/">Immich</a> to manage my photos (hosted on my Mac, behind Tailscale) and will probably migrate my Google Photos to it.</p>
<img src="https://turbo.paulstamatiou.com/gear/apple-imac-g3-copyright-paulstamatiou-3.jpg" alt="Apple iMac G3" width="2500" height="1780" /><br /><br /><img src="https://turbo.paulstamatiou.com/gear/apple-imac-g3-copyright-paulstamatiou-2.jpg" alt="Apple iMac G3" width="2500" height="2500" /><br /><br /><img src="https://turbo.paulstamatiou.com/gear/apple-imac-g3-copyright-paulstamatiou.jpg" alt="Apple iMac G3" width="2500" height="2038" />
<small>I&#x27;ve been meaning to post a much more in-depth article about the iMac. I updated the RAM, converted the HD to an SLC NAND flash CompactFlash card, and applied new thermal paste to the CPU heatsink. So much nostalgia.</small>
<p>Ironically, I now work in the office on weekdays, so the setup doesn&#x27;t get as much use anymore. I purchased a car for my commute, the newly redesigned 2025.5 Audi SQ5 SUV. I haven&#x27;t had a car since I sold my E92 M3 about 7 years ago. Mechanically, it&#x27;s great: quick, makes a nice sound, and overall fun to drive. The rest is just okay. The interior design leaves a lot to be desired. There&#x27;s ugly piano black plastic everywhere and too many controls are touch-based.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2025/12/audi-sq5-cel-commute.jpg" alt="Audi SQ5 Check Engine Light" width="2500" height="1875" />
<small>Driving to work… notice the check engine light that comes on and off randomly. Take it from me: don&#x27;t buy the first year of a new car generation.</small>
<p>But the icing on the cake is the garbage computer system. Not the infotainment system (though I really dislike that it lacks a traditional tachometer gauge cluster setting), but the whole car&#x27;s computer system has been remarkably buggy. Various warnings and check engine lights constantly come on and then vanish on their own. I took it in for service just a month after I purchased it. They kept it for more than a week and the issues persisted. Others on Reddit are having similar problems and hope an upcoming software update will fix everything. I&#x27;ve definitely learned my lesson about buying a new generation car.</p>
<h3>Apps I love</h3>
<img src="https://turbo.paulstamatiou.com/gear/mnemosyne-kleid-notebook.jpg" alt="Maruman Mnemosyne x Kleid A5 Notebook" />
<small>Okay it&#x27;s not an app, but I love taking notes, sketching UI designs and scratching off to-do list items in <!-- --><a href="https://turbo.paulstamatiou.com/gear/maruman-mnemosyne-kleid-notebook">Mnemosyne x Kleid notebooks</a><!-- --> with my <!-- --><a href="https://turbo.paulstamatiou.com/gear/baronfig-squire-pen">Baronfig Squire</a><!-- -->. I also love <!-- --><a href="https://amzn.to/4joRdoF">Uchida Le Pens</a><!-- --> for sketching too. I&#x27;ve gone through a few in 2025.</small>
<ul>
<li>
<p><strong><a href="https://www.diabrowser.com/">Dia</a></strong> has been my primary browser for the majority of 2025. After living with Arc for the few years prior, I&#x27;m really accustomed to a browser with side tabs. I&#x27;ve tried to get into the ChatGPT Atlas browser and Perplexity&#x27;s Comet browser but they never stuck for me, even with the promise of all their agentic functionality.
I just don&#x27;t really have a huge need to automate things just yet.</p>
<p>Actually, I take that back, I would but the few times I&#x27;ve tried current solutions they were too slow and inaccurate. Maybe later in 2026. About 99% of what I have AI do in a browser for me is summarize long articles, and I use both Dia&#x27;s integrated chat for that, and recently, Anthropic&#x27;s <a href="http://claude.ai/chrome/">Claude browser extension</a> for that.</p>
<p>I just hope that Dia keeps its craft and charm even after its parent company&#x27;s acquisition by Atlassian.</p>
</li>
<li>
<p><strong><a href="https://flighty.com/">Flighty</a></strong> for insanely good flight tracking. I don&#x27;t fly <em>that</em> much and this app is still worth every penny. I get notified of flight delays before the airlines send notifications. I can more easily look up alternate routes, see where the inbound plane is, and more. It&#x27;s just a delightfully well-crafted app.</p>
</li>
<li>
<p><strong><a href="https://apps.apple.com/us/app/yuka-food-cosmetic-scanner/id1092799236">Yuka</a></strong> lets you look up the health impact of various food and cosmetic items. My wife and I use it often to make better choices when shopping, such as avoiding harmful chemicals.</p>
<p>There are a few apps like it but it&#x27;s simple and works well. It does not have data about microplastics (you should definitely take a look at Nat Friedman&#x27;s <a href="https://www.plasticlist.org/">PlasticList</a>) yet unfortunately, but other apps like Olive and Oasis Health do.</p>
<p>These days we&#x27;re much more mindful about what we bring into the house and have replaced pans with non-toxic ceramic ones, plastic cutting boards with oiled wood ones, avoiding certain dish detergents, et cetera.</p>
</li>
<li>
<p><strong><a href="https://mercury.com/share/stammy">Mercury</a></strong> is hands down the best personal banking app and bank out there. There&#x27;s an annual fee but you get a lovely, well-designed modern app with things like automatic transfer rules to move money around (e.g., don&#x27;t keep cash in checking, always move to HYSA) and support for sending wires really easily.</p>
</li>
<li>
<p><strong><a href="https://netnewswire.com/">NetNewsWire</a></strong> combined with <a href="https://paulstamatiou.com/hello-rss">Feedbin</a> is my RSS reader setup of choice. NNW has been around since I had a G4 Mac Mini in my college dorm in 2004. Great, simple piece of software. Though I do wish it had slightly more robust search functionality.</p>
</li>
<li>
<p><strong><a href="https://culturedcode.com/things/">Things</a></strong> has been my to-do list app for many years. Simple, well-built apps for desktop and phone. I have a few minor design gripes with it (what designer <em>wouldn&#x27;t</em> have strong thoughts about their to-do list app) but it gets the job done. There&#x27;s an <a href="https://github.com/hald/things-mcp">unofficial Things MCP server</a> I&#x27;ve been meaning to integrate into my workflow too.</p>
</li>
<li>
<p><strong><a href="https://raindrop.io/">Raindrop</a></strong> is where I send articles I want to read later, curate design inspiration, save interesting links, and everything in between. It also saves a permanent copy of each link you bookmark so it&#x27;s still accessible even if that page ceases to exist on the web. I try to go through it weekly to organize and review what I&#x27;ve saved.</p>
</li>
<li>
<p><strong><a href="https://obsidian.md/">Obsidian</a></strong> (with the Cupertino theme) is my catch-all for daily notes and more. I pay for Obsidian Sync service too. While I have various folders for different types of documents from outlines and drafts of blog posts to documents for ideas, I primarily use it for work. I create a new file each week where I write notes for the week. At the bottom of each week&#x27;s document I keep a running to-do list. At the end of each day I&#x27;ll reprioritize that list or write down an action plan if I&#x27;m in the middle of a large task so I&#x27;m prepared the next morning.</p>
<p>While I really love Obsidian, it&#x27;s not perfect. Searching for files is really, really rough in my experience. I <em>need</em> to keep things in organized folders as I know I&#x27;ll need to find them later and can&#x27;t rely on search. Also, despite a robust developer community, there&#x27;s not yet an amazing LLM solution. Fortunately everything in Obsidian is flat files, so I often use Claude Code with my Obsidian vault for things like synthesizing summaries and themes across a lot of files.</p>
<p>And finally, the other thing I don&#x27;t love about Obsidian is the mobile app navigation. It&#x27;s likely a downside of it being a highly-extensible and cross-platform app, instead of a more opinionated native iOS app.</p>
</li>
</ul>
<p>Despite using all these apps for notetaking, saving, and curating, I don&#x27;t really like the term second brain for this PKM stack. This quote below from <a href="https://www.joanwestenberg.com/i-deleted-my-second-brain-692aa40d59d5f06dd5131e43/">I Deleted My Second Brain</a> resonates with me to a degree, and I sometimes find myself saving things I never revisit.</p>
<blockquote>
<p>"The “second brain” metaphor misfits how human memory works: associative, embodied, and purposefully forgetful.</p>
<p>When I first started using PKM tools, I believed I was solving a problem of forgetting. Later, I believed I was solving a problem of integration. Eventually, I realized I had created a new problem: deferral. The more my system grew, the more I deferred the work of thought to some future self who would sort, tag, distill, and extract the gold.</p>
<p>That self never arrived.""</p>
</blockquote>
<h3>The Year of Claude Code</h3>
<p>2025 was the year of coding agents for me (and everyone else too). It&#x27;s a remarkable, remarkable tool. At the start of the year I mostly used Cursor for smaller tactical changes, but I quickly became heavily dependent on Claude Code. It just kept getting better throughout the year.</p>
<blockquote>
<p>"Claude Code (CC) emerged as the first convincing demonstration of what an LLM Agent looks like - something that in a loopy way strings together tool use and reasoning for extended problem solving. In addition, CC is notable to me in that it runs on your computer and with your private environment, data and context."<br/>
—<a href="https://karpathy.bearblog.dev/year-in-review-2025/">Karpathy</a></p>
</blockquote>
<p>There&#x27;s many articles online on the proper way to configure and use Claude Code, how to put skills, agents, and <code>CLAUDE.md</code> to work for you, but <a href="https://x.com/bcherny/status/2007179832300581177">this thread from the Claude Code creator</a> in particular is worth a scroll:</p>
<blockquote>A Tweet embed was not displayed. Read this article in a browser to see it as intended.</blockquote>
<p>Tools like Claude Code still need constant babysitting and can sometimes get stuck in a loop, trying the same solutions that didn&#x27;t work. I find it critical to try out other models regularly, even for the same task. For example, I get the feeling that Sonnet/Opus aren&#x27;t <em>amazing</em> at more advanced or recent SwiftUI tasks. In a recent example it gave me the old GeometryReader hack for getting scroll offset from a ScrollView instead of the single <code>.scrollPosition()</code> modifier I wanted.</p>
<p>These days I&#x27;m usually bouncing between Claude Code (usually via their official extension inside Cursor, which has nice expandable inline diffs) and Gemini 3 Pro via Cursor Agents. I don&#x27;t have a set workflow. Sometimes I&#x27;ll have Opus make a plan, then have GPT poke holes through it before Claude Code implements. I&#x27;ve also dabbled with tools like <a href="https://x.com/Stammy/status/1955785843521757695">Conductor</a>.</p>
<p>Aside from the obvious desire for faster and smarter models that just nail each task, there&#x27;s one thing I wish these tools were better at: <strong>undo</strong>.</p>
<p>I know version control is technically my job. Git exists. But when I&#x27;m iterating quickly on a specific piece of functionality, I want to easily roll back to the last known good version without thinking about it. That&#x27;s often from a previous agent response. I can leave a trail of commits behind me, but that doesn&#x27;t look great on a PR. I can spend more time amending commits or dealing with git rebase, but that&#x27;s friction I&#x27;d rather avoid.</p>
<p>This feels like something these tools themselves should help with. Cursor, for example, doesn&#x27;t have diffs for each agent response. If you want to undo the last change, you have to ask the LLM to do it, wait, and hope nothing else unexpected is changed in the process. Compare that to just discarding changes if you&#x27;d made a git commit.</p>
<h3>Design + AI</h3>
<p>Much of what I do is design something from scratch in Figma, get it to around 90% or to a point where I have a few options I can&#x27;t decide between without trying them out, and then begin building it. Figma is very much still a starting point. Lots of iteration—in aesthetics, interactions, and logic—happens while I&#x27;m building and feeling it out with real builds.<sup><a rel="footnote" href="#footnote-11" id="r11">11</a></sup> For me that even meant going deep on working with metal shaders this past year: an area that seemed too complex to approach previously.<sup><a rel="footnote" href="#footnote-12" id="r12">12</a></sup> However, I will sometimes use Figma MCP to help speed up parts of the development workflow.</p>
<p>The act of building and testing out as you build is what design is all about to me. It rapidly surfaces new ideas for iterations and directions. There should have never been a design to engineering "handoff" phase. It&#x27;s the same thing. Every designer should be a design engineer too. Being able to more rapidly build designs and interactions also means you no longer have to scratch your head trying to decide if you should come up with a long dissertation about why a certain piece of feedback from a peer or executive isn&#x27;t worth pursuing. Most of the time, you can just try it out and see how it feels that day. Don&#x27;t close off paths too soon.</p>
<p>The biggest shift in design has not been on the visual design front for me. I don&#x27;t necessarily need production assets with models like Nano Banano Pro, nor are there any UI design tools good enough yet to truly enhance my visual and UI design workflow… yet. I&#x27;ve tried to use them for coming up with design inspiration for things like iconography and brand design tasks at times, but haven&#x27;t found anything that truly enhances my workflow yet.</p>
<p>Designers need to push on what AI isn&#x27;t good at yet. To me, that means constantly seeking inspiration, curating, and communicating well. <strong>Always be curious.</strong></p>
<p>You need to constantly be seeking information and inspiration. It can come from anywhere. Archive what feels good, interesting, or provocative to you. Hone your taste. The best designers I know are always curating. Some on Are.na and X. Some just in their own Figma moodboards. Some with link saving tools like Raindrop. Build that habit.</p>
<h3>Restraint in AI</h3>
<p>With Claude Code, Cursor Agents, and dozens of other AI dev tools anyone can build for themselves now. We&#x27;re entering the era of rapidly created, personalized and bespoke software. It&#x27;s going to seem even more insane this year.</p>
<p><strong>Just because you can, doesn&#x27;t mean you should.</strong></p>
<p>The hard part now isn&#x27;t building. It&#x27;s restraint in this world where we have more capabilities than ever.</p>
<p>I&#x27;ve noticed this industry is a bit too trigger-happy to jump into Claude Code and start generating, then immediately commit what was one-shotted. Maybe we should all be doing our own product plan mode outside of Claude Code&#x27;s plan mode.</p>
<p>Taking a step back to ask what we&#x27;re actually building and why before we start. It&#x27;s too easy to skip the product thinking and strategy. That&#x27;s the necessary but slow and hard work of deciding what should exist, why, and who it&#x27;s for in the first place.</p>
<p>What I&#x27;m referring to is just the normal product development process we&#x27;ve been doing for decades. Nothing new here. Just a reminder to not skip it when AI makes the building process closer and closer to a single button press.</p>
<p>As I design things I&#x27;m continually in a loop asking myself things like:</p>
<ul>
<li>Do I even need that (button/view/interaction)?</li>
<li>Is that implied constraint absolutely required? Is it validated?</li>
<li>And some of the Rick Rubin questions like "What&#x27;s the simplest way to express this idea?" or "What&#x27;s the core feeling or essence we&#x27;re trying to convey?"</li>
<li>I also constantly reference the <a href="https://longform.asmartbear.com/extreme-questions/">brainstorming questions in this article</a>.</li>
</ul>
<p>Similarly, even if AI does make something for you and does it well, quality can drop fast if you&#x27;re not careful to polish and clean up everything afterwards. For code quality and product design quality. Always polish it yourself. That&#x27;s where craft lives.</p>
<h3>Thoughts on personality in AI</h3>
<p>Everyone&#x27;s building some sort of agentic assistant right now. Connect your calendar. Integrate your email. Take actions. It all feels the same. A lot of assembled parts. Too many teams skip the hard parts: personality that builds trust, memory that truly enables continuity, and extensibility that meets you where you are. They also don&#x27;t think enough about the <em>why</em>. Okay, so you can access my calendar… now when and why am I supposed to use this?</p>
<p>That&#x27;s why too many of these tools today feel like packaged slop.</p>
<p>Personality and memory are what make these tools feel familiar and natural, not merely transactional. When GPT-4o was retired after GPT-5 launched, people were genuinely upset. They had gotten attached to how 4o wrote, how it felt. That&#x27;s not nothing. As AI becomes more ubiquitous, more ambient—even worn—this will only matter more. Even in quick interactions, the wrong tone and style is <a href="https://x.com/xlr8harder/status/2005195519732355194">immediately clocked</a>.</p>
<p>Personality, memory, and extensibility form the defining triad of future agentic systems that you&#x27;ll <em>want</em> to use:</p>
<ul>
<li>Personality: Comfortable, safe, and genuinely helpful across long-running exchanges and fleeting moments alike. It builds trust, maintains patience when things break, keeps people engaged over time, and even makes things fun when warranted.</li>
<li>Memory: For intimately understanding your preferences, retrieving past decisions, and helping proactively (or at least trying to) without overstepping or making assumptions. Memory is tricky to get right. When unexpected and done poorly it can fail hard and quickly erode trust. It&#x27;s not just RAG or long context. It&#x27;s selective context, memory, and reasoning working together.</li>
<li>Extensibility: What use would this all be if these systems couldn&#x27;t do things for you and integrate into your workflows and tools?</li>
</ul>
<p>It&#x27;s time to stop thinking about building these systems as a series of LEGO bricks to slap together.</p>
<h3>2026</h3>
<p>2025 was a lot of change compressed into twelve months—new job, new house, new daily habits. Most of it came down to getting rid of stuff, physically and mentally, that were getting in the way. Now I&#x27;m at Sesame working on problems I actually want to solve with people who care about the same things I do. This has been a lengthy article… a lot longer than I had originally planned. If you made it this far, <em>thank you</em> for reading.</p>
<hr/>
<p>While I&#x27;ve been religiously saving interesting links and articles for inspiration in Raindrop, one thing I&#x27;ve started doing in the last year is maintaining a single markdown file where I paste interesting design-related quotes and related things. I wanted to close this article with a few of those.</p>
<p>I always like to refer to old computer and operating system reference material and designs for inspiration. The creators of these systems started from what felt like a blank canvas, drawing on things like the desktop metaphor, to build what we have today. I try to get myself into the mindset they might have been in when thinking about the next generation of computing we&#x27;ll have with AI. Palm webOS is a great one too… I got a <a href="https://paulstamatiou.com/gear/palm-pixi-plus">Palm Pixi Plus</a> recently:</p>
<blockquote>A Tweet embed was not displayed. Read this article in a browser to see it as intended.</blockquote>
<blockquote>
<p>"People aren&#x27;t trying to <em>use computers</em>—they&#x27;re trying to get their jobs done."<br/>
—Apple, <a href="https://andymatuschak.org/files/papers/Apple%20Human%20Interface%20Guidelines%201987.pdf">Human Interface Guidelines: The Apple Desktop Interface (1987)</a></p>
</blockquote>
<p>On seeing things fresh and getting unstuck:</p>
<blockquote>
<p>"[…] looking closely at the micro level can unblock you for understanding the macro level. […] Pirsig&#x27;s Brick is a tool for seeing things freshly “without primary regard for what has been said before” which creates that perfect tension of challenge and ability enabling flow."<br/>
—Jordan Moore, <a href="https://jordanm.co.uk/2023/02/14/how-to-dismantle-a-creative-wall.html">How to Dismantle a Creative Wall</a></p>
</blockquote>
<blockquote>
<p>"But there&#x27;s a paradox at the heart of design that&#x27;s rarely discussed: the discipline that most profoundly determines how lasting and inspiring a work of design can be is a designer&#x27;s ability to look away — not just from their own work, but from other solutions, other possibilities, other designers&#x27; takes on similar problems. […]</p>
<p>The most innovative solutions often come from designers who are aware of conventions but not beholden to them. […]</p>
<p>This discipline of looking away preserves the singularity that makes great design resonant. When we constantly reference existing solutions, our work inevitably gravitates toward the mean. […]</p>
<p>This is perhaps the most difficult discipline in design — harder than mastering software, harder than learning color theory, harder than understanding grids and proportions. It requires confidence to trust your own vision when countless examples of "how it&#x27;s done" are just a search away. It demands the courage to pursue a direction that hasn&#x27;t been validated by others.<br/>
—Christopher Butler, <a href="https://www.chrbutler.com/good-design-comes-from-looking-great-design-comes-from-looking-away">Good Design Comes from Looking, Great Design Comes from Looking Away</a></p>
</blockquote>
<p>On design conviction:</p>
<blockquote>
<p>"There&#x27;s an important rule of prototyping: <strong>find the fun first and build from there</strong>. In all of your brainstorming, you need to determine what is actually fun to play. Sometimes a really complex or interesting system is compelling to plan out, codify, and parse as an algorithm… but then turns out to be lackluster to engage with. Keep moving. Find this fun as fast as possible, and don&#x27;t accept anything less. Your players won&#x27;t either."<br/>
—Andrew Zigler, <a href="https://www.andrewzigler.com/blog/mud-cookbook-design-meets-implementation/">MUD Cookbook: design meets implementation</a></p>
</blockquote>
<blockquote>
<p>"Conviction often stands in opposition to market trends. To have conviction before validation may make you seem weird or delusional, but it defines great artists—the ability to appreciate what others overlook or even fight against."<br/>
—Willem Van Lancker, <a href="https://vanlancker.substack.com/p/design-literacy">Design Literacy</a></p>
</blockquote>
<blockquote>
<p>"Hayden, you can&#x27;t change the world. It&#x27;s not possible. All you can do is try to make your own world and then invite other people to be a part of it."<br/>
—<a href="https://www.starwars.com/news/hayden-christensen-revenge-of-the-sith-20">George Lucas</a> to Hayden Christensen</p>
</blockquote>
<p>On soul:</p>
<blockquote>
<p>In its purest form, design is <em>poiesis</em>. It is drawing ideas from the ether. It&#x27;s a Muse.</p>
</blockquote>
<blockquote>
<p>"Beautifully designed products without soul, are just that: representational garden art. In all of our history, we&#x27;ve never had more money to design beautiful, functional and usable products. The bar is higher than ever, yet, they&#x27;ve never been more boring and devoid of soul."<br/>
—Steyn Viljoen, <a href="https://viljoen.space/writing/beautiful-boring-and-without-soul">Beautiful, boring, and without soul</a></p>
</blockquote>
<p>On software today, especially with this era of personalized software:</p>
<blockquote>
<p>"software isn&#x27;t just functional anymore. it&#x27;s quietly turned into a lifestyle brand, a digital prosthetic we use to signal who we are, or who we wish we were.[…] people don&#x27;t just use these apps. they use them to imagine themselves differently. more organized. more intentional. more in control. apps like superhuman or linear aren&#x27;t just tools, they&#x27;re lifestyle upgrades. software that feels like a reward. a signal that you care about your time, your taste."<br/>
—<a href="https://omeru.bearblog.dev/lifestyle/">you are what you launch: how software became a lifestyle brand</a></p>
</blockquote>
<blockquote>
<p>"We stopped doing the real thing that would be the most empathetic, useful, and that would actually serve business outcomes best: building stuff that worked well and that people would love."<br/>
—Jenny Wen, <a href="https://jennywen.ca/notes/dont-trust-the-design-process">Don&#x27;t trust the (design) process</a></p>
</blockquote>
<p>As for books, I did not read much at all in 2025 and really need to change that in 2026, similar to my <a href="https://paulstamatiou.com/reading-more-kindle-oasis">2017 goal of reading 24 books</a>. I&#x27;m currently reading <a href="https://amzn.to/4ppuSbL">The Soul of A New Machine</a> and <a href="https://amzn.to/3YoSgLF">The History of the Future: Oculus, Facebook, and the Revolution That Swept Virtual Reality</a>. I&#x27;ll probably find more from <a href="https://news.ycombinator.com/item?id=46345897">this list of books mentioned on Hacker News</a>.</p>
<br><br><br><hr><br><h3>Footnotes</h3><p><a href="#r1">1</a><!-- --> After 20 years, I finally got my G4 Mac Mini back. The person I sold it to reached out after noticing my gear pages where I&#x27;ve been collecting vintage gadgets and asked if I wanted my old Mac Mini back. I need to add it to my gear section. I have an old <!-- --><a href="https://paulstamatiou.com/gear/intel-mac-mini">Intel Mac Mini</a><!-- --> too.</p><p><a href="#r2">2</a><!-- --> I&#x27;ve been running this site for half my life. These days I mainly just try to keep my gear pages updated frequently, and then only focus on an article when I have some topic I want to go deep on, a perspective I think is unique and worth unpacking, or generally just something I want to nerd out on. That tends to mean about one longer article per year, which is fine with me. Work consumes a lot of my time and I&#x27;m passionate about designing and building great products.</p><p><a href="#r3">3</a><!-- --> Also, I&#x27;ve worked with too many people who use their past experiences as the primary input for a decision. That&#x27;s not only the wrong approach all too often, but it also makes everyone around them resent their unwillingness to consider new ideas and perspectives (or even just entirely different culture, values, quality, people).</p><p>Not to mention.. do you know how annoying it is to keep hearing, "When I was at [company], we did X."? I always, always try to catch myself when I&#x27;m about to say that about my time at Twitter or another past company.</p><p><a href="#r4">4</a><!-- --> Even with fresh daily contacts, they&#x27;re still nowhere near as comfortable as glasses on my eyes. Glasses are just easier and I&#x27;ve started collecting eyewear I really like, such as <!-- --><a href="https://paulstamatiou.com/gear/mr-leight-marmont-glasses">Mr. Leight</a><!-- --> and <!-- --><a href="https://paulstamatiou.com/gear/lindberg-now-titanium-glasses">Lindberg</a><!-- -->.</p><p><a href="#r5">5</a><!-- --> Not being emotional with investments like that and being quick to diversify is something I learned after being at Twitter for 9 years where the stock was performing pretty poorly most of the time. Whenever I&#x27;d vest new RSUs and have an open trading window I&#x27;d immediately sell them. The logic there was "if you had $X in cash right now, would you go out and buy Twitter stock?" The answer for me was usually no.</p><p><a href="#r6">6</a><!-- --> Mastodon didn&#x27;t quite pan out. I got really excited about the prospect of owning and hosting my own social media back when the Twitter exodus began in 2023… but it was never quite as active over there (same with Threads and Bluesky), and I still prefer Twitter/X.</p><p><a href="#r7">7</a><!-- --> I stopped the process with one company after meeting the CEO I would have worked with who lacked that energy. Instead, it felt like they sucked all the energy from the conversation.</p><p><a href="#r8">8</a><!-- --> 5-10 years ago it felt like there was a wave of designers that figured success was going on the management track early (after sometimes just 2 years as an IC) when on a large team and we had bloated teams with too many managers that slowly lost touch of craft over time. Now they&#x27;re having a hard time getting back into IC.</p><p>Similarly, designers that don&#x27;t do well with 0-1 design from scratch, for example without relying on existing design systems, will have a harder time operating on these smaller, craft-focused teams. AI tools today can&#x27;t help that much on the visual design side, and people lacking those foundational skills will need to find ways to adapt.</p><p><a href="#r9">9</a><!-- --> My 2.5 years endlessly designing, building, then redesigning and rebuilding every part of my app <!-- --><a href="https://paulstamatiou.com/stocketa">Stocketa</a><!-- --> prepared me well for sweating the front-end details. Lately I&#x27;ve also been touching some metal shaders as well.</p><p><a href="#r10">10</a><!-- --> We do, however, have quite a few hardware product designers and industrial designers.</p><p><a href="#r11">11</a><!-- --> The new problem is now when people ask for a specific Figma mock of something in the app; the latest version <em>is</em> in the app and it&#x27;s much more work to go back and update Figma mocks to be production accurate. Probably a product opportunity for Figma there.</p><p><a href="#r12">12</a><!-- --> Dan Hollick&#x27;s <em><a href="https://www.makingsoftware.com/chapters/shaders">Making Software</a></em> chapter about shaders is a great read.</p>]]></description>
            <link>https://paulstamatiou.com/2025-year-in-review</link>
            <guid isPermaLink="true">https://paulstamatiou.com/2025-year-in-review</guid>
            <dc:creator><![CDATA[Paul Stamatiou]]></dc:creator>
            <pubDate>Mon, 12 Jan 2026 16:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Browse No More]]></title>
            <description><![CDATA[<p><strong>I&#x27;m no longer browsing the web</strong>; I&#x27;m consuming AI answers instead.</p>
<p>I love and adore today&#x27;s so-called <em>AI answer engines</em>: tools like ChatGPT, Perplexity, Grok, Copilot, and Gemini. I use them at least a dozen times throughout the day, and I&#x27;m sure you use them frequently as well. Their convenience is undeniable.</p>
<p>I turn to these tools to save me some clicks, but I give up control for that convenience. What I gain in efficiency—no longer needing to browse through slow-loading ad-heavy websites just to find out how to tie a Windsor knot or grab a recipe—I lose in the personality, idiosyncrasy, and creativity that makes the web feel authentic. We&#x27;ve come to expect, seek, and rely on this.</p>
<p>Browsing with traditional search engines wasn&#x27;t exactly seamless but you were in the driver&#x27;s seat. You would occasionally end up on some obscure personal site or forum that was unexpectedly right up your alley.</p>
<p>Those magical detours defined our web experience, enriching us with insight and creativity while establishing human connections. Today&#x27;s instant answers with these AI tools sacrifice this beautiful chaos that once made the internet so captivating. But there&#x27;s hope—a new kind of browsing experience might just be around the corner.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2025/03/stammy-ai-answer-engines-3.webp" alt="AI answer engines - Copilot, Gemini, Perplexity, ChatGPT, Grok, Meta, Phind, You" width="8380" height="4752" />
<small>We&#x27;re increasingly experiencing the web like this.</small>
<p>Before we had AI answer engines, and before we had search engines we just had lists of links with web directories like aliweb, Yahoo! Directory and dmoz. You&#x27;d tediously wade through these directories to find and absorb content you were interested in, or just to explore and tinker. Everything online was created by people and you were getting a glimpse into their world with each site.</p>
<p>The web grew. We gained search engines, blogs, feed readers, social media and more. While there were new ways of creating content and new ways of consuming, when you really needed something you&#x27;d still turn to a search engine and click around until you found what you needed.</p>
<p>This led to inevitable moments of delightful and serendipitous discovery. There was real joy in discovering another unique voice online, someone whose articles and interests were right up your alley. Their style of writing lent itself to being devoured in one sitting, while you scan their site to see how you can bookmark or subscribe to keep tabs on their latest works.</p>
<p>It wasn&#x27;t just about stumbling upon a random personal blog that was a fun occasion. It was finding communities you didn&#x27;t know existed. Even just recently as I&#x27;ve been <a href="https://x.com/Stammy/status/1878265690643407233">upgrading my iMac G3</a> and running into some issues, I came across a forum for Mac OS 9 enthusiasts that was chockfull of the exact type of content I was looking for. It was not easy finding it. It didn&#x27;t happen in one sitting, or with one tool and ended up being something I caught in passing that someone said in a video on a blog. But the payoff was worth it for that moment.</p>
<p>Serendipity while browsing the web wasn&#x27;t just a byproduct of how the web began to form. It stretched our empathy by exposing us to diverse voices, nudged us out of echo chambers, and kept our web from becoming monotonous.</p>
<p><strong>That style of surfing the web is fading away.</strong> What social media hasn&#x27;t already taken over, or search engines haven&#x27;t already diluted by sending us to ad-laden mainstream sites, is now steadily being eroded by AI-powered answer engines.</p>
<p>AI answer engines are phenomenal in what they do. I can fire off a prompt and relatively quickly get a blurb with the exact information I need. It really can&#x27;t be overstated how great they are.</p>
<p>But I&#x27;ve lost something profound in the process—the <strong>joy of the unexpected detour</strong>. <strong>I&#x27;m not really browsing the web anymore</strong>. At best, <strong>I&#x27;m just browsing AI interpretations of a limited slice of the web.</strong> A slice that I didn&#x27;t even pick or have control over. My surface area for discovery is now whatever these tools decide to show me.</p>
<p>It&#x27;s not just me. Traditional search engines are evolving into answer engines. Zero-click searches are rising and will continue to rise. <a href="https://searchenginewatch.com/p/seo-in-a-zero-click-world">Nearly 60% of Google searches</a> now end without the user clicking to any site. And now Google is experimenting with "<a href="https://blog.google/products/search/ai-mode-search/">AI mode</a>"<sup><a rel="footnote" href="#footnote-1" id="r1">1</a></sup> to take this to the next level.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2025/03/stammy-google-ai-sge.webp" alt="Traditional search engines are becoming answer engines. Google&#x27;s prominent Search Generative Experience (SGE) and its focal CTA to show more" width="2438" height="1682" />
<small>Traditional search engines are becoming answer engines. Google&#x27;s prominent Search Generative Experience (SGE) and it&#x27;s focal CTA to show more. I love <!-- --><a href="https://turbo.paulstamatiou.com/gear/oura-ring/">my Oura ring</a><!-- --> for what it&#x27;s worth.</small>
<h3>Core issues</h3>
<h3>Is this really a problem?</h3>
<p>This is just another classic example of technology evolving. Who cares if it&#x27;s a bit harder to find some smaller websites? I see a few issues at play here, and it extends beyond just web browsing. At a high level, these AI answer engines lack transparency in how they work, remove control, and homogenize what&#x27;s left, sucking all vibrancy out of what makes the web special.</p>
<ul>
<li>
<p><strong>1) Deprioritized attribution</strong></p>
<p>These tools largely show sources as a tiny footnote link. As an industry we started using that design pattern to link to receipts to prove the LLM was not hallucinating. We need to highlight great content when it&#x27;s most relevant, not bury it with a link and a little generic hovercard or popover.</p>
</li>
<li>
<p><strong>2) The black box of search</strong></p>
<p>How do these tools index and rank the web? How do they decide what content is most relevant to a given question or user? They largely prioritize mainstream sources. How do they interpret your question and turn it into keywords to search their bespoke web index? How do they know when they&#x27;ve retrieved enough info? We lost the agency over these things we had  with search engines.</p>
</li>
<li>
<p><strong>3) Summary homogenization and mode collapse</strong></p>
<p>Even with access to diverse web sources, responses from these tools can feel a bit... off. Fine for when you&#x27;re only looking to fetch basic facts, but limiting and less vibrant for anything else. <strong>It&#x27;s like having access to every book in the world, but only being able to read them summarized by the same person with the same writing style.</strong></p>
</li>
</ul>
<h3>1) Deprioritized attribution</h3>
<p>The way these AI answer engines approach attribution leaves a lot to be desired. The early days of LLMs were especially riddled with hallucinations. The industry began using tiny numeric footnote citations to show that they had the receipts and there was actual data behind each sentence. I even did the same (albeit showing screenshot thumbnails too) when designing and building <a href="https://x.com/Stammy/status/1643659759122518018">this feature</a>.</p>
<p>In addition, these tools try to impress upon us that they are mighty and have referenced some huge number of webpages while coming up with each response. They display this information as a pile of favicons or list of sources, with no easy way to understand why they were included or how they were used. You&#x27;re not meant to wade through it, nor should you have to.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2025/03/stammy-answer-engine-attribution-4.webp" alt="AI answer engines showing web source attribution with inline citations, hover cards and more" width="3052" height="1844" />
<small>Web source attribution shown on these tools with inline citations, source bars, and hover cards.</small>
<p>Each source receives roughly the same visual representation with these tools. There&#x27;s no transparency if it&#x27;s from a reputable mainstream news site, a single author that&#x27;s a domain expert given their past works, or a site you&#x27;ve frequented before. At most you&#x27;ll get an expanded card or sidebar showing more the favicon, domain name, article title along with truncated content.</p>
<p>Some tools do it better than others, including the domain name as the citation instead of a number, or listing a few sources in the footnotes. But that still doesn&#x27;t tell me much about the site, author, why this particular source was selected, and how its content was used. There&#x27;s lots of signals that can be used to help guide understanding here.</p>
<p>It would also be interesting to also consider LLMs employing a system similar to X&#x27;s Community Notes (née <a href="https://en.wikipedia.org/wiki/Community_Notes">Birdwatch</a> when I worked at Twitter) to clarify the context of and add perspective of web sources. For example, a source might seem upstanding but then you discover a whole Hacker News thread explaining in detail why it&#x27;s not accurate.<sup><a rel="footnote" href="#footnote-2" id="r2">2</a></sup></p>
<p>And finally, if you take a particularly dystopian view it&#x27;s not hard to see potential second order effects of these tools with their deprioritized attribution. Perhaps authors will begin focusing on their own empires, where they have control over how their content is seen and monetized—such as moving it to private newsletters, away from the prying eyes of LLMs. AI companies may license data from bigger sites that do this, but definitely not your personal blog or sites on <a href="https://blog.kagi.com/small-web">the small web</a>.</p>
<p>Better or more prominent attribution isn&#x27;t the solution to everything. It&#x27;s a way of framing content to reflecting a broader range of perspectives, and elevating enough signals to allow the reader to understand what they&#x27;re presented and why. Simply sampling the top X keyword results on a topic isn&#x27;t enough to do this or reduce the echo chamber feeling; you also need greater control, understanding, and transparency in the search process.</p>
<h3>2) The AI search black box</h3>
<p>We also face lack of transparency regarding how these tools search the web to gather and process information needed to answer your questions. There is the potential for search and ranking bias, or lack of clarity at the least. Questions like "How are they creating their search indexes?", "What do they value when ranking sites?", and "How do they select a set of web results for user queries?" get elevated.</p>
<p>AI answer engines make countless hidden decisions about what sources matter and what information is relevant—all without your input or awareness. <strong>You get the illusion of comprehensiveness</strong>, when in reality you&#x27;re getting a narrow slice of available information filtered for you.</p>
<p>These tools each have their own way of searching the web. Some may lean on third-party search indexes like Bing (ChatGPT) or X/Brave Search (Grok) but conduct their own crawling and ranking, while others handle everything independently. You&#x27;ve probably become fairly accustomed to how results feel in Google or DuckDuckGo, and you have a good grasp of how to wrangle them to find what you&#x27;re looking for.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2025/03/stammy-ai-sources-details.webp" alt="" width="2950" height="1670" />
<small>Expanded web sources shown in Grok, Perplexity, and ChatGPT. All lack context about what kinds of sites these are, why they were selected, and how they were used.</small>
<p>Now we&#x27;re dealing with a new system entirely, but this time you&#x27;re disarmed—<strong>you&#x27;ve lost your agency</strong> to fiddle with keywords, endlessly navigate pages, decide when to try a new query because one wasn&#x27;t fruitful, and so on. Of course, you can always ask the AI answer engines a different question or provide a follow-up, but you still lack control over how they&#x27;re translating your prompt into an index search.</p>
<p>Perplexity, for example, tries to provide greater transparency when doing a Pro search by showing the exact keywords they used to search their web index. However, I find this approach gives me even <em>less confidence</em> in what it was doing. Customers approach these tools thinking they are all-knowing AI supercomputers... and then see their thoughtfully-posed question get dumbed down to a 4 word search? I have no control over that process nor when it decides to keep searching.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2025/03/stammy-perplexity-pro-search-expanded.webp" alt="Perplexity Pro search with expanded status showing search details" width="2684" height="2000" />
<small>Perplexity Pro search showing different keywords used for a web search based on the question.<br/><br/>This screenshot also perfectly illustrates the core problem. The entire Internet has been talking about <!-- --><a href="https://daringfireball.net/2025/03/something_is_rotten_in_the_state_of_cupertino">Gruber&#x27;s post about Apple Intelligence</a><!-- -->, that should have been included as a source but I have no clarity into how it ranked, searched, and selected these mostly mainstream sources.</small>
<p>What that type of UI does accomplish well is the job of communicating progress successfully during a long-running task. Even more intricate UIs exist, such as those from ChatGPT, Perplexity, Gemini, and Grok for <em>deep research</em><sup><a rel="footnote" href="#footnote-3" id="r3">3</a></sup> tasks that providing a peek into CoT reasoning.
ChatGPT&#x27;s deep research does do one novel thing when presenting sources though, it shows a tiny snippet of <em>how</em> that result was used.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2025/03/stammy-chatgpt-deep-research-sources-description.webp" alt="ChatGPT&#x27;s deep research starts to add a bit of context about what a source was used for: a welcome step in the right direction." width="2266" height="1768" />
<small>ChatGPT&#x27;s deep research starts to add a bit of context about what a source was used for: a welcome step in the right direction.</small>
<p>There&#x27;s also risk on the other side of it: letting users assume that the response they get is the truth. Maybe the cursory web search the answer engine did behind the scenes wasn&#x27;t thorough enough? This is especially the case when dealing with niche topics. (Grok does the absolute worst here: for niche topics it won&#x27;t reference <em>any</em> websites at all!) You&#x27;ve really got to scour the web to find what you need. If these tools are just a few keyword searches in their search index, that won&#x27;t cut it. They don&#x27;t know when to keep searching or ask for further clarification.</p>
<p>I realize that having to fiddle with search engines, while it can be seen as a control, can also be a nuisance at times. I&#x27;m not trying to be too dismissive here.</p>
<p>The huge benefit I&#x27;m flying past is that LLMs do a pretty solid job of understanding your intent and nuance—a crucial trait, given that most people still struggle to write great questions. Though I also think we should do more to guide people here; Elicit does a <a href="https://x.com/Stammy/status/1892615079302209727">nice job with this UI</a> to suggest different ways to ask precise questions.</p>
<video controls="true" poster="">
      
      <source src="https://turbo.paulstamatiou.com/uploads/2025/03/elicit-ask-question-ui.mp4" type="video/mp4">
      Your browser does not support the video tag.
    </video>
<small>Research tool Elicit helps its users determine if their question is strong enough and suggests ways to improve.</small>
<p>We deserve so much more here. If AI tools understand our intent so well, they should deliver much more natural, interesting, and diverse results that feel indistinguishable from having a panel of experts at your side.</p>
<h3>3) Summary homogenization and mode collapse</h3>
<p>You know the feeling. AI-generated content often doesn&#x27;t <em>feel</em> great. It feels slightly off; vaguely mechanical, even predictable. LLMs are largely consensus machines. In the pursuit of zero bias, you end up systematically smoothing out any novel perspectives or viewpoints introduced through these already not-too-diverse web sources used as context.</p>
<p>This feeling where models lose their creativity after post-training is often called <a href="https://gwern.net/doc/reinforcement-learning/preference-learning/mode-collapse/index">mode collapse</a>. Its makes LLMs particularly unsuitable for tasks like creative writing. Sudowrite, an AI writing tool, specifically addressed this problem of "AI-isms" when <a href="https://x.com/superamit/status/1897757915051966875">announcing their new writing model</a>. And just recently, OpenAI mentioned they&#x27;re working on a <a href="https://x.com/sama/status/1899535387435086115">model made for creative writing</a>.<sup><a rel="footnote" href="#footnote-4" id="r4">4</a></sup></p>
<p><strong>When you try to please everyone, you wow no one.</strong></p>
<p>The <a href="https://x.com/benhylak/status/1891421918479184100?s=46&t=AgMC5vUAQsda9BGeY3pppw">way we build and train LLMs</a> has led us to this. I could keep going down the rabbit hole and discuss the need for LLMs to get better at <em>creativity</em>. This is another thing you feel, even if you can&#x27;t quite put your finger on it.</p>
<p>People could tell <a href="https://x.com/sjwhitmore/status/1894294114511790270">when Sonnet 3.7 felt a bit worse than 3.5</a>. They were impressed when <a href="https://x.com/localghost/status/1895394522726813847">GPT 4.5 could do more</a> despite <a href="https://x.com/sjwhitmore/status/1895546829607203159">not being a benchmark-killing model</a>. I&#x27;ve definitely noticed this with 4.5 and have been <a href="https://x.com/Stammy/status/1887951663098642662">putting my Pro subscription to use</a>.  I just wish we as an industry cared as much about <a href="https://gwern.net/creative-benchmark">this side of LLMs</a> as we did with coding and reasoning capabilities.</p>
<p>Even with the right web sources, there&#x27;s little insight into how AI answer engines use the content of each web source when generating their answers. Similar to the potential for search bias, we lack insight into how each web source is weighed and what other signals are used for determining what to incorporate in responses. <strong>Without intentional guidance, LLMs naturally lean toward averaging rather than amplifying unique, minority, or particularly insightful viewpoints.</strong></p>
<p>Okay, maybe we&#x27;re onto something here. But where does that intentional guidance come from?</p>
<h3>Intentional personalization</h3>
<h3>Tools that grow with you. Tools that understand you.</h3>
<p>Today&#x27;s AI answer engines face fundamental challenges that go beyond the feeling of nostalgia for the old web, surfacing some bespoke notion about serendipitous discovery, or wanting more indie content bubbled up. The real issues—weak attribution, black-box decision-making, and homogenized responses—threaten to flatten rather than enrich how we use the web. Browsing the web isn&#x27;t and shouldn&#x27;t be a one size fits all experience.</p>
<p>The current generation of AI tools faces a prodigious challenge: <strong>how can they surprise and delight you when they know almost nothing about you?</strong></p>
<p>The solution isn&#x27;t overwhelming people with more controls, endless configuration opportunities, or exceedingly prominent website cards and attribution. People are confused enough as is selecting the model to use, or having to choose between needing a web search, a pro search, or a deep search, et cetera.</p>
<h3>What personalization really means</h3>
<p>These tools need to be more personalized to you and tailored to your needs. I know, I know... the term <em>personalization</em> gets tossed around a lot for countless uses—often carrying negative connotations, conjuring images of invasive ad targeting. But there&#x27;s a better way.</p>
<p><strong>AI personalization doesn&#x27;t have to be about consuming every detail of your life or cloning yourself.</strong> We&#x27;ve fended off giving too much personal data to individual companies, why start now? You don&#x27;t need to be digitally cloned to help you throughout your day. Even a little bit of info about your past interactions, goals, and interests can go a long way to delivering experiences that resonate more deeply with you.</p>
<h3>A better way</h3>
<p>This might come as a shock but I don&#x27;t believe we want to embody some magical "it just works" scenario with personalized AI where these tools know <em>everything</em> about you, build some comprehensive understanding or model of you, and act as you. I believe a more intentional, transparent approach would serve us better, for several critical reasons:</p>
<ul>
<li><strong>Behavior ≠ intent:</strong> What I do on my computer, phone, or browser is not always what I want to do or who I want to be. That can be a moving target. Just because one user ends up seeing and reading a lot about pop culture news doesn&#x27;t mean they&#x27;re not more interested in reading about another topic they&#x27;re having trouble discovering. This is why it&#x27;s not as easy as just sucking in as much raw data from the user as possible.</li>
<li><strong>Context matters:</strong> Your needs and motivations can change quickly. They can be based on time, location, task, who you&#x27;re with, and more. You might be focused on a particular project and don&#x27;t want personalization to be influenced by what you do at other times. I like to think about this akin to having different profiles in your browser. When researching a specific industry or topic for work, I don&#x27;t want my personal interests bleeding into my results, and vice versa. This goes much deeper than just a work and home separation.</li>
<li><strong>Transparency is non-negotiable:</strong> Users deserve clarity about how their data shapes their experience. This means showing when personalization is active and providing intuitive controls. Even something as small as highlighting a blurb you enjoyed, requesting more depth on topics of interest, or correcting AI assumptions about your knowledge level.</li>
</ul>
<p>Providing users transparency and control in tweaking how AI interprets them is critical to seeing, reinforcing, and correcting assumptions as they go. We need to invest in exploring some of these things as an industry. These tools are remarkably complex and we can&#x27;t hope to nail it on the first try without some light user guidance along the way.</p>
<p>I&#x27;m okay doing a bit of work as an end user to shape my experience; and this doesn&#x27;t just have to be a text response. As a random example, imagine a simplified interest graph representing how the AI understands you, where you prune irrelevant nodes, amplify important ones, and add entirely new focus areas that the system may have missed.</p>
<p>This isn&#x27;t an entirely new concept, I think we&#x27;re just so focused on increasingly more capable foundational models and discrete skills like reasoning that we&#x27;re not quite at the point of going broad enough for things like this. OpenAI has inched in this direction in the past with its <a href="https://openai.com/index/memory-and-new-controls-for-chatgpt/">Memory</a> and <a href="https://help.openai.com/en/articles/8096356-custom-instructions-for-chatgpt">Custom Instructions & Traits</a> features.<sup><a rel="footnote" href="#footnote-5" id="r5">5</a></sup></p>
<img src="https://turbo.paulstamatiou.com/uploads/2025/03/chatgpt-memories-traits.png" alt="ChatGPT&#x27;s take on personalization with Memory, Custom Instructions, and Traits" width="2500" height="2344" />
<small>ChatGPT&#x27;s first steps towards personalization with Memory and Custom Instructions</small>
<p>These current implementations don&#x27;t yet fulfill the capabilities I&#x27;ve outlined here. For example, it&#x27;s unclear how ChatGPT decides to save memories, as they often seem to sporadic while also too specific. Additionally, custom instructions are great for high-level information about you, but things like traits feel more task and prompt-specific; not necessarily something I&#x27;d always want at the account level.</p>
<h3>Personalizing without overreaching</h3>
<p>Okay so providing users some control to tweak as they go is all fine... but what kind of source data are we talking about here?</p>
<p>Controlling the OS or the browser are the most powerful positions to be in. While it&#x27;s hard for most large companies to even think about competing at the OS level, several have begun to compete with browsers: The Browser Company and Perplexity have already announced working on new AI browsers. Maybe OpenAI will enter the arena too.</p>
<p>Even basic browsing data offers powerful personalization potential. What content did you engage with deeply versus merely glance at? What did you create versus consume? Which topics consistently draw your attention over time? These patterns reveal far more than explicit preferences ever could.</p>
<p>There&#x27;s a lot more to talk about when it comes to data capture here—from OS file access to accessing more detailed info from messaging apps, connecting to various cloud providers (email, docs, bookmarks), or even just knowing what apps someone is using or has installed while accomplishing a task. Some of those can be considerably harder integrations to justify with the additional privacy questions they raise.</p>
<p>I&#x27;m already on a bit of a tangent here, but I think the best route, barring inventing your own OS or browser that magically gets massive market adoption, is diving deeper into task-based routes of asking for, clarifying, and showing how context is used (touched on in <a href="#a-better-way">[object Object]</a>). It won&#x27;t be easy though. You&#x27;ll need to build systems for storing and querying these preferences with each LLM interaction. You won&#x27;t want to just inject a ton of this as context with every call.</p>
<p>The key is balancing intentional personalization with user agency.</p>
<h3>Why does personalization matter again?</h3>
<p>Even with light personalization, AI answer engines could meaningfully tailor their responses to you. They would know you&#x27;re very technical and experienced with the topic at hand to skip the basics and dive deeper into technical concepts. They would know you&#x27;ve been writing about technology for 20 years and really enjoy the underlying ways things work and always want that deeper understanding. And so many other things that might seem like minute details at first, but combined really add up.</p>
<p>They could know enough about you, your past interactions, interests and goals to guide you without overstepping, respecting your time and intelligence. A thoughtfully personalized system would:</p>
<ul>
<li><strong>Connect the dots:</strong> Help connect new concepts and topics to previous ones you&#x27;ve read about as a frame of reference.</li>
<li><strong>Identify and manage echo chambers:</strong> Help you peek outside the echo chamber by surfacing novel perspectives.</li>
<li><strong>Leverage trusted sources:</strong> Help you learn from web sources you&#x27;re already familiar with, while balancing new perspectives you may desire.</li>
<li><strong>Anticipate needs:</strong> Proactively suggest content you may be looking for before you&#x27;ve had to ask, in addition to doing tasks for you (The agentic aspect of this type of personalization could warrant an article of its own.)</li>
</ul>
<p>Technology that knows you, even loosely, and helps you out in these ways isn&#x27;t a particularly novel concept, but we can&#x27;t lose sight of it as we design, iterate, and build these AI tools we all use.</p>
<h3>Preserving the web&#x27;s magic</h3>
<p>Don&#x27;t get me wrong, I love these tools. ChatGPT, Perplexity, Gemini, Grok, and others have earned their place in my daily workflow, largely displacing my use of traditional search engines.Yet without thoughtful evolution, they risk homogenizing and muting the web&#x27;s rich diversity into bland, generic responses—eliminating what made the internet magical to begin with.</p>
<p>The large companies behind these tools have every incentive to develop deeper, more nuanced understandings of their users. In recent months, we&#x27;ve seen firsthand that these companies don&#x27;t have much of a moat. Switching costs for users are as low as can be: just head to the App Store and pick up the next AI tool topping the charts. We saw it with DeepSeek one week and Grok another.</p>
<p>By adding more intentional personalization to their products, these companies will not only grow their moat and deliver more impactful, tailored answers but also embrace and highlight the web&#x27;s unique voices and perspectives.</p>
<p>Will it help them directly achieve AGI? Maybe not. But it might start to <em>feel</em> like AGI sooner when these tools are more personalized.</p>
<p>This requires inching towards intentional personalization with refined AI product functionality, greater transparency about how these systems make decisions or apply personalization, and intuitive controls to let users guide their experience without becoming overwhelmed. We can augment human curiosity and creativity rather than replace it.</p>
<p>The magic of browsing the web isn&#x27;t quite gone, but it&#x27;s waiting to be reinvented.</p>
<br><br><br><hr><br><h3>Footnotes</h3><p><a href="#r1">1</a><!-- --> It&#x27;s always interesting to see how companies market their AI capabilities. Some really try to downplay AI and make it more about the opportunity, not the technology. Perplexity has more humanizing taglines like "Where knowledge begins", Grok has "Understand the universe", and OpenAI is rather utilitarian with ChatGPT just focusing on uses it can do without a specific tagline (of course OpenAI itself is all about safe and beneficial AGI), and then Google does the opposite and just calls it... "AI mode".</p><p><a href="#r2">2</a><!-- --> I know that is a bit crazy to consider; imagine just visiting a site today and your browser tells you this site is not accurate or has some other editorial issue with the content. That&#x27;s not the job of a browser or other foundational technology, right? The difference here is that people did not seek this content out themselves, and they don&#x27;t know what they&#x27;re looking at or have all the tools available to decide on their own at a glance. The AI answer engine dug that all up on its own, so it&#x27;s critical to provide as much info as possible to help people be informed about what they&#x27;re consuming. You can&#x27;t just put a disclaimer at the bottom saying AI can make mistakes and move on.</p><p><a href="#r3">3</a><!-- --> With every AI company coming out with roughly the same features it&#x27;s starting to get a bit noisy with all the different modes, let alone models, to use to accomplish your task. That&#x27;s another problem entirely, but I&#x27;m not here to talk about that. <strong>I just want to say how amazed I was the first time I used ChatGPT Deep Research.</strong> I forked over the $200/mon for the Pro subscription (and I&#x27;m still paying for it the next month) and give it a whirl.</p><p>It&#x27;s remarkable how comprehensive it is with just about any prompt. It asks you for feedback before it dives in so you can steer it a bit more which is nice, though the UI for that could be easier than having to reply in a single textarea to a bunch of bullets/questions. ChatGPT Deep Research is the type of thing that gets me really excited about the evolution of these AI tools. They materially save me time and help me go deeper on things that interest me, like learning about topics thoroughly.</p><p><a href="#r4">4</a><!-- --> There was <!-- --><a href="https://x.com/Srirachachau/status/1899591681802227889">a whole bunch of discourse</a><!-- --> about this on X, particularly around whether people even want to read stories made by AI. I think we&#x27;re jumping too far to one end of the spectrum where AI is writing everything. As a writer, I want an LLM that can act as a thought partner. I will provide the ideas, outlines, drafts and I want something to act as an editor, devil&#x27;s advocate, and mentor all in one. For that role it&#x27;s key that these tools can actually write well too, not just code, execute python scripts for complex math, and help with reasoning. The way they communicate is critical too. I&#x27;m not just thinking about it for writing articles. I want this for helping me frame documents like persuasive product briefs I write, et cetera.</p><p><a href="#r5">5</a><!-- --> Another sign that OpenAI is thinking about personalization was spotted in <!-- --><a href="https://x.com/OpenAIDevs/status/1899531367056064814">their recent announcement</a><!-- --> for the new Responses API. They showed a brief example use case for the <code>file_search</code>  tool to gather user preferences for an agentic task. The exact implementation was left up to the API consumer in that example of course. While this article is generally about AI answer engines and the web, personalization like this will be especially important for agents.</p><br/><p><strong>The title of this article</strong> is a reference to an immersive theater work called <!-- --><a href="https://en.wikipedia.org/wiki/Sleep_No_More_(2011_play)">Sleep No More</a><!-- --> I saw in NYC a few years ago. It tells the story of Macbeth and there&#x27;s some interesting parallels I&#x27;m drawing on from this article. For one, loss of agency. When you visit you&#x27;re immersed in an environment where you feel like you lose control (similar to what AI answer engines feel like they&#x27;re doing today). You&#x27;re a spectator wandering around while confusing things happen around you.</p>]]></description>
            <link>https://paulstamatiou.com/browse-no-more</link>
            <guid isPermaLink="true">https://paulstamatiou.com/browse-no-more</guid>
            <dc:creator><![CDATA[Paul Stamatiou]]></dc:creator>
            <pubDate>Thu, 13 Mar 2025 16:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[The Startup Designer]]></title>
            <description><![CDATA[<p>There&#x27;s nothing glamorous about being a designer at a startup. It&#x27;s a role that frequently values speed and pragmatism over going <a href="https://paulstamatiou.com/craft">deep in the craft</a>. It&#x27;s not all big launches, viral tweets, building for happy paths, and clear-cut product requirements.</p>
<p>However, it can be incredibly rewarding. The fun comes from being able to excel at learning new skills and wearing many different hats while being solely responsible for large efforts.</p>
<img src="https://turbo.paulstamatiou.com/media/2024/starcraft.jpg" alt="Starcraft" />
<small>The "Fog of War" in StarCraft hides areas that have yet to be explored.</small>
<ul>
<li>
<p>The startup designer&#x27;s greatest strength is their speed and versatility. It&#x27;s the light aiding in the search for product-market fit as resourcefully as possible.</p>
</li>
<li>
<p>The startup designer is <a href="https://twitter.com/Stammy/status/1563886808546611202">part artist, part scientist</a>. The scientist views product design as something to be tamed with rules, systems, and principles; a thorough optimizer. The artist is aware of some of those rules but often chooses their own path. The artist runs by feel, and is known to always detach components. One crafts a system that helps with consistency, accessibility and scaling; the other continually challenges it and provides the friction needed to improve it.</p>
</li>
<li>
<p>The startup designer can survive—and thrive—without relying on a design system. They can go from a blank canvas for a new homepage or landing page design and bring it to life in a way that embraces the brand and marketing strategy.</p>
</li>
<li>
<p>The startup designer is <a href="https://paulgraham.com/relres.html">relentlessly resourceful</a>, and embraces any task, even the mundane, unfamiliar, or gargantuan. Helping with company swag, brand design, icon design, packaging print design, use case landing pages, et cetera. There are a few exceptions where outsourcing makes sense, but most of the time there&#x27;s not enough time to find a contractor, onboard them, ramp them up on project context, and guide them through iterations.</p>
</li>
<li>
<p>The startup designer knows where to compromise on quality, when to push for it hard, and how to advocate for it beyond intuition, armed with customer feedback, insights, and company goals.</p>
</li>
<li>
<p>The startup designer perpetually exhibits strong ownership and knows what to work on. Their priorities come up naturally from working closely with the team and seeing what users are running into. They know the right fidelity, speed, and urgency for each task.</p>
</li>
<li>
<p>The startup designer embraces ambiguity and is naturally optimistic. The cards are already stacked against every early stage startup. The team needs to be crazy enough to see through it all and envision the future they&#x27;re building and convincing others of. When there are inevitable moments of uncertainty—with a feature, with the entire product, with a company pivot—the startup designer takes action to find clarity, gather data, and explore alternate solutions. <a href="https://twitter.com/JamesClear/status/1795843808963248316">The pessimist criticizes, the optimist creates.</a></p>
</li>
<li>
<p>The startup designer balances their desire for craft and extremely high-quality shipped products with the pre-PMF startup&#x27;s need to prioritize shots on goal. The faster you&#x27;re able to ship (and nurture what is shipped), the more shots you can take, and the more likely you&#x27;ll reach product-market fit. There are times when spending an extra week or two ironing things out and polishing matters, but most of the time it&#x27;s hard to make that ROI math work. This compromise is one of the harder parts of the job.</p>
</li>
<li>
<p>The startup designer doesn&#x27;t try to predict designs needed for future versions of a feature that hasn&#x27;t been built yet. They do enough design due diligence to make sure it works reasonably well for the near-term, then move on. Chances are that feature won&#x27;t live long or work out anyways. And if it does well, it&#x27;ll probably be redesigned and rebuilt based on new information.</p>
</li>
<li>
<p>The startup designer fully separates themselves from the work. There is no time for ego. There will be hard feedback at every turn: from the team, from the customers. Everything worked on is the result of countless iterations. There&#x27;s no point getting worked over a design that probably won&#x27;t matter in the long run, or even next week when they&#x27;re focused on something else.</p>
</li>
<li>
<p>The startup designer is pragmatic. They know they can&#x27;t refine everything to perfection before it gets shipped, and that not everything will ship. But they know when it&#x27;s worth advocating for a bit more quality and rigor.</p>
</li>
<li>
<p>The startup designer has a natural urge to thoroughly explore designs for any task. Even with a minor visual design task, the startup designer knows the power of continuining to explore iterations and alternate designs. Sometimes the best design is Frame 1, sometimes it&#x27;s Frame 37.</p>
</li>
<li>
<p>The startup designer knows that even unshipped designs provide value. These designs can show the team what&#x27;s possible for the future vision. They can prove a certain direction isn&#x27;t worth investing in. They can show why another design is a better choice. Some of the startup designer&#x27;s best design work will go unshipped and they know that&#x27;s okay.</p>
</li>
<li>
<p>The startup designer is vocal. About product direction and requirements. About technical issues affecting users. About marketing and storytelling. About branding. About prioritizing issues. Not only about their own thoughts, but also about the customers&#x27; thoughts.</p>
</li>
<li>
<p>The startup designer asks a lot of the same questions to drive toward simplicity. Is X even needed? How can we remove this step? Is this actually a problem? Why can&#x27;t X and Y be the same thing? There&#x27;s a myriad of basic foundational questions like this for any set of designs that can help frame the challenges in a new light.</p>
</li>
<li>
<p>The startup designer never simply hands off designs. They care too much to treat them like finished objects to be lobbed over a fence. They document the basics but know there is no substitute for working closely with the team to build it together. New information, such as technical constraints, edge cases, and forgotten error states, always bubbles up while building, and the startup designer is there to help, often jumping into the code.</p>
</li>
<li>
<p>The startup designer is technical. Not just to prototype ideas, help build features or add polish, but also to intimately understand technical constraints of the product which helps them with design exploration.</p>
</li>
<li>
<p>The startup designer knows that new ideas need to be protected and nurtured to be able to have a chance at growing. They will set context with stakeholders, share exploratory visuals or <a href="https://twitter.com/Stammy/status/1364261677898870785">docs</a>, and continually find ways to evangelize.</p>
</li>
<li>
<p>The startup designer talks to customers directly, shares concepts and synthesizes feedback. They tell everyone about <a href="https://www.amazon.com/Mom-Test-customers-business-everyone-ebook/dp/B01H4G2J1U?&linkCode=ll1&tag=paulstamatiou-20&linkId=7bc55d1068cf621d14b3a6bbbe8f98f4&language=en_US&ref_=as_li_ss_tl">The Mom Test</a>.</p>
</li>
<li>
<p>The startup designer knows what altitude to operate at. One feature might require a few optimizations via incremental design, while another may deserve taking a step back and rethinking the entire foundation or direction.</p>
</li>
</ul>
<p>The startup designer may not know to do all these things on Day 1, but learns over time.</p>]]></description>
            <link>https://paulstamatiou.com/the-startup-designer</link>
            <guid isPermaLink="true">https://paulstamatiou.com/the-startup-designer</guid>
            <dc:creator><![CDATA[Paul Stamatiou]]></dc:creator>
            <pubDate>Tue, 27 Aug 2024 00:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Stocketa]]></title>
            <description><![CDATA[<div>Please read <a href="https://paulstamatiou.com/stocketa/" title="Stocketa">this Stocketa article</a> in a browser to see embedded Stocketa videos.</div>
<p>It was March 2020, I was in New England when covid quarantine had just begun and I found myself much more homebound. In these situations I&#x27;m not one to just do nothing. I always have some sort of project or hobby to keep me busy, be it taking and editing photos, writing detailed blog posts, or coding something.</p>
<p>I had always wanted to learn iOS development, so this felt like the perfect opportunity. I was particularly keen to learn SwiftUI to build my designs natively. Years back I had dabbled with writing an Objective-C app, but it never quite filled me with joy, to say the least. As a designer, I&#x27;ve spent the last decade getting good with prototyping tools and frameworks to mimic realistic, interactive mobile prototypes. Building it myself was the natural next step to give me even more control over the experience, and <a href="https://paulstamatiou.com/craft/">get even deeper into the craft.</a></p>
<p>I started learning Swift and SwiftUI basics with courses like Design+Code, and Hacking with Swift. But I knew myself—I learn best with a project of my own. I knew exactly what I wanted to build: a better stock portfolio tracker. The stock market had taken a plunge with covid and I was doing dozens of trades per week with everything on sale. It would be fun to have a simple app of my own to track the performance of my trades instead of dealing with the subpar sites and apps from my stockbrokers.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-stocketa-phone.webp" alt="Stocketa app" width="3442" height="2754" />
<p>Little did I know this project would consume my nights and weekends for over two years, often spending 10-20 hours a week on it. I built a ton of functionality, sweat all the details, wrote a comprehensive node backend for it, created an LLC for it, and managed an active Testflight. I was learning Swift and SwiftUI along the way, so I was often redesigning and rebuilding as I went.</p>
<p>Eventually, I decided to stop pursuing it. I&#x27;ll get into the why a bit later. <strong>This post is for me to document <a href="https://stocketa.com">Stocketa</a>.</strong> I designed and built a lot that I&#x27;m proud of and want to have somewhere to archive it before I pull the plug.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-stocketa-app-store.webp" alt="10 images that would have been used for the Stocketa App Store screenshots if Stocketa had been published" width="3233" height="2720" />
<small>The mostly-finished App Store screenshots that would have been published.</small>
<h3>What is <s>was</s> Stocketa</h3>
<p>Stocketa was a simple portfolio tracker designed with care. It came out of my frustration of having to check the clunky apps and sites that my brokers had just to get a glimpse at how my investments were doing. I&#x27;m a casual investor and don&#x27;t need much from a tool like this but I had assets in various places, and I just wanted one easy and well-designed place to check them. I wanted to see real per-transaction gain/loss info, based on my own cost basis.</p>
<p>While there are tons of apps, brokers, and neobanks that address this, nothing quite felt like what I wanted. There were several types of solutions in this space:</p>
<ul>
<li>First off, there are simple stock apps like Apple Stocks that let you see stock charts, news, and more. They have good data and don&#x27;t require any accounts to use. However, they offer no functionality to log your holdings and track your gains/losses.</li>
<li>There are lots of broker apps (e.g., Robinhood) that let you trade and track your holdings, but they only let you see your holdings from them, not from any other financial services you might use.</li>
<li>Then there&#x27;s a whole category of what I&#x27;d call advanced stock services like TradingView (and several that have since died or pivoted over the years), but they&#x27;re not mobile-first or as elegant as I wanted.</li>
<li>There are broader investment advisor services like Personal Capital. While they do often have some aggregator functionality to link up your other accounts, they&#x27;re not that powerful for diving into individual assets, aren&#x27;t particularly well-designed, and are primarily focused on upselling you on their own investment advising services (seriously, I used to get endless 8am calls from Personal Capital).</li>
<li>And there are lots of smaller apps on the App Store where you can track your holdings but the design and UX leaves a lot to be desired. I&#x27;ve tried most of them.</li>
</ul>
<p>From a design perspective, I generally found that financial apps bias towards density when displaying your assets. They assume you have tons of stocks and prioritize a list view where you have to tap in to a detail view to see more info. I found myself constantly tapping in, manipulating a chart or looking at some basic stats, then swiping back and repeating all that for several stocks. It was not easy or the kind of at a glance info I wanted.</p>
<p>That left me with my challenge. I wanted a <em>simple</em> portfolio tracker aimed at the casual investor. It didn&#x27;t have to do it all, but it should aim to do a few things well. An app just for me.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-stocketa-iphone-DSC06278.webp" alt="Stocketa running on an iPhone" width="3000" height="2007" />
<h3>Going custom</h3>
<p>I was more than thrilled to be working on a new app from scratch. After years of working at large companies with rigid design systems and gobs of stakeholders for every little design decision, I was yearning for some creative freedom. Freedom from process, freedom from typical design constraints. I would be in full control, designing and building it myself. <strong>It was <em>my</em> <a href="https://paulstamatiou.com/side-projects/">side project</a> after all</strong>.</p>
<p>I had gotten tired of designing for traditional mobile apps. You know the type.. you add a tab bar, a typical navigation stack, page header and the app already feels significantly basic, muted, and limited out of the gate.</p>
<p><strong>This was my place to have fun.</strong> I wanted to go custom and toss out whatever components the system gives you for free. And I knew that by having to figure out how to build various UI components from scratch, I&#x27;d learn a lot along the way. Almost all of Stocketa&#x27;s UI is custom.</p>
<p>I will say that <strong>going custom is almost always the absolutely <em>wrong</em> thing to do</strong> 99% of the time. The operating system you&#x27;re working in—be it iOS, Android, macOS—has invested a ton in a highly-considered suite of components. They&#x27;re remarkably accessible, well-tested, and work on a variety of devices.</p>
<p>It&#x27;s absolutely no small feat to consider creating a custom component for your app. However, when going custom does make sense and you&#x27;re okay with the added scope and responsibility, the app becomes your canvas to do whatever you want and <em>make it yours</em>.</p>
<p>The first area where custom made sense for me was general app navigation. When I got started, I knew I wanted this app to have minimal app chrome. I didn&#x27;t want a standard tab bar and header taking up space. I wasn&#x27;t going to require much navigation: most things would just live inside the stock cards from the home timeline.</p>
<p>The app would be focused around showing more with less. Personally, I only cared about tracking a few stocks, but I hated the work of constantly having to tap in to see a detail view, or interact with the chart. As such, the main scroll view needed to be more immersive and not get occluded by unnecessary app chrome.</p>
<p>It started with app navigation, custom stock cards, sheets, and more. Needless to say, I spent a lot of time on the details with everything being custom. Below are a few examples:</p>
<div>Please read <a href="https://paulstamatiou.com/stocketa/" title="Stocketa">this Stocketa article</a> in a browser to see embedded Stocketa videos.</div>
<h3>Designing and building</h3>
<p>I started with the basics: getting a scroll view of stock cards working, adding charts, and hooking it up to a database for persistence (initially Core Data before moving to Firebase). Then I added the requisite network calls and polling to update the stock card from a financial data provider. I started with IEX as the data provider as they had a decent API, reasonable pricing, and allowed commercial use, which would be required for a consumer app like this to go on the App Store.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-early-stocketa-build.webp" alt="Early Stocketa build screenshot" />
<small>Working on an early build in 2020.</small>
<p>One of the initial key decisions with Stocketa was that I wanted to track stock transactions in a comprehensive way. Simply logging the number of shares you had for each stock was not going to cut it. This ended up being a significant amount of work to do properly, but it was necessary:</p>
<ul>
<li>For each stock sale or purchase I wanted to be able to display not only the total gain/loss, but per-transaction gain/loss so you could tell if an individual transaction was a good trade.</li>
<li>When it comes to stock sales, I needed to know the cost basis method (FIFO, LIFO, et cetera) so I could correctly calculate and display the realized and unrealized gains on a particular transaction. When selling shares, I also needed to know from which previous transaction or transactions the shares would be sold so I could get the correct cost basis and accurately calculate the gain/loss based on the cost basis method.</li>
<li>And then there was dealing with stock splits, which seems simple at first glance but ended up being quite a bit of work to build in a robust way: not simply altering previous transactions. They should be automatically applied for new splits, but also able to be manually applied if you didn&#x27;t log split-adjusted transactions.</li>
</ul>
<img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-slides-Stocketa18@2x.jpg" alt="A glimpse at part of how comprehensive transaction types in Stocketa were shown" width="3840" height="2160" />
<small>A glimpse at part of how comprehensive transaction types in Stocketa were shown.</small>
<p>At some point I gave it a name: Stocketa. In Greek you might say "marketa" (Μαρκέτα, though αγορά might be a more proper word) when referring to a market, so this was like coalescing Stock and Market with that in mind.</p>
<hr/>
<p>When I was interviewing for a new job in 2021, I created these slides as part of my presentation after talking about my work at Twitter for the previous 9 years. These weren&#x27;t all of Stocketa slides, and there was a lot of additional talking points I had for each slide, but you get the idea.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-slides-Stocketa01@2x.jpg" alt="" width="2000" height="1125" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-slides-Stocketa02@2x.jpg" alt="" width="2000" height="1125" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-slides-Stocketa03@2x.jpg" alt="" width="2000" height="1125" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-slides-Stocketa04@2x.jpg" alt="" width="2000" height="1125" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-slides-Stocketa05@2x.jpg" alt="" width="2000" height="1125" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-slides-Stocketa06@2x.jpg" alt="" width="2000" height="1125" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-slides-Stocketa07@2x.jpg" alt="" width="2000" height="1125" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-slides-Stocketa08@2x.jpg" alt="" width="2000" height="1125" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-slides-Stocketa09@2x.jpg" alt="" width="2000" height="1125" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-slides-Stocketa10@2x.jpg" alt="" width="2000" height="1125" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-slides-Stocketa11@2x.jpg" alt="" width="2000" height="1125" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-slides-Stocketa12@2x.jpg" alt="" width="2000" height="1125" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-slides-Stocketa13@2x.jpg" alt="" width="2000" height="1125" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-slides-Stocketa14@2x.jpg" alt="" width="2000" height="1125" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-slides-Stocketa15@2x.jpg" alt="" width="2000" height="1125" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-slides-Stocketa16@2x.jpg" alt="" width="2000" height="1125" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-slides-Stocketa17@2x.jpg" alt="" width="2000" height="1125" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-slides-Stocketa18@2x.jpg" alt="" width="2000" height="1125" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-slides-Stocketa19@2x.jpg" alt="" width="2000" height="1125" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-slides-Stocketa20@2x.jpg" alt="" width="2000" height="1125" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-slides-Stocketa21@2x.jpg" alt="" width="2000" height="1125" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-slides-Stocketa22@2x.jpg" alt="" width="2000" height="1125" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-slides-Stocketa23@2x.jpg" alt="" width="2000" height="1125" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-slides-Stocketa24@2x.jpg" alt="" width="2000" height="1125" />
<small>Slides touching on various parts of Stocketa as of late 2021. The design of many of these screens is now outdated, but it&#x27;s a good look at a point in time.</small>
<h3>A note about SwiftUI</h3>
<p>I kept designing, building.. and then redesigning and rebuilding. One of the side effects of learning Swift and SwiftUI as I was building this was that I was constantly redoing specific pages and parts of the app as I went. I continually found better ways to build things, and similarly I would continually refine designs. About a year or so into building Stocketa I <a href="https://paulstamatiou.com/getting-started-with-swiftui/">wrote about my experience with SwiftUI</a>. Much of that still rings true.</p>
<p>SwiftUI has come a long way since iOS 13. It&#x27;s more performant, there&#x27;s more parity in available components and functionality compared with UIKit, and you get more control over things. And with iOS 17, you get some goodies like shaders, keyframes, scroll transitions, and more.</p>
<video controls="false" poster="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-xcode-swiftui-preview-stocketa-poster.webp">
      <source src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-xcode-swiftui-preview-stocketa.webm" type="video/webm">
      <source src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-xcode-swiftui-preview-stocketa.mp4" type="video/mp4">
      Your browser does not support the video tag.
    </video>
<small>Xcode showing a SwiftUI preview.</small>
<p>There&#x27;s still a gap between the types of things you can do with AppKit and UIKit, but SwiftUI is undeniably a powerful tool that&#x27;s dramatically more approachable. And not just a coding tool; it&#x27;s a great design tool. Designers can quickly lay things out, hook up interactions, and get a real feel for a design using a native tool.</p>
<p>Almost all of Stocketa&#x27;s UI is built with SwiftUI. There were only a few occasions when I found it necessary to use UIKit to achieve some goal.<sup><a rel="footnote" href="#footnote-1" id="r1">1</a></sup> None of this would have been possible, or drawn me to take a closer look into building iOS apps, if it hadn&#x27;t been for SwiftUI.</p>
<h3>What I built</h3>
<p>I used the app daily and continued pouring time into every feature and detail to meet my high quality bar. While I initially planned for this to be a simple to build app that would not require a backend, or even any user accounts, that did not last for long. I quickly realized I needed my own backend to unlock a few things.</p>
<p>At first, this was so I didn&#x27;t have to include the API key for my financial data provider inside the app for security reasons—I wouldn&#x27;t want someone to find it and start running up my bill by abusing it. I created a backend proxy for the API with rate-limiting and throttling. Then, I wanted to have it be authenticated with user accounts, so I added Sign In With Apple along with a stock data caching system so that I only had to fetch stats for a stock once with a certain time period (depending on the particular stat that was either seconds, 24 hours, or weekly) regardless of however many user accounts needed that stock info. The main goal with that was to also reduce my costs associated with financial data API usage.</p>
<p>By this point I really started enjoying the speed at which I could update endpoints and business logic entirely on the backend. I started moving logic I had in the app to the backend. <strong>Stocketa was starting to come together.</strong></p>
<p>Even though this was just a solo project, I used Linear to keep track of tasks, ideas, features, customer feedback, and milestones.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-stocketa-linear.webp" alt="My Linear app usage for Stocketa" />
<p>I had prioritized lists of things to build and bugs to fix. I was using—and loving—Linear for this. Here&#x27;s a list of <em>most</em> of the things I built for Stocketa:</p>
<div>Please read <a href="https://paulstamatiou.com/stocketa/" title="Stocketa">this Stocketa article</a> in a browser to see embedded Stocketa videos.</div>
<p>I ran a small TestFlight alpha with close friends, then increasingly I added more people. At one point I was up to around 1,000 people. That was the most I wanted to allow. I received lots of feedback from overall great first impressions (below), to general feature requests, and of course lots of bug reports.</p>
<blockquote>
<p>Already the app is filling a need for me in its personal approach to tracking investments: no pushing for sales, no integrations with brokers and no unnecessary permissions. Brilliant.</p>
</blockquote>
<blockquote>
<p>Simply amazed at the SwiftUI work you’ve poured into this app. So beautiful. The onboarding alone is a masterclass in attention to detail. Bravo.</p>
</blockquote>
<blockquote>
<p>love it, this feels so polished and slick already... really great use of SwiftUI</p>
</blockquote>
<blockquote>
<p>Just got the invite, added my stocks... the animations are beautiful, design is clean and precise... it’s all around beautiful. Congrats!</p>
</blockquote>
<blockquote>
<p>F**k, man. This app is incredible. You’re building all of this on your own?</p>
</blockquote>
<blockquote>
<p>Dude. This app is f**king beautiful. Really great job. Just imported shares - super easy.</p>
</blockquote>
<blockquote>
<p>This NUX is insane. The particles when you add a stock. Gives me the happy brain chemicals..</p>
</blockquote>
<p>I had thousands on a waiting list but there were API and hosting costs associated with the increased usage that I didn&#x27;t want to bear yet, as well as a huge increase in support and customer feedback that took a lot of time to manage. You start to hear the same types of feedback, and it just becomes a chore to manage that many emails. That good news was that something was resonating and people cared enough to go through the work to send in bug reports and feature requests.</p>
<h3>The website</h3>
<p>At some point early in feature development I took a break to focus on the website. At first I wanted a simple landing page to build interest, and collect emails for a waitlist so I could keep people in the loop. And I didn&#x27;t want to spend that much time on it.</p>
<video controls="true" poster="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-stocketa-v0-landing-page-poster.webp">
      <source src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-stocketa-v0-landing-page.webm" type="video/webm">
      <source src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-stocketa-v0-landing-page.mp4" type="video/mp4">
      Your browser does not support the video tag.
    </video>
<small>Video: Initial Stocketa teaser homepage.</small>
<p>There was nothing fancy or particularly special about this initial page. It was just something quick I wanted to get out the door. And now, a while later, there&#x27;s a lot I hate about this early design. The background texture was too strong, the headline alignment feels odd with the phone.. but I digress.</p>
<p>In that initial design I did start playing with some wave-related elements—a loose reference to stock market charts going up and down. And then to add to that, I built a few mini stock cards gently hovering in place (thanks to <code>offset-path</code> CSS along with 2 keyframe animations) in the background. Each stock card had an SVG line chart—loosely based on that stock&#x27;s actual performance around the time—that would animate on page load. I ended up keeping a version of these mini stock cards on the latest version of the website, and then on an onboarding screen inside the app.</p>
<p>The original inspiration for these random floating stock cards was from my now <a href="https://paulstamatiou.com/work">out-of-date work page</a> where I highlighted projects with some large cards, each with their own intro animation based on the project. One of them was for my work on Twitter Video, where video clip thumbnails would fan out from the phone on hover (shown below).</p>
<video controls="true" poster="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-portfolio-twitter-video-hover-poster.webp">
      <source src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-portfolio-twitter-video-hover.webm" type="video/webm">
      <source src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-portfolio-twitter-video-hover.mp4" type="video/mp4">
      Your browser does not support the video tag.
    </video>
<small>The floating mini stock cards on the Stocketa homepage were inspired by the hover state animation on this project card from my old portfolio page.</small>
<h3>Homepage design <code>v1.0</code></h3>
<video controls="true" poster="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-old-stocketa-website-poster.webp">
      <source src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-old-stocketa-website.webm" type="video/webm">
      <source src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-old-stocketa-website.mp4" type="video/mp4">
      Your browser does not support the video tag.
    </video>
<small>Video: The first full version of Stocketa.com in early 2021, currently <strong><a href="https://stocketa.com/v1/">archived here</a></strong>. The App Store QR code was meant to be displayed on scroll but in this version I didn&#x27;t have that hooked up as the app wasn&#x27;t live.</small>
<p>In early 2021 I ended up getting around to designing and building out the first complete homepage for Stocketa. I had enough functionality and features built that it felt worthy of investing some time into showcasing them on the site.</p>
<p>Lots of app websites at the time (and still now) had the typical hero section on their homepage: some app screenshot in a phone frame off to one side, with accompanying header and subtitle text adjacent. Nothing wrong with that, but I wanted something a bit more engaging. I wasn&#x27;t entirely interested in optimizing for conversion, and cramming a lot in above the page fold.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-old-stocketa-explorations.webp" alt="Old Stocketa explorations" />
<small>Initial design explorations in figma.</small>
<p>I thought it would be nice to try to do something where the 3D phone frame was angled and then began to change position on scroll while a brief teaser video of the app functionality played. Apple had done something similar in recent years with product pages, such as the first-generation AirPods Pro. They used over 100 frames of the AirPods that would progress as you scrolled:</p>
<video controls="true" poster="https://turbo.paulstamatiou.com/uploads/2023/08/airpods-pro-first-gen-site-animation-poster.webp">
      
      <source src="https://turbo.paulstamatiou.com/uploads/2023/08/airpods-pro-first-gen-site-animation2.mp4" type="video/mp4">
      Your browser does not support the video tag.
    </video>
<small>Example of a technique used by Apple.</small>
<p>There&#x27;s a lot of ways to achieve an effect like this. One route route is using Lottie and essentially converting each frame of your video or animation to a base64-encoded string in a json file for the Lottie web player to manage. It&#x27;s not a flawless solution, however, and can incur some large file sizes depending on what you&#x27;re doing. It&#x27;s best for vector micro-animations, not large devices with complex visual content. I also didn&#x27;t want to incur the cost of that large initial json download blocking the very first thing you see on the site.</p>
<p>Instead I opted to have javascript display a sequence of frames composited to <code>canvas</code> along with an offscreenCanvas for performance. I used <a href="https://rotato.app/">Rotato</a> to import my short Stocketa screencast, create a 3D phone video, and then create a PNG sequence of frames. I wasn&#x27;t super pleased with the quality—the phone frame didn&#x27;t look super realistic and had some rough pixelated edges—but it was good enough compared to doing it all by hand with other design tools.</p>
<video controls="true" poster="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-old-stocketa-website-hero-animation-poster.webp">
      <source src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-old-stocketa-website-hero-animation.webm" type="video/webm">
      <source src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-old-stocketa-website-hero-animation.mp4" type="video/mp4">
      Your browser does not support the video tag.
    </video>
<small>Scroll-based Stocketa 3D phone, paired with subtle parallax for header elements and the floating stock cards. There were some other minor scroll effects like the gradient glow behind the phone spreading.</small>
<p>I then exported optimized transparent webp, and jpg files (with accompanying alpha masks created in Sketch to save bandwidth) and had the javascript detect which file type to use for the animation. While I was pleased with how this effect turned out, it ended up becoming a rather huge annoyance when I wanted to update the content later—it&#x27;s a pain to generate, optimize, and update the image sequence each time.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-old-stocketa-site-grid-layout-2.webp" alt="Old Stocketa Layout" width="3278" height="2452" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-old-stocketa-site-grid-layout-1.webp" alt="Old Stocketa Layout" width="3244" height="2400" />
<small>Other bits of the website: cards for various features.</small>
<p>And finally, as for the rest of the content on this site I went with a basic feature card approach, sometimes called a "bento box" layout; particularly when varying card sizes are used. This is a layout that I&#x27;ve grown to like a bit less over the years as it has become very common.</p>
<h3>Homepage design <code>v2.0</code></h3>
<video controls="true" poster="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-new-stocketa-website-poster-2.webp">
      <source src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-new-stocketa-website.webm" type="video/webm">
      <source src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-new-stocketa-website.mp4" type="video/mp4">
      Your browser does not support the video tag.
    </video>
<small>Video: New Stocketa site</small>
<p>A year later, it was time for another redesign. Stocketa had more functionality, and a lot more refinements. I had more to share, and I had grown tired of the 3D phone frame interaction. It was neat but it was just there for show; it wasn&#x27;t the best way to show off parts of the app as it scrolled off screen. It was also a pain to update the frame sequences. I essentially just wanted to take screenshots of the real app from the iOS simulator and upload them.</p>
<p>Separately, I didn&#x27;t want a super long page with a lot of repetitive modules and screenshots. I wanted a skimmable feature list. I began to wonder if I could get away with just a single phone frame on the site that showed everything.</p>
<p>I eventually landed on a two pane approach: the device frame was always in view, fixed on the right side, while the scrollable left side contained the feature list. The trade-off with this design was that it would require hovering over each feature item to be able to update the screenshot shown in the device frame. I figured an interesting compromise to that would be having the phones stack up and away on scroll. Almost like the old Apple Time Machine backup UI.</p>
<p>I built several versions of this and found that it didn&#x27;t feel great. There wasn&#x27;t much scroll distance so if you scrolled at a normal or fast pace, you&#x27;d see a bunch of phones flicker by you as the animations tried to keep up. It was too busy and hectic, not to mention a lot of state management to deal with jumping between your current scroll-based position screenshot to a hover-based screenshot if you hovered over a feature list item. I ended up simplifying a bit and only having the scroll-based UI manage just a few states: the intro phone frame, the first feature screenshot, and then a final animation at the bottom of the page.</p>
<video controls="true" poster="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-stocketa-homepage-v2-responsive-poster.webp">
      <source src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-stocketa-homepage-v2-responsive.webm" type="video/webm">
      <source src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-stocketa-homepage-v2-responsive.mp4" type="video/mp4">
      Your browser does not support the video tag.
    </video>
<small>The website&#x27;s mobile layout uses a carousel of screenshots in the header.</small>
<p>After sorting out the core interactions, I had to figure out how to deal with mobile and tablet interactions. The fix two-pane layout made this a bit of a challenge. I ended up turning the header into a carousel of device frames you could scroll through.</p>
<p>And then finally, I added a few small bits of polish ✨:</p>
<ul>
<li>Hero title text gradient changes based on scroll</li>
<li>The icon accent color and background circle color change based on scroll</li>
<li>When hovering over any feature list item, there is a subtle background color change created by an overlaid gradient. SVG-created noise/grain is also overlaid on top of the background.</li>
<li>When hovering over any feature list item, or when you&#x27;re reached the end of the page, there&#x27;s a subtle icon particle emitter that floats up icons from the bottom. Each feature used a different icon for this.</li>
</ul>
<video controls="true" poster="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-stocketa-homepage-v2-particle-emitter-poster.webp">
      <source src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-stocketa-homepage-v2-particle-emitter.webm" type="video/webm">
      <source src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-stocketa-homepage-v2-particle-emitter.mp4" type="video/mp4">
      Your browser does not support the video tag.
    </video>
<small>Particle emitter effects: icons float up from the bottom, based on the feature list item being hovered on. There&#x27;s also another very subtle emitter generating some tiny floating particles.</small>
<p>Overall I liked this design, but looking back at almost a year later, the gradient text and background colors feel a bit too much for my taste now.</p>
<h3>API troubles</h3>
<p>Eventually it became clear that the quality of financial data Stocketa relied on was not cutting it. The first provider I used, IEX, would sometimes have charts outdated, inaccurate prices (especially for less frequently traded assets on the IEX exchange), and lacked data for OTC markets (they required you sign a pricey license directly with OTC), as well as significantly limited data for Nasdaq-listed stocks (even basic things like pre-market and after-hours data). The last straw was when IEX dropped mutual fund data entirely, all without any advance notice.</p>
<p>I later used another provider that allowed commercial use that didn&#x27;t charge too much ($100/month) but I had even more problems with their data and reliability. Endpoints were even returning old and incorrect data, and even once alerted to issues, their team would not only ignore the bugs but claim they didn&#x27;t exist. I couldn&#x27;t ship Stocketa with unreliable financial data to people that would be paying me for a quality app.</p>
<p>I also could not get certain types of data with paid APIs. I had to build a scraping engine on my backend that would visit a few sites to get the data I needed for less updated data like dividend yield, earnings dates, and even for OEF data (other providers would be more than a day delayed for this at times).</p>
<p>Needless to say, this was all frustrating. It was a hassle, hard to maintain, and unreliable. At the same time, my backend continued getting more involved to deal with more and more of the intricacies of dealing with stocks. Things like dealing with companies merging or stock tickers renaming.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/08/copyright-paulstamatiou_com-stocketa-backend.webp" alt="Stocketa Backend" />
<small>~13k LOC node/express backend (shown in Zed but I now prefer <!-- --><a href="https://twitter.com/Stammy/status/1713303350987698459">Cursor</a><!-- -->) for Cloud Run. It manages auth, caching, news, core business logic, cleaning up data, notifications, widgets, working with multiple API, and a bit of scraping. This was my first time doing anything of this size with node and typescript.</small>
<p>Starting out I thought getting access to a stock market data API would be the easy part. I quickly learned about the world of market data feeds, SIPs (Securities Information Processor), and vendor agreements.</p>
<p>Quality market data exists, it&#x27;s just not made for indie app developers. It&#x27;s very expensive. Several leading U.S. market data providers have commercial use data pricing starting at $2,000 per month. And that&#x27;s not for everything, if you need things like index data or options data, there&#x27;s more charges ahead.</p>
<p>I spoke with one of these providers last year, trying to get them to understand how small app developers need affordable commercial use data. They presented a startup-focused plan that they were pitching for $499/month in addition to a per-MAU fee. Even that I would still consider very expensive for my needs, and it seems like that may have fallen by the wayside and is no longer promoted on their website.</p>
<p>I could spend months developing Stocketa, incurring that monthly API cost until I went live (or risk getting shutdown if I tried to use a cheaper non-commercial plan during the TestFlight phase) then not make enough money to cover costs on the App Store and have to shut it down shortly after anyways.</p>
<p>Overall, it feels like no one in this cares to cater to the developer and startup crowd, or they believe there&#x27;s not much money for them to pursue there. This was the same case with Plaid when I briefly looked into getting access to their investments API to automatically sync holdings data. They required some sort of minimum length contract.</p>
<h3>Why I stopped working on Stocketa</h3>
<p>When I started this project, I really began to wonder why where weren&#x27;t any great indie apps focused on stocks like this. Just simple, well-designed apps to help the casual investor keep track of their investments. Well I think I was starting to get my answer: getting quality financial data, even just for the United States, is a nightmare. You can only get it if you have a lot of money to invest in your project. And good luck if you really want a great API with comprehensive international data.</p>
<p>I can&#x27;t help but draw parallels to what happened recently with the Twitter and Reddit APIs. The risk of running your project or business solely on top of another company&#x27;s API, no matter how reliable you think they may be, is extremely high.</p>
<p>Stocketa was always meant to be a side project—never a real business. For it to be a real business, I would need to keep adding functionality and introducing more ways to make money. I couldn&#x27;t just have a simple and elegant little app tracking your stocks. It would have to do more, like dipping into financial advice services, or offering stock trading. That&#x27;s a hyper-competitive space lined with massive companies. That would mean a busier, cluttered app. The exact reason why I started Stocketa was because of all those cluttered apps.</p>
<p><strong>I decided to stop working on Stocketa for a few reasons:</strong></p>
<ul>
<li>
<p><strong>Data:</strong> As mentioned above, all the expenses and challenges associated with acquiring reliable, affordable, and high-quality financial data that would make it feasible to release this as a reasonably priced subscription-based app.</p>
</li>
<li>
<p><strong>Support:</strong> The associated investment in customer support. Based on how people were using my TestFlight, it was going to be a significant investment to keep up with support, emails, maintenance, and ongoing feature development. However, part of this was likely due to complexity incurred from having to fix or skirt around unreliable data. There were lots of things I wanted to keep improving and refining with the app and that wouldn&#x27;t end any time soon.</p>
<p>If I were to release and charge for Stocketa, I would feel especially on the hook to resolve issues in a timely manner and that&#x27;s not something I can accomodate now because of the next point.</p>
</li>
<li>
<p><strong>Time:</strong> And most importantly, I&#x27;ve found something more worthy of my complete focus and attention: Rewind AI. I sunk a lot of nights and weekends into Stocketa over the years. It consumed every spare moment, even taking over my occasional time writing blog posts here when I had something to share. That was something I really missed. Now, I would much rather be focusing my creative thinking time on how I can improve and grow Rewind.</p>
</li>
</ul>
<p>I originally started working on Stocketa with one goal: to learn Swift and SwiftUI my way with a project that was interesting to me. At the time that was scratching my own itch of keeping track of my investments. While it turned into a much larger and unshipped project, I learned a ton about native iOS development and was able to push myself creatively.</p>
<p>These days I&#x27;m happiest investing my design, product and development time into Rewind AI, where my SwiftUI knowledge learned with Stocketa has been tremendously helpful.</p>
<br><br><br><hr><br><h3>Footnotes</h3><p><a href="#r1">1</a><!-- --> I only had to go down to UIKit a few times. One time for things like custom text fields for more control over interactions, styling, text input, and formatting. Another to use a CollectionView for drag-to-reorder stocks. A third time for creating particle emitters in a few places, like confetti effects, as well as one area where I have some twinkling stars in a night illustration when the stock market is closed. And one last time to get more control over gestures. I needed to get a location when a long press <em>begins</em> and SwiftUI LongPressGesture() didn&#x27;t provide that, so I used UILongPressGestureRecognizer instead.</p>]]></description>
            <link>https://paulstamatiou.com/stocketa</link>
            <guid isPermaLink="true">https://paulstamatiou.com/stocketa</guid>
            <dc:creator><![CDATA[Paul Stamatiou]]></dc:creator>
            <pubDate>Mon, 16 Oct 2023 00:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Digital clutter]]></title>
            <description><![CDATA[<p>I started taking photography more seriously about a decade ago. I shot photos in RAW with increasingly higher megapixel cameras, spent a lot of time post-processing photos—see my 30K word post about <a href="https://paulstamatiou.com/building-a-windows-10-lightroom-photo-editing-pc/">building a custom Adobe Lightroom PC</a>—and designed and built custom photo stories to share them.</p>
<p>While I would go through the process of culling photos that I published online, I didn’t do that for what I backed up. I kept <em>everything</em>. I always thought, "what if I want to go back to this and edit it differently one day?"</p>
<p>I kept every RAW photo I shot, every video, every GoPro clip... I even kept every phone photo going back to my first iPhone. And why not, storage is cheap and easy, right?</p>
<p>The terabytes kept adding up. I added close to a terabyte with <a href="https://paulstamatiou.com/photos/new-zealand/">New Zealand</a>. Hundreds of gigs with <a href="https://paulstamatiou.com/photos/africa/">Africa</a>. When you hit a few terabytes the obvious solution is to move to a NAS, or Network Attached Storage. I wrote about this extensively in 2015 with <a href="https://paulstamatiou.com/storage-for-photographers-part-2/">Storage for Photographers (Part 2)</a>.</p>
<p>Years back these were pretty dumb devices that would just appear as a networked drive for your computer to manage. Today, they’re full-blown personal servers, capable of running self-hosted apps and services. That makes it easy to have them encrypt your data, and automatically back your files up to cloud services, which is probably what you want if you’re paranoid about backups and try to follow the 3-2-1 rule.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2017/08/copyright-paulstamatiou_com-DSC05186-2000.jpg" alt="NAS setup" />
<small>My NAS setup some years back.. it became far messier over the years after I moved to NYC and had less space for networking gear.</small>
<p>Over the years I paid thousands of dollars just to keep those RAW photos safe. At one point I think I had copies on 3 or 4 separate cloud services.. you know, just in case. I later upgraded to another NAS that was physically a bit smaller.</p>
<p>In hindsight, I couldn&#x27;t care less about 90% of all that data, if not more. The fact that I had terabytes of available storage made it all too easy to not be picky with what I was backing up and just archive everything.</p>
<p>When it was time to move to a different apartment, I took that as the perfect excuse to simplify. I no longer wanted a NAS in my life. A little whirring box, always making random hard drive noises, always taking up space, always making heat. Though I’m sure my perspective would be a bit different if I had enough space to hide the NAS in a perfect server closet completely out of sight and mind.</p>
<p>I needed to get rid of tons of RAW photos for which I no longer cared. I knew I wouldn’t be able to get rid of everything and I still wanted maybe 2 TB of local storage, separate from my computer. My first inclination was to just look for a tiny NAS that I could load up with 2.5” SATA SSDs, or something even better like M.2 NVMe SSDs. I didn’t find anything I liked—most small NAS devices would still require some massive barrel-jack power adapter.</p>
<h3>Picking an M.2 SSD enclosure</h3>
<p>I ended up deciding to get a small, simple external Thunderbolt SSD enclosure. In particular, I wanted an M.2 NVMe SSD enclosure. M.2 SSDs are much smaller and faster than other modern SSDs using SATA. I wanted an small, bus-powered enclosure that was Thunderbolt 3 or 4, and had some basic heatsink or thermal pad for the SSD.</p>
<p>There were a few options I looked at. The <a href="https://www.amazon.com/dp/B07ZWPH7G3?_encoding=UTF8&psc=1&linkCode=ll1&tag=paulstamatiou-20&linkId=ec9bd7e1c319cc02b39d8045c1d94095&language=en_US&ref_=as_li_ss_tl">Sabrent Rocket Nano</a> looked perfect at first glance due to its tiny size but they don&#x27;t sell it as an enclosure, and it&#x27;s only USB-C, not Thunderbolt, so I ruled that out. Then I looked at a <a href="https://www.amazon.com/Thunderbolt-Certified-Tool-Free-Enclosure-EC-T3NS/dp/B08FT59SB6?ie=UTF8&linkCode=ll1&tag=paulstamatiou-20&linkId=e9fc4a2515dc46de1493ee73d89912ad&language=en_US&ref_=as_li_ss_tl">Thunderbolt 3 enclosure from Sabrent</a>. Unfortunately, some reviews pointed out issues with performance and reliability that had me concerned. There was also a new <a href="https://satechi.net/products/usb4-nvme-ssd-pro-enclosure?variant=40188470067288">Thunderbolt 4 enclosure from Satechi</a>, but it wasn&#x27;t shipping (and still seems to be out of stock). That aside, it looked like a great option, but it was far too large for some reason.</p>
<p>After a lot of looking I eventually landed on the <a href="https://www.amazon.com/OWC-Envoy-Express-Thunderbolt-Enclosure/dp/B08LYQPRPJ?&linkCode=ll1&tag=paulstamatiou-20&linkId=6eab0ee6644082eab4ef5f7e6ba7ea89&language=en_US&ref_=as_li_ss_tl">OWC Envoy Express</a>. I was hoping for a more aesthetically pleasing option but OWC has been a reputable brand I&#x27;ve been familiar with so it felt like the safe option. I don&#x27;t like how the Thunderbolt cable is part of the case design (you can detach it but you have to open the case), but it wasn&#x27;t a dealbreaker for me. At the time I purchased this, it was a bit cheaper at $79.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/04/copyright-paulstamatiou_com-owc-envoy-express-ssd.jpg" alt="OWC Envoy Express Thunderbolt 3 SSD enclosure" />
<small>The Envoy Express enclosure alongside a cheaper USB-C enclosure I got for another spare SSD I had.</small>
<p>The Envoy Express enclosure is all metal and seems very well-made so I&#x27;m quite pleased with it.</p>
<p>As for what SSD to use with the enclosure, I decided to use one I already had: an older 2 TB Samsung 970 Evo. At the time I was also parting out and selling <a href="https://paulstamatiou.com/gear/desktop-pc/">my gaming PC</a> (didn&#x27;t use it enough after I got an Xbox Series X and it was taking up space) and I decided to repurpose the 2 NVMe SSDs I took from it. If you want to do the same, you can find affordable 1 and 2 TB options from Western Digital, Samsung, and SK Hynix among others. It&#x27;s when you start looking for 4TB SSDs that the prices go up considerably.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2019/05/copyright-paulstamatiou_com-DSC2824-2000.jpg" alt="My old desktop PC" />
<small>My old desktop PC where I salvaged my M.2 SSDs from</small>
<p>Installing the SSD in the OWC enclosure took less than a minute. There&#x27;s two screws to open the case, then one more screw to fasten the SSD. The case has a built-in thermal pad that touches the top of the SSD, though I wish it had some sort of cooling for the bottom as well.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/04/copyright-paulstamatiou_com-owc-envoy-express-ssd-2.jpg" alt="Samsung 970 EVO SSD inside OWC Envoy Express Thunderbolt 3 enclosure" />
<small>Breathing new life into my old 970 EVO M.2 SSD by putting it in the OWC Envoy Express enclosure.</small>
<h3>Setup and disk encryption</h3>
<p>The next thing I did was open up Disk Utility on macOS, format the SSD, then set up encryption. While there&#x27;s lots of ways to encrypt your data—like VeraCrypt which touts plausible deniability with hidden volumes—I opted for the <a href="https://support.apple.com/guide/disk-utility/encrypt-protect-a-storage-device-password-dskutl35612/mac">encryption functionality built into macOS</a> for simplicity.</p>
<p>With the SSD ready to go, the hard part was determining what photos and data I wanted to from my NAS I wanted to keep and transfer to this SSD. This was made particularly hard as my NAS was very slow. I had gigabit ethernet but that doesn’t matter, these spinning disks are barely faster than 100MB/s for sequential read even with a RAID setup. So my long process over a week or so was transferring a folder or two to my laptop overnight, as much as I could with the available space I had on my MacBook Pro&#x27;s internal SSD.</p>
<p>Once on my laptop I had to go through and decide what to delete and what to keep. There were a lot of easy ways I was able to save space by cutting things like GoPro videos of which I had hundreds of gigs from trips. I didn&#x27;t care for that footage much and the important clips I had already used in other videos elsewhere.</p>
<p>But there&#x27;s no getting around it, this was an arduous process. For some older trips I only kept the post-processed original size JPGs and deleted the RAWs. Then there were tons of just random photos I deleted. It took me a few days but eventually I was able to shave a few terabytes; enough to fit the important stuff on this 2 TB SSD. (I had a bit of overflow which I tossed on the other USB-C external enclosure I had which I won&#x27;t use often so the speed isn&#x27;t important).</p>
<h3>Cloud encryption and backup</h3>
<p>With the photos and data trimmed down and ready to transfer to the SSD, I needed to figure out how I wanted to have this SSD backed up and encrypted on cloud services. For that I turned to <a href="https://www.arqbackup.com/">Arq</a>.</p>
<p>Arq is a backup power tool for advanced users. It&#x27;s a standalone Mac app that connects to just about any cloud service including AWS, Backblaze, OneDrive, Wasabi, Google Cloud, as well as all S3-compatible storage providers. The best part is that you bring your own credentials for those cloud services, and you have fine-grained control over how things are backed up, stored, encrypted, and much more.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/04/copyright-paulstamatiou_com-arq-macos-ssd-backup.jpg" alt="Arq backup app for macOS" />
<p>I decided to separate my photos and other more important data into different folders with different backup strategies. Photos took up most of the 2 TB and I wanted them backed up but I didn&#x27;t expect to access them frequently so I didn&#x27;t want to use the Amazon "S3 Standard" storage class. I decided to use S3 Glacier Instant Retrieval for my photos.</p>
<p>I&#x27;m no stranger to Glacier, Amazon&#x27;s slower and cheaper data archival storage tier, and have been using some form of it for a decade, but I never had a great experience. It always felt unpredictable and slow; yes, I realize that&#x27;s the basically the trade-off you sign up for. As of 2021, Amazon added a new type of Glacier storage called Instant Retrieval. So you get the benefit of more affordable data archival storage along with quicker retrieval times.</p>
<p>There&#x27;s quite a few S3 storage classes to select from: Standard, Standard Infrequent Access, One Zone Infrequent Access, Glacier Instant Retrieval, Glacier Flexible Retrieval, Glacier Deep Archive. It&#x27;s important to familiarize yourself with the <a href="https://aws.amazon.com/s3/storage-classes/">functionality of the S3 storage class</a> you plan on using. And that&#x27;s just with AWS, you can to use any other cloud provider you like with Arq.</p>
<p>To give you a rough idea of the prices associated with some of these S3 storage classes, <strong>here&#x27;s what it would cost to store 2 TB per month</strong>, with no other actions or transfers:</p>
<table><thead><tr><th>S3 Storage Class</th><th>Monthly price to store 2 TB</th></tr></thead><tbody><tr><td>S3 Standard</td><td>$47.10 USD</td></tr><tr><td>S3 Standard Infrequent Access</td><td>$25.60 USD</td></tr><tr><td>S3 One Zone Infrequent Access</td><td>$20.48 USD</td></tr><tr><td>S3 Glacier Instant Retrieval</td><td>$8.19 USD</td></tr><tr><td>S3 Glacier Flexible Retrieval</td><td>$7.41 USD</td></tr><tr><td>S3 Glacier Deep Archive</td><td>$2.05 USD</td></tr></tbody></table>
<p>And then, for my other data, which was more important and not nearly as sizable, I opted for S3 Standard Infrequent Access. Here&#x27;s how that looks in Arq:</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/04/copyright-paulstamatiou_com-arq-macos-ssd-backup-settings-3.jpg" alt="Arq showing different S3 storage classes for different folders" />
<small>Arq showing different S3 storage classes for different folders</small>
<p>Arq also lets you specify encryption for your data—separate from the macOS encryption I set up that&#x27;s required to mount the drive—so I did that as well. It&#x27;s important to note that you will need the Arq client to be able to access the encrypted files again; they&#x27;re unreadable if you go directly to the storage bucket on S3.</p>
<p>That&#x27;s it! I&#x27;m very happy with the new setup. I&#x27;m relieved to no longer have a NAS taking up space and making noise in my house. The external SSD is tiny and I still have control over where my data is backed up online. I can easily add more cloud storage destinations later on as I see fit.</p>
<h3>Cloud control</h3>
<p>However, after all this work slimming down my archives, the job is not done. My NAS was just the first target. I still have a stockpile of data and memories across other services like Google. Take Google Photos for example. Absolutely amazing service. I love the heck out of the product. And while Apple&#x27;s Photos functionality is great, I&#x27;ve always loved all that Google Photos had to offer from amazing search to strong sharing functionality.</p>
<p>I just wish Google Photos wasn&#x27;t owned by Google. I&#x27;m trying to reduce my reliance on consumer-oriented Big Tech products like this in favor of services where I have more control. Google has been heralded for their data portability tool Google Takeout, which includes Google Photos data, but in my experience using it was all but pleasant.</p>
<p>First, I had to wait days to let the archives prepare, which I understand what needs to happen with this much data so that&#x27;s fine. But then, I had to download more than a dozen separate zipped files amounting to over 800 GB. I don&#x27;t even think I had that much space on my laptop, let alone extra space to be able to unzip them all. And once unzipped, I don&#x27;t recall the files having any sort of helpful organization to make it feasible to trim down moments you don&#x27;t need. I gave up on that.</p>
<p>Cloud storage services make it all too easy to eagerly backup anything and everything without being intentional. Now we&#x27;ve all inadvertently become data hoarders.</p>
<p>Just because we have easy access to near-infinite and increasingly more affordable storage doesn&#x27;t mean we <em>should</em> be using all that space. The next generation of cloud-based services need to design for curation and control. It doesn&#x27;t feel like an immediate concern, but it will only continue to increase.</p>
<p>These days getting your Google account hacked isn&#x27;t just about your email. It may be about your entire digital life. This is more than just decluttering, it&#x27;s about control, <a href="https://paulstamatiou.com/getting-started-with-security-keys/">security</a> and privacy too.</p>]]></description>
            <link>https://paulstamatiou.com/digital-clutter</link>
            <guid isPermaLink="true">https://paulstamatiou.com/digital-clutter</guid>
            <dc:creator><![CDATA[Paul Stamatiou]]></dc:creator>
            <pubDate>Sat, 15 Apr 2023 00:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Hosting your own Mastodon server]]></title>
            <description><![CDATA[<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-mbp.jpg" alt="Mastodon admin settings for discovery" />
<p>A lot has happened since I published my article on the <a href="https://paulstamatiou.com/mastodon/">open source decentralized social networking service Mastodon</a> a few weeks ago. I saw a lot of interest in and discourse around that post that was great to see. Since then, a few notable things have happened that have caused Mastodon usage to spike yet again.</p>
<p>Twitter unsurprisingly ended up entirely banning third-party Twitter clients, including hugely popular ones like Tweetbot and Twitterific. I briefly summarized the ebb and flow of being a developer working with the Twitter API in the last post:</p>
<blockquote>
<p>"Long story short, Twitter made it hard. Hard to even get an API key and get your app approved. Hard to get bugs fixed or new features accessible via the API. Hard to access the data developers wanted. Hard to not hit arbitrary constraints or limits. Things were always changing, rugs were pulled, announcements about new priorities and new rugs were made, only for them to be pulled again (read <a href="https://www.theverge.com/2021/11/15/22779149/twitter-api-version-2-official-decentralized">this</a>, <a href="https://techcrunch.com/2022/11/02/twitter-cancels-its-chirp-conference-for-developers-amid-management-transition/">this</a> and <a href="https://techcrunch.com/2022/12/15/developer-platforms-are-all-about-trust-and-twitter-lost-it/">this</a>)".</p>
</blockquote>
<p>Well, the final rug was pulled. Fortunately, there was a bit of a silver lining. The folks at Tapbots were able to launch their lovely Mastodon app <a href="https://tapbots.com/ivory/">Ivory</a>. The launch went so well that a flood of people took that as an opportunity to take a closer look at Mastodon and join. Mastodon has grown from 500,000 active users last year to now being <a href="https://mastodon.social/@mastodonusercount">almost at 10 million</a>.</p>
<p>Mastodon just keeps getting better. There&#x27;s more authentic conversations and far less linkbait and thread spam from influencers. It feels like a place I&#x27;d prefer spending more of my time to catch up on things.</p>
<p>With my interest in Mastodon, I recently decided I wanted to take the next step and host my own Mastodon server for my account: <a href="https://stammy.design/@stammy">@stammy@stammy.design</a>. In my <a href="https://paulstamatiou.com/mastodon/">previous post about Mastodon</a> I provided some details about different routes you could take to self-host Mastodon. Today, I&#x27;ll show you how you can host your own Mastodon instance, step-by-step.</p>
<div><h3>Table of contents</h3><p>This is a long post and took me more than a month to write, but you don&#x27;t have to go through it all. At a high-level I show two routes to hosting your own Mastodon server: a simple route employing a fully-managed webhost, and a much more comprehensive and advanced route involving a traditional webhost.</p><p>I also make sure you&#x27;re good to go with maintenance tips, debugging tips, scripts to backup your database, purge storage and more.</p><ul>
<li><a href="https://paulstamatiou.com/hosting-your-own-mastodon-server/#so-you-want-to-host-your-own-mastodon-server">So you want to host your own Mastodon server?</a></li>
<li><a href="https://paulstamatiou.com/hosting-your-own-mastodon-server/#choose-how-youd-like-to-host">Choose how you&#x27;d like to host</a></li>
<li><a href="https://paulstamatiou.com/hosting-your-own-mastodon-server/#setting-up-mastodon-with-mastohost">Setting up Mastodon with Masto.host</a></li>
<li><a href="https://paulstamatiou.com/hosting-your-own-mastodon-server/#setting-up-mastodon-with-a-regular-webhost">Setting up Mastodon with a regular webhost</a></li>
<li><a href="https://paulstamatiou.com/hosting-your-own-mastodon-server/#logging-into-mastodon">Logging into Mastodon</a></li>
<li><a href="https://paulstamatiou.com/hosting-your-own-mastodon-server/#migrating-your-account">Migrating your account</a></li>
<li><a href="https://paulstamatiou.com/hosting-your-own-mastodon-server/#what-to-expect">What to expect</a></li>
<li><a href="https://paulstamatiou.com/hosting-your-own-mastodon-server/#maintaining-debugging-and-optimizing-your-server">Maintaining, debugging, and optimizing your server</a></li>
<li><a href="https://paulstamatiou.com/hosting-your-own-mastodon-server/#the-end">The end</a></li>
</ul></div>
<h3>So you want to host your own Mastodon server?</h3>
<p>And why you would want to do host your own Mastodon server? If you&#x27;ve read this far, you probably already have a hunch or two as to why, but here are a few excuses to choose from:</p>
<ul>
<li>
<p>You value being in complete control over your Mastodon identity, data, and privacy. You don&#x27;t want to risk it on an instance where you don&#x27;t know the moderators, don&#x27;t want to be under their control, or simply don&#x27;t trust them to maintain the server long-term.</p>
</li>
<li>
<p>You want a speedy Mastodon experience. By controlling your own instance you can set it up with the appropriate resources and hosting location near you to keep Mastodon feeling speedy at all times. That&#x27;s not the case with various instances, especially the larger ones experiencing rapid growth.</p>
</li>
<li>
<p>You want a weekend project, because Mastodon is open source and able to be self-hosted</p>
</li>
<li>
<p>You see lots of people running their own instance and it seems cool.</p>
</li>
<li>
<p>You want a better Mastodon user name, one that speaks more to your identity or interests. Run Mastodon on your long-time domain name or an entirely new one, paired with whatever user name you like.</p>
</li>
</ul>
<p>Whatever your reason for wanting to host your own Mastodon server, I&#x27;m here to help you get started. I&#x27;ll walk you through the process of setting up your own Mastodon server. I&#x27;ll also provide some tips along the way to help you get the most out of your Mastodon experience.</p>
<h3>What you&#x27;ll need</h3>
<p>At a bare minimum, you&#x27;ll need a domain, some money, and some time:</p>
<p><strong>A domain.</strong> Picking the user name and domain name you wish to use for your new Mastodon instance is probably the hardest part.</p>
<p>You&#x27;ll need a domain name you can connect with your new Mastodon server. You should also know the basics of how to modify DNS records on it. This varies by domain name registrar but is generally pretty easy to figure out. If you don&#x27;t have a preferred registrar yet, Google Domains is pretty easy and you don&#x27;t have to make a new account with two-factor auth if you&#x27;re already a Google user.</p>
<p>Otherwise, I also like Amazon AWS Route 53, but it&#x27;s a bit harder to use and they don&#x27;t support nearly as many top-level domains (such as .design, .dev, et cetera) as other registrars.</p>
<p><strong>Some money.</strong> For a single user instance you can get away with $6/mo with the lowest plan on masto.host. but if you have a lot of followers (or just want a beefier server), you&#x27;ll want to upgrade to a bigger plan and that could run you closer to $50/mo.</p>
<p><strong>And a few hours.</strong></p>
<p>If you opt for a more involved hosting setup you&#x27;ll need access to a few more things, such as an SMTP server to send emails, and optionally, access to a cloud service such as Amazon S3 to host media. I&#x27;ll get into that in a bit.</p>
<hr/>
<h3>Choose how you&#x27;d like to host</h3>
<p>The easy way or the hard(er) way?</p>
<p>I&#x27;ll show you two different ways to setup your own Mastodon server. For the most part I&#x27;m assuming you are only setting up Mastodon for yourself, or just a few people. This guide is not really meant for someone wanting to setup a Mastodon server that will accomodate hundreds of users as that will take you down a different path.</p>
<h3>Option 1: Using a dedicated Mastodon host</h3>
<p>The easiest way to get your own Mastodon server up and running quickly is with a host that specializes in Mastodon hosting. There are <a href="https://docs.joinmastodon.org/user/run-your-own/">several</a>, but I&#x27;ll share how to use one of the most popular ones, Masto.host.</p>
<p>So what exactly do I mean by dedicated host? You won&#x27;t have to worry about the typical setup and maintenance required with a regular host, like configurations, software updates, backups, et cetera. This might be route for you if you want the easiest possible way to get started, and having full server control is not as important to you. You won&#x27;t have complete control over the hardware, the software (beyond Mastodon itself), how your media is stored and served, or anything lower level like that.</p>
<p>While you won&#x27;t have the ability to tweak things and keep an eye on performance, but it&#x27;s an easy way to get started for cheap. The most affordable Masto.host plan is only $6 per month for up to 20GB of media storage and 2GB database. For a casual single user without a lot of followers this should be okay. Masto.host lets you upgrade to higher plans if you need later on.</p>
<p>Personally, I did not want to use an option like this. I wanted to be able to serve my media files with a CDN, control the entire server config, as well as just know more about the hardware used in my server (SSD? NVMe SSD? etc). I always want to have significant headroom on my server in case any of my Mastodon posts goes viral. I don&#x27;t want to have a bogged down server limiting the reach of my posts.</p>
<h3>Option 2: DIY with a regular webhost and server</h3>
<p>The other option is getting a VPS or dedicated server, setting up Mastodon and its dependencies. While this route takes considerably more time to setup, it&#x27;s the most flexible by far. You control everything and you can eke out more performance and functionality. And some hosting providers will give you a head start with a Linux image with Mastodon pre-installed—there&#x27;s quite a few things to configure but this makes it a bit easier.</p>
<p>Maybe you decide you want to modify the code to <a href="https://stammy.design/@stammy/109764353001942728">remove a rate limit</a>, or change the character limit of posts? Maybe you want to move to a fork of Mastodon, like Hometown. Want to serve your media from a fast CDN on a subdomain that you have backed up? You can do all of that on your own server.</p>
<p>As expected, it will take longer to setup (a few hours) and it will probably cost more. But if you&#x27;re reading this far, you probably already know your having own server is right for you.</p>
<h2>Setting up Mastodon with Masto.host</h2>
<h3>Option 1, the easy way</h3>
<p>This is by far the easiest way to get started. By the end of this section, you&#x27;ll have your own Mastodon instance running on your own domain. You only need access to your domain name registrar (or DNS provider if use a separate service) so you can change a DNS record.</p>
<p>You don&#x27;t have to worry about getting access to an SMTP server to send notification emails, nor will you have to figure out how to save media files to a cloud provider.</p>
<h3>Sign up and change DNS</h3>
<p>Visit <a href="https://Masto.host">Masto.host</a>, choose a plan, and provide your domain name (though you can run it as a subdomain on masto.host if you wish). You&#x27;ll be greeted with a page telling you to add a DNS <code>A</code> record so your domain name can point to your Masto.host server.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-setup-masto-dns.jpg" alt="Masto.host DNS setup page" />
<p>Every domain name registrar / DNS provider has a slightly different way of modifying DNS records, so I can&#x27;t show too much more detail there. You&#x27;ll likely need to log into where you have your domain name registered and look for some DNS or zone settings.</p>
<h3>Installation</h3>
<p>When you&#x27;ve successfully added that DNS record, Masto.host should automatically detect it and begin installation.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-setup-masto-install.jpg" alt="Masto.host install in progress" />
<p>The installation screen said this process usually took a few minutes. Unfortunately, in my case it actually took a whopping 8 hours. I hope that&#x27;s just temporary due to a temporary spike in new users.</p>
<h3>Create your Mastodon user & upgrade permissions</h3>
<p>Once that&#x27;s done you can go right to your new Mastodon instance and create an account. This will be your Mastodon account, so choose the username you want.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-setup-masto-just-installed.jpg" alt="Masto.host - New mastodon server setup" width="1999" height="1310" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-setup-masto-change-user-role.jpg" alt="Masto.host - changing user role to Owner" width="2000" height="1167" />
<p>After creating your Mastodon account, you&#x27;ll just need to do one more thing. Go back to Masto.host and look for a button called "Change User Role." Here you can upgrade your new account to have "Owner" privileges. Now your account will have access to a new Administration tab in Preferences.</p>
<h3>That’s it!</h3>
<p>That&#x27;s pretty much it! There are some things to fill out, and settings to change in Preferences which I go over later in this article, but your server is now online and ready to explore!</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-setup-masto-dashboard.jpg" alt="Masto.host server detail page" width="2000" height="1317" />
<small>The Masto.host site leaves a lot to be desired. You can only see how much storage your media and database use.</small>
<p>Aside from that, there&#x27;s not much you can control or change with Masto.host. The site lets you do a few things like download daily backups for your own safe-keeping, change your plan, and opt to install ElasticSearch for an additional monthly fee.</p>
<p>ElasticSearch lets your Mastodon instance have full-text search for logged in users to search their own posts, bookmarks, favorites, and mentions on your server. I probably would not recommend it if you have the smallest server plan as it can use a good bit of RAM; it&#x27;s unclear how much RAM your Masto.host server has and how much RAM ElasticSearch is configured to use.</p>
<h3>What you can&#x27;t do</h3>
<p>There are a few things you won&#x27;t be able to do with a setup like Masto.host where you don&#x27;t have control over the exact configuration. One of these is so-called single user mode. This mode makes the homepage your profile instead of a timeline of users. Typically, you would just update your <code>.env.production</code> file enable it. Though this is a pretty easy thing for Masto.host to build into their web dashboard as a future setting.</p>
<p>Similarly, you can&#x27;t do a more advanced username where you could have a username like you@example.com even though Mastodon may actually be hosted on a subdomain like you@social.example.com. This is described in the <a href="https://docs.joinmastodon.org/admin/config/#web_domain">Mastodon documentation as WEB_DOMAIN</a>.</p>
<h2>Setting up Mastodon with a regular webhost</h2>
<h3>Option 2, the not-so-easy way (DigitalOcean VPS)</h3>
<p>This section is for people like me that want more control over their server and the software that runs on it, and don&#x27;t mind a few twists and turns to get there. In this section we&#x27;ll pick out server hardware and options, create an account to send emails with SMTP, setup media storage with a cloud provider, follow a setup wizard in the command line and then configure a few things.</p>
<p>You should be comfortable with Linux and command line basics for this setup process as well as ongoing server maintence.</p>
<h3>Getting an SMTP server</h3>
<p>First, we&#x27;ll need to get access to an SMTP server to let Mastodon send email notifications. While this seems like a step that should be optional, it&#x27;s required by Mastodon to send emails used to verify new accounts. There are many ways to get access to an SMTP server:</p>
<ul>
<li>
<p><strong>Setup and configure an MTA like <code>postfix</code>, <code>exim</code>, or <code>sendmail</code></strong> on your server. This <a href="https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-postfix-as-a-send-only-smtp-server-on-ubuntu-22-04">is not a particularly easy route</a>. You may still have deliverability issues, or your <a href="https://www.digitalocean.com/blog/smtp-restricted-by-default">webhost may restrict SMTP</a>. It&#x27;s also not advisable to run an SMTP server on the same IP as your web server.</p>
</li>
<li>
<p><strong>Use your email provider&#x27;s SMTP server.</strong> If you use <a href="https://support.google.com/a/answer/176600">GMail (details linked)</a>, <a href="https://support.microsoft.com/en-us/office/pop-imap-and-smtp-settings-for-outlook-com-d088b986-291d-42b8-9564-9c414e2aa040">Outlook</a>, <a href="https://www.fastmail.help/hc/en-us/articles/1500000279921-IMAP-POP-and-SMTP">Fastmail</a> or similar email service providers, you can try to just use their SMTP server. This will require you to provide some credentials (either by generating a unique app-specific password, or your email password), and send from the same email address and domain you currently use with your email.</p>
</li>
<li>
<p><strong>Use a dedicated SMTP provider</strong> like Amazon AWS SES (Simple Email Service), Mailjet, Resend, SendGrid, Mailgun, SMTP2Go, SparkPost, ZeptoMail, Postmark, and many more. I personally use AWS SES and would recommend it if you&#x27;re already using AWS services in some capacity. Setting up SES is a <a href="https://docs.aws.amazon.com/ses/latest/dg/send-email-getting-started-migrate.html">bit involved though</a>, and you&#x27;ll be in a sandbox period at first.</p>
</li>
</ul>
<p>While I personally use AWS SES, I was looking for something even easier to setup for this article and after trying a few, had a great experience getting started with Mailjet. By comparison, trying to setup SendGrid was a disaster; way too many steps involved, including having to talk with support.</p>
<p>There&#x27;s a few steps to follow before you can get your SMTP server login credentials but Mailjet makes it pretty straightforward:</p>
<ul>
<li>
<p>Sign up for a free account at <a href="https://www.mailjet.com/">Mailjet</a>.</p>
</li>
<li>
<p><strong>Add your domain</strong> as a new sender domain. Click "Setup my SMTP" (or navigate to Sender domains from Account) to add your domain.</p>
</li>
<li>
<p><strong>Validate your domain</strong> by adding a TXT DNS record. You&#x27;ll need to log into your DNS provider or domain name registrar to edit that.</p>
</li>
<li>
<p><strong>Authenticate the domain</strong> by adding 2 TXT DNS records for SPF and DKIM.</p>
</li>
<li>
<p><strong>Specify the email address you&#x27;ll send from</strong> and marking it as transactional.</p>
</li>
<li>
<p><strong>Get your API key and SMTP server URL</strong>. This can be found under "SMTP and SEND API Settings" on the Account page. When setting up Mastodon, the API key will act as your SMTP username and the API secret will act as your password.</p>
</li>
</ul>
<div><h3>Tip: Use your webhost for DNS too</h3><p>You may want to just use whichever hosting provider you end up choosing as your DNS provider as well, instead of your domain name registrar (if they differ). Most hosts make it a bit easier to set your <code>A</code> record that points to your server if they also manage the DNS.</p><p>In this article I show how to use DigitalOcean as your hosting provider, so you can skip ahead to that part below or create an account and <!-- --><a href="https://docs.digitalocean.com/products/networking/dns/how-to/add-domains/">follow these instructions</a><!-- -->.</p></div>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-mailjet-domains.jpg" alt="" width="2000" height="1516" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-mailjet-domains-dns.jpg" alt="" width="2000" height="1205" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-mailjet-sender-address.jpg" alt="" width="2000" height="1162" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-mailjet-apikey.jpg" alt="" width="2000" height="2200" />
<small>Mailjet is one of the easier ways to get access to </small>
<p>Keep your new SMTP credentials handy, you&#x27;ll need it soon.</p>
<h3>Picking your webhost</h3>
<p>You can get a Linux server up and running from any number of hosting providers (like AWS EC2 or Lightsail, Linode, Hetzner, DigitalOcean, Vultr, etc) if you&#x27;re comfortable with the <a href="https://docs.joinmastodon.org/admin/install/">standard Mastodon installation process</a>. If you go this route you&#x27;ll need to install various system packages, Ruby, Node, Postgres and nginx among others.</p>
<p>However, I&#x27;m going to focus on using a DigitalOcean "Droplet" for this article. Mainly because they have a <a href="https://marketplace.digitalocean.com/apps/mastodon">1-Click Mastodon installer</a>. It saves you a good bit of time but there&#x27;s still more to do after that I&#x27;ll walk you through.</p>
<p>Droplets are DigitalOcean&#x27;s name for their Linux-based virtual machines running on virtualized hardware. They have a good variety of hardware to choose from, including options for faster NVMe SSDs which I really appreciate.</p>
<p>Lets get started! Click "Create Mastodon Droplet" on <a href="https://marketplace.digitalocean.com/apps/mastodon">the 1-click installer page</a> and create an account if you don&#x27;t have one yet.</p>
<h3>Picking your hardware</h3>
<p>After logging in you&#x27;ll be sent to a page to create your new Mastodon droplet and select what hardware to use. How much CPU, RAM and storage space do you need? Storage doesn&#x27;t really matter as we&#x27;ll be hosting uploaded media on a separate cloud service. As for storage speed, DigitalOcean droplets only offers SSDs and faster NVMe SSDs; no slower mechanical hard drives. You can opt for the NVMe SSD if you wish (I did) but it&#x27;s probably overkill for most people just setting up a single-user personal Mastodon instance.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-digitalocean-setup-droplet.jpg" alt="Creating your DigitalOcean droplet server for Mastodon" width="1000" height="1124" />
<small>Creating a DigitalOcean "droplet" server</small>
<p>With CPU and RAM, it&#x27;s definitely a lot of "the more, the better" and whatever you can afford, but here&#x27;s some additional context to think about it with:</p>
<p><strong>RAM:</strong> When it comes to RAM, while you could get by with 1GB, I would say you&#x27;d want at least 2GB, especially if you plan to run ElasticSearch on your instance. I ended up going with 4GB and my machine on average consumes about ~2GB of RAM so I have a good amount of headroom.</p>
<p><strong>CPU:</strong> CPU is critical to several parts of what run Mastodon like Sidekiq, a background job processor, and Puma, the app server on top of nginx. The more CPU resources you have available, the more processes and threads you can spin up without bogging down your system. With the web server for example, if you increase the number of threads you&#x27;ll use more CPU, but if you create more processes, you&#x27;ll use more RAM.</p>
<p>I picked a server with 2 Intel cores and it has been doing fine with my Mastodon activity with about 4,000 Mastodon followers.</p>
<div><h3>Tip: Start small</h3><p>With DigitalOcean droplets you can easily upgrade to a more powerful machine, but you may not be able to downgrade to a less powerful machine. This is usually due to having a disk image that&#x27;s too large for another server.</p><p>I suggest starting with a server that has 2GB of RAM. If you find you need more RAM, CPU, disk space, et cetera, you easily upgrade later. It takes maybe 5-10 minutes to upgrade and DigitalOcean handles everything for you automatically.</p></div>
<p>After selecting your server hardware, you&#x27;ll want to select the option to enable monitoring and backups. Then, click "Advanced" and enable IPv6. And finally, you&#x27;ll need to create or provide an SSH key. I highly recommend following <a href="https://docs.digitalocean.com/products/droplets/how-to/add-ssh-keys/">their SSH instructions</a> so you can use a key that your computer has so you can easily access your server with <a href="https://iterm2.com/">your preferred terminal app</a>. You can still use the web console provided by DigitalOcean but it&#x27;s a bit clunky.</p>
<div><h3>Option: Managed Database</h3><p>I ended up selecting the option to have a managed database for an extra $15 per month. If you don&#x27;t mind the extra cost it&#x27;s nice for it&#x27;s automatic backups that let you revert to any point in time. That being said, for a single user Mastodon instance, you probably won&#x27;t get any performance benefit out of it, just peace of mind. And since it&#x27;s basically another remote server, you can access it with a tool like SQLPro for Postgres (if you&#x27;ve configured its security settings to allow your IP) if you&#x27;re so inclined to poke around in the database.</p><p><strong>Important:</strong> If you select the managed database option while creating your Mastodon 1-Click droplet, it should automatically put the correct database credentials for you, but there is one more place where you need to specify the database access credentials: <code>/etc/environment</code>. If you don&#x27;t do this you may see Mastodon admin CLI commands fail, such as when trying to modify your first Mastodon account to give it owner privileges.</p><p>You will also want to verify that <code>/etc/environment</code> has the correct database name specified. By default it should be <code>mastodon_production</code>.</p><p>And finally, you will need to add the following to <code>/home/mastodon/live/.env.production</code>:</p><pre><code class="language-plaintext">DB_SSLMODE=require
# You may also need to do the following as a hack
# More context: https://github.com/mastodon/mastodon/discussions/19917
NODE_TLS_REJECT_UNAUTHORIZED=0
</code></pre><p>And then restart the services <code>sudo systemctl restart mastodon-*</code>. Without those lines, you may see some errors in the streaming service logs.</p><p>And finally, you&#x27;ll want to go to DigitalOcean, click on your managed database, then visit settings to ensure you restrict connections to just your IP and your Mastodon server under the "Trusted sources" section.</p></div>
<p>Click <strong>Create Droplet</strong> and your server should be ready in about 30 seconds or so.</p>
<h3>Adding your domain & setting up DNS</h3>
<p>Next up, we&#x27;ll need to add your domain name to DigitalOcean and setup necessary DNS records.</p>
<div><h3>Tip: Using a Mastodon on a domain where you already host a website, without exposing the subdomain</h3><p>If you wanted to use a domain where you&#x27;re already hosting a website, you may think that it&#x27;s not possible to host Mastodon on that domain without resorting to a subdomain which would leave you with a lengthy Mastodon username like <code>username@social.example.com</code>.</p><p>Fortunately there&#x27;s a a lesser known Mastodon tip that lets you host Mastodon on a subdomain but allows your username to be shown as being directly on the root domain itself, such as <code>username@example.com</code>. This is done by setting the <code>WEB_DOMAIN</code> environment variable to the root domain. This is not something that the Mastodon setup wizard will ask you about, but it&#x27;s something you can do after the setup wizard is complete by manually editing the <code>.env.production</code> file, typically located in the <code>/home/mastodon/live</code> directory.</p><p>This is described in the <!-- --><a href="https://docs.joinmastodon.org/admin/config/#web_domain">Mastodon documentation as ,[object Object]</a><!-- --> and <code>LOCAL_DOMAIN</code>. To sum up: with this configuration you can have Mastodon hosted on a subdomain but completely hide that from people that follow you. They&#x27;ll only see your username at your root domain.</p></div>
<ul>
<li>Click the menu on your droplet and select <strong>Add a domain</strong>.</li>
<li>Type in the domain you want to use for Mastodon, and select your droplet server from the dropdown.</li>
<li>If you haven&#x27;t done so already, you&#x27;ll want to go to your domain name registrar and designate DigitalOcean as the DNS host by adding the 3 nameservers shown. More info <a href="https://docs.digitalocean.com/tutorials/dns-registrars/">can be found here</a>.</li>
<li>Finally, you just need to add an <code>A</code> record for your droplet. Just type <code>@</code> for the Hostname and click the dropdown to select your droplet to automatically select the IP address needed.</li>
</ul>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-digitalocean-server-setup-add-domain.jpg" alt="Add domain to DigitalOcean" width="2000" height="1312" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-digitalocean-server-setup-add-domain-2.jpg" alt="Adding your domain to digitalocean" width="2000" height="725" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-digitalocean-server-setup-add-domain-record.jpg" alt="Adding DNS A record in DigitalOcean" width="2000" height="610" />
<p>After DNS propagates in a few moments you&#x27;ll be able to directly SSH into your server with just <code>ssh root@yourdomain.com</code>, assuming you setup your SSH key earlier.</p>
<h3>Setting up cloud file storage</h3>
<p>Before we can start setting up Mastodon, there&#x27;s one more thing we need to do: setup and get login credentials for cloud object storage for all user-uploaded files on your Mastodon instance. This part is optional: Mastodon can easily host files directly from your server.</p>
<p>However, hosting user-uploaded files on a cloud service instead of your Mastodon server has some benefits. First, it takes the load off your web server to respond to requests for media, freeing up your server to respond to other requests. This is especially important if you have a less powerful server. It&#x27;s an easy way to make things more performant. Second, cloud object storage providers are made for serving static files quickly and that&#x27;s especially true if you use one with a CDN.</p>
<p>There are a lot of services to choose from such as DigitalOcean Spaces, Wasabi, Minio, Google Cloud Storage, Amazon S3, and any service that offers S3-compatibility like <a href="https://developers.cloudflare.com/r2/examples/mastodon/">Cloudflare R2</a>.</p>
<p>I personally use Amazon S3 with a CloudFront distribution (CDN), used on a CNAME subdomain. It was a bit more involved to setup, including creating separate IAM and bucket permissions, so I wanted to show a simpler solution for this article, using DigitalOcean Spaces. If you&#x27;re familiar with AWS, that&#x27;s a great route to consider though.</p>
<p>The easiest way is to use DigitalOcean&#x27;s own object storage solution, Spaces. It costs $5/month for 250GB of storage with 1TB of outbound transfer. That should be more than enough space for most.</p>
<p>To get started, click the <strong>Create</strong> button at the top of DigialOcean&#x27;s dashboard and select Spaces to create a bucket for storing your Mastodon server&#x27;s files. Here you&#x27;ll need to pick a bucket name and location, which should default to the same region as your droplet server. The bucket name doesn&#x27;t matter much as it&#x27;s not readily visible to your users unless they dig into their browser web inspector. You&#x27;ll also want to check the box to enable CDN.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-digitalocean-create-spaces-bucket.jpg" alt="Creating DigialOcean Spaces bucket" width="2000" height="1611" />
<p>After you create the bucket you&#x27;ll need to specify a subdomain to access your files from and setup an SSL certificate so HTTPS will work. DigitalOcean makes this pretty easy. Go to the <strong>Settings</strong> tab of your new Spaces bucket and click <strong>Change → Edit CDN Settings</strong>.</p>
<p>Select a subdomain name that you&#x27;ll use for hosting user-uploaded media on your Mastodon server, like <code>files.yourdomain.com</code>. While this is optional, it&#x27;s a nice touch. After the certificate is created, the next step is to just select it from the dropdown on the Settings page under CDN as shown below. If you&#x27;re lost at any point during this process, more <a href="https://docs.digitalocean.com/products/spaces/how-to/enable-cdn/">details can be found here</a>.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-digitalocean-create-spaces-bucket-cdn.jpg" alt="Edit CDN Settings" width="2000" height="1000" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-digitalocean-create-spaces-bucket-cdn-subdomain.jpg" alt="Create subdomain for Spaces CDN and setup SSL certificate" width="2000" height="1762" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-digitalocean-create-spaces-bucket-cdn-subdomain-config.jpg" alt="Configure CDN" width="2000" height="1569" />
<p>The final step is getting the API key and secret for your new bucket. On the main Spaces page (click Spaces from the sidebar) there is a link at the top right titled <strong>Manage keys</strong>. Click that and then you can generate a new key and give it a name. Once you&#x27;re done with that copy your key and secret for use later.</p>
<h3>Setting up Mastodon</h3>
<p>By this point your DigitalOcean project should look like this: you have a droplet server, a Spaces bucket, and an attached domain.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-digitalocean-server-setup.jpg" alt="DigitalOcean Droplet and project dashboard" width="2000" height="1348" />
<p>You&#x27;re ready to begin the actual Mastodon setup! Mastodon is already installed thanks to the 1-Click Droplet installer. You just need to access the setup wizard via the command line. You can use the built-in console on the website or SSH into it with your preferred terminal app. The website console can be accessed by selecting <strong>Access console</strong> from the <strong>...</strong> menu on your droplet. I prefer directly SSHing into the server with <code>ssh root@yourdomain.com</code>.</p>
<p>When you&#x27;re connected to your server, you&#x27;ll instantly see the Mastodon setup wizard start to run:</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-digitalocean-mastodon-setup-wizard.jpg" alt="Setting up Mastodon in the command line" width="2000" height="1217" />
<small>The Mastodon setup wizard</small>
<div><h3>Tip: If you make a mistake...</h3><p>If at any point you make a mistake while working in the command line setup wizard and need to undo something, just close the SSH session or web console, and re-open it. The setup process will start over again until it&#x27;s completed.</p></div>
<p>You&#x27;ll be asked to answer a few questions and fill in some details and credentials:</p>
<ul>
<li>
<p><strong>Domain name:</strong> Your domain name for Mastodon.</p>
</li>
<li>
<p><strong>Do you want to store user-uploaded files on the cloud? (y/N):</strong> Type <code>y</code> for yes.</p>
</li>
<li>
<p><strong>Provider:</strong> Select DigitalOcean Spaces.</p>
</li>
<li>
<p><strong>Space name:</strong> The bucket name you chose.</p>
</li>
<li>
<p><strong>Space region:</strong> Type in the region for your spaces bucket. When you go to copy your Spaces endpoint, it&#x27;ll be the subdomain after your bucket name that&#x27;s short (like <code>nyc3</code>) depending on the hosting location.</p>
</li>
<li>
<p><strong>Space endpoint:</strong> Your Spaces "Origin Endpoint" as seen on the DigitalOcean website <em>but with the bucket name subdomain at the front removed</em>. Even though you setup the CDN, for this you need the non-CDN URL or it won&#x27;t work. For me it was the following but this varies based on the location you chose:</p>
<pre><code>https://nyc3.digitaloceanspaces.com
</code></pre>
</li>
<li>
<p><strong>Do you want to access the uploaded files from your own domain?</strong>: This is asking if you want to use a CNAME alias for your hosted files, for example to appear as if they are hosted from your domain. I&#x27;ll assume you followed the directions above for setting up Spaces CDN with a subdomain and certificate, so you can say <code>yes</code>.</p>
</li>
<li>
<p><strong>SMTP server:</strong> Check with your SMTP provider, but in the case of Mailjet it was <code>in-v3.mailjet.com</code> for me. This could be different for you.</p>
</li>
<li>
<p><strong>SMTP port:</strong> Depends on your SMTP provider, but likely <code>587</code>.</p>
</li>
<li>
<p><strong>SMTP username / password:</strong> Provide the username and password for your SMTP provider. If you&#x27;re using Mailjet as described above the API key will act as your SMTP username and the API secret will act as your password.</p>
</li>
<li>
<p><strong>SMTP authentication:</strong> The default <code>plain</code> should be fine. You may also be asked for an OpenSSL verify mode, for that you can usually input <code>peer</code> or <code>none</code>.</p>
</li>
<li>
<p><strong>Email address to send emails "from":</strong> Hit enter to accept the default <code>notifications@yourdomain.com</code> address.</p>
</li>
<li>
<p><strong>It is time to create an admin account that you&#x27;ll be able to use from the browser! Username:</strong> Pick the username that you&#x27;ll want to use for your Mastodon profile.</p>
</li>
</ul>
<p>Your full Mastodon handle will end up being <code>@yourusername@yourdomain.com</code>.</p>
<p>At this point you&#x27;ll be given a password to log into your new Mastodon account. You&#x27;ll want to change it to something stronger after you log in for the first time (more on that later). But before that can be done you&#x27;ll need to follow the instructions to setup your SSL certificate with Let&#x27;s Encrypt so https will work for your domain.</p>
<p>If you find yourself struggling to get the Let&#x27;s Encrypt process to work, check the DNS records on your domain to ensure everything is setup correctly, particularly the <code>A</code> record for the domain and that you&#x27;ve correctly added the DigitalOcean nameservers with your registrar. Also, you can just give it some time for DNS to propagate and try again later.</p>
<p>There&#x27;s just a few more things to do before logging into your new Mastodon server.</p>
<h3>Fixing the cloud storage config</h3>
<p>Unfortunately I was unable to get DigitalOcean Spaces cloud object storage with CDN working flawlessly out of the gate and had to manually edit a few lines in a config file. We&#x27;ll be editing the <code>.env.production</code> file—where a lot of Mastodon settings live— to adjust some of the media storage settings.</p>
<ul>
<li>
<p><strong>If you&#x27;re using the subdomain as shown during Spaces setup:</strong>
You&#x27;ll need to add a line for <code>S3_ALIAS_HOST</code> as shown below. This value is the same as the subdomain you setup earlier along with the SSL certificate. Then you&#x27;ll need to modify the S3_ENDPOINT and S3_HOSTNAME values to be in this format.</p>
<pre><code>S3_PROTOCOL=https
# Replace the following with your bucket name 
S3_BUCKET=stammy-mastodon
# Replace with your bucket region
S3_REGION=nyc3
# Replace with the subdomain you setup earlier for your Spaces bucket / CDN
S3_ALIAS_HOST=files.stammy.social
# Change the region in the URL below to match your bucket region
S3_ENDPOINT=https://nyc3.digitaloceanspaces.com
# This is your "Origin Endpoint" as found on your Spaces bucket page
S3_HOSTNAME=stammy-mastodon.nyc3.digitaloceanspaces.com
</code></pre>
</li>
<li>
<p><strong>If you&#x27;re not using a subdomain alias for hosting your files:</strong> You will need to remove the bucket name from your DigitalOcean Spaces bucket&#x27;s "Origin Endpoint" that is used as your hostname. Ensure your S3_ENDPOINT and S3_HOSTNAME look like this. Remove any line with S3_ALIAS_HOST if it already exists.</p>
<pre><code>S3_ENABLED=true
S3_PROTOCOL=https
S3_BUCKET=stammy-mastodon
# Replace nyc3 region in the next 3 lines with your bucket region
S3_REGION=nyc3
S3_HOSTNAME=nyc3.digitaloceanspaces.com
S3_ENDPOINT=https://nyc3.digitaloceanspaces.com
</code></pre>
</li>
<li>
<p><strong>If you used Amazon S3 with CloudFront instead:</strong> If you went for the more advanced route of using S3 with a CloudFront distribution connected to a CNAME on your domain, you will configure it like this:</p>
<pre><code># Your S3 bucket name. 
S3_BUCKET=my-mastodon-files
# Replace us-east-1 with your bucket region, lowercase.
S3_REGION=us-east-1
# Hostname is likely your bucket name + .s3.amazonaws.com
S3_HOSTNAME=my-mastodon-files.s3.amazonaws.com
# Only use if you&#x27;ve configured a CloudFront CNAME on your domain with SSL cert 
# If you&#x27;re not using a CNAME, remove this line and then change the S3_HOSTNAME to the default (such as s3.us-east-1.amazonaws.com based on your region)
S3_ALIAS_HOST=turbo.stammy.design
# You do not need an S3_ENDPOINT line
</code></pre>
</li>
</ul>
<p>Once you&#x27;ve made the changes to your <code>.env.production</code> file, you&#x27;ll need to restart the Mastodon services to apply the changes:</p>
<pre><code>sudo systemctl restart mastodon-*.service
</code></pre>
<h3>Upgrading your Mastodon account privileges</h3>
<p>By default your new Mastodon account does not have all privileges available. Mastodon allows an account to have roles like Moderator, Admin, and Owner. You&#x27;ll want to modify your account to have the Owner role. This can be done using the admin CLI tool called <a href="https://docs.joinmastodon.org/admin/tootctl/">tootctl</a>.</p>
<p>Connect to your server via SSH again (or DigitalOcean&#x27;s web console) and run the following commands:</p>
<pre><code># Change from the root user to the mastodon user 
sudo su - mastodon 
# Change to the Mastodon bin directory 
cd /home/mastodon/live/bin
# Modify your account to have the Owner role
RAILS_ENV=production ./tootctl accounts modify admin --role Owner
</code></pre>
<p>This may take a few seconds then you should see "OK". If you have any issues, or are using a different webhost, just confirm that you&#x27;re in the right directory. If you have an error running this and happen to be using the DigitalOcean managed database, you may need to configure the database in another file. Read the <a href="#managed-db">managed database</a> section for details.</p>
<h3>Enabling single user mode</h3>
<p>If this Mastodon account is for you and you only, you can enable single user mode to have the Mastodon homepage be a profile view of your account. By default, this is not enabled and the Mastodon homepage is a timeline view.</p>
<p>To enable this, you&#x27;ll need to edit <code>.env.production</code> and then restart the web server.</p>
<pre><code># Change from the root user to the mastodon user 
sudo su - mastodon 
# Change to the Mastodon web directory 
cd /home/mastodon/live
# Edit the .env.production file in Vim
vim .env.production
</code></pre>
<p>Now you&#x27;ll need to create a new line anywhere in the file by moving the cursor with the arrow keys, tapping i to enter Insert mode, creating a new line, then typing in the following line:</p>
<pre><code>SINGLE_USER_MODE=true
</code></pre>
<p>Tap ESC to exit insert mode, and then type :wq and hit enter to save and exit vim. And finally, exit mastodon user mode to go back to root by typing <code>exit</code>, and then restart the web server:</p>
<pre><code># Restart the web server, this can take a few seconds
systemctl restart mastodon-web.service
</code></pre>
<h3>Ensuring your SSL cert will auto-renew without issue</h3>
<p>Mastodon uses the popular certbot tool from the EFF to obtain certs from Let&#x27;s Encrypt and enable HTTPS on your server. That part all worked great during the initial setup. Certificates from Let&#x27;s Encrypt last for 90 days before they need to be renewed. Certbot makes them easy to auto-renew: it should have installed a cron with it either in a systemd <code>certbot.timer</code> (see it with <code>systemctl show certbot.timer</code> if you&#x27;re curious) or in <code>/etc/cron.d/certbot</code>.</p>
<p>You&#x27;ll need to ensure that your cert will auto-renew without issue. Shouldn&#x27;t this work out of the box? It should, yes. However, I began poking around in my setup and noticed a configuration issue by default (not sure if this is a DigitalOcean Mastodon installer issue or a Mastodon issue) that would lead to renewal failing.</p>
<p>The default method used is called standalone mode and it only works when the web server is not running, which won&#x27;t happen during auto-renewal unless you setup your own cron that also stops and starts the server for renewal. This is fine for the initial setup, but if you want to auto-renew your cert, you&#x27;ll need to use a different method. For more context on this issue, see this commit has <a href="https://github.com/mastodon/documentation/pull/1036/commits/9bc371f3547a884aa094a1151e813f678bd0623e">updated installation instructions</a> that were never merged to Mastodon main, and <a href="https://github.com/mastodon/documentation/issues/940">this issue</a>.</p>
<p>First, see if you&#x27;ll even have an issue by doing a dry run invocation of the certbot renew command:</p>
<pre><code>sudo certbot renew --dry-run
</code></pre>
<p>If the dry run says the renewal would be successful, you don&#x27;t need to do anything else and your setup is all good. If it says renewal will fail, you likely need to do the following:</p>
<pre><code># Edit this config file, swapping out example.com for your domain 
vim /etc/letsencrypt/renewal/example.com.conf
</code></pre>
<p>Then find the line that says <code>authenticator = standalone</code> and replace it with these two lines below and save the file.</p>
<pre><code>authenticator = nginx
installer = nginx
</code></pre>
<p>Now you can do a dry run again and it should say the renewal would be successful as shown below:</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-certbot-renew-dryrun.png" alt="Terminal showing a dry run of certbot renew for SSL cert" width="2000" height="1039" />
<h3>Final setup: updating packages, enabling the firewall, etc..</h3>
<p>At this point you could skip ahead and check that Mastodon works and log into your account for the first time, but you&#x27;ll need to come back to complete a few more things. For the most part you just need to <a href="https://docs.joinmastodon.org/admin/prerequisites/#do-not-allow-password-based-ssh-login-keys-only">follow this Mastodon guide</a> where you&#x27;ll update system packages, configure fail2ban to block repeated login attempts and setup a firewall.</p>
<p>The DigitalOcean website has its own interface for configuring a firewall but after repeated attempts I was unable to get it working, so I stuck with the route recommended by Mastodon: iptables.</p>
<h3>Optional: Configure IPv6</h3>
<p>During DigitalOcean droplet setup you checked a box to enable IPv6 connectivity for your server. Even though that is enabled, you will need to edit some files and add a DNS record. Follow <a href="https://docs.digitalocean.com/products/networking/ipv6/how-to/enable/#on-existing-droplets">this DigitalOcean guide.</a></p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-digitalocean-ipv6-aaaa.png" alt="DigitalOcean adding AAAA record for IPv6" width="2000" height="504" />
<p>Then you&#x27;ll need to add an <code>AAAA</code> DNS record to your domain. An <code>AAAA</code> record is like an <code>A</code> record that points to your server, but for IPv6. DigitalOcean should automatically show you your server&#x27;s IPv6 address in a dropdown when creating that record.</p>
<h3>Optional: Setting up automatic database backups</h3>
<p>If you opted not to go for the DigitalOcean managed database upgrade, you&#x27;ll want to a way to export and save backups of your database on a recurring basis. The easiest way to do this is to setup a cronjob that runs a script to dump your database, zip it up, and save it to a cloud storage bucket with the Amazon AWS command line interface. Since we already setup Spaces for cloud object storage, we can re-use that to save your database backups, though if you want to spend the extra time to use a separate cloud provider or bucket for saving only backups, that is preferrable.</p>
<p>First, you&#x27;ll need to install the AWS CLI. You could follow <a href="https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2-linux.html#cliv2-linux-install">this guide</a> to install the AWS CLI, but likely you can just install it with: <code>apt</code>:</p>
<pre><code># Run as root 
apt install awscli
# Provide your credentials for your Spaces bucket, api key and secret when prompted 
aws configure 
# Switch to the Mastodon user
sudo su - mastodon 
# Test to see that it works by listing what&#x27;s in your Spaces bucket 
# Note: you need to replace the region with your region if different 
# Any time you interact with the AWS CLI, you need to use the --endpoint-url option to 
# specify that we are using DigitalOcean Spaces, not Amazon S3
aws --endpoint-url https://nyc3.digitaloceanspaces.com s3 ls

cd /home/mastodon

# Now we&#x27;ll create the script to backup the database
vim backup_database.sh
</code></pre>
<p>Tap i to enter Insert mode in vim, and paste the following, replacing the Spaces region in the endpoint URL with your Spaces region code:</p>
<pre><code class="language-bash">#!/bin/bash

# Create a filename with the date and time
FILENAME=mastodon_production_$(date +%Y%m%d%H%M).gz

# Dump the database, gzip it, and save locally 
pg_dump mastodon_production | gzip > ${FILENAME}

# Upload the file to your Spaces bucket
# Important: Replace the region with your region if different
# Important: Replace the bucket name &#x27;stammy-mastodon&#x27; with your bucket name
aws --endpoint-url https://nyc3.digitaloceanspaces.com s3 cp ${FILENAME} s3://stammy-mastodon/backups/

# Delete the local file
rm ${FILENAME}
</code></pre>
<p>Save the script (Tap ESC to exit insert mode, type :wq, hit Enter), then made it executable:</p>
<pre><code>chmod +x backup_database.sh
</code></pre>
<p>Now we&#x27;ll create a cronjob to run the script every day:</p>
<pre><code># Enter cron job editor. If you&#x27;re asked what editor to use, select vim again.
crontab -e
</code></pre>
<p>Create a new line after the comment block at the time, and enter the following to create a database backup every week. If you want more frequent backups, you can customize it to your liking, such as with <code>0 0 */3 * *</code> for every 3 days. Take a look at <a href="https://crontab.guru/">crontab.guru</a> to help you figure out what values to input.</p>
<pre><code># Backup every week
@weekly ./backup_database.sh
</code></pre>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-autobackup-database.png" alt="Configuring a cronjob to backup the database" width="2000" height="1309" />
<p>Save the file and you should be good. You may want to try manually running the script now (<code>./backup_database.sh</code>) to ensure it works, and check your Spaces bucket to see a new file was added to the backups directory.</p>
<h3>Optional: Install ElasticSearch</h3>
<p>If you want the ability for you and your Mastodon instance users to be able to search their own posts, bookmarks, favorites, and mentions, you&#x27;ll need to install ElasticSearch. This is optional because it&#x27;s really not that useful. You cannot search across instances, and it does not even support showing posts from other people on other servers that your server has seen but that do not mention you, even if you follow them.</p>
<p>It also takes a bit of RAM, so I especially would not recommend install ElasticSearch if you only have 2GB of RAM or less server. It can be done, but I don&#x27;t think it&#x27;s worth it.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-elastic-search-off.jpg" alt="What mastodon search looks like without elastic search installed" width="2000" height="1263" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-elastic-search-on.jpg" alt="Mastodon with elastic search installed, showing search results" width="2000" height="1901" />
<small><strong>Left:</strong> Mastodon search without ES installed. <strong>Right:</strong> With ES installed, showing local results for people, hashtags and posts, including your own.</small>
<p>To install ElasticSearch, you can <a href="https://docs.joinmastodon.org/admin/optional/elasticsearch/">follow these instructions from the Mastodon site</a>. However, when you get to the part of the guide that tries to enable the service, you may see this error:</p>
<pre><code>Job for elasticsearch.service failed because a fatal signal was delivered to the control processed
</code></pre>
<p>This is likely to happen if your machine doesn&#x27;t have enough RAM. By default ElasticSearch tries to take a lot of RAM, so you&#x27;ll want to configure it to use less. For example, if you only wanted it to use 512MB of RAM, you can create a new file <code>memory.options</code>:</p>
<pre><code># Create an elastic search config file to limit memory usage
vim /etc/elasticsearch/jvm.options.d/memory.options
</code></pre>
<p>Then enter these two lines to specify a min and max amount of RAM that ElasticSearch can use. For example, a min of 256MB and max of 512MB:</p>
<pre><code>-Xms256m
-Xmx512m
</code></pre>
<p>Save the file and try to start the service again:</p>
<pre><code>systemctl daemon-reload
systemctl enable --now elasticsearch
</code></pre>
<p>Run the rest of the steps mentioned in the guide and you should have functional search on your instance. You may run into one more issue resulting in a security warning. This <a href="https://github.com/mastodon/mastodon/issues/18625">github thread</a> is helpful for resolving that (though I think it was also fixed recently in Mastodon 4.1.0).If you want to go down the rabbithole you can modify <a href="https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-minimal-setup.html">more security settings</a> but it&#x27;s likely not a huge deal as we&#x27;ll be setting up a firewall that won&#x27;t allow port access to ElasticSearch.</p>
<h2>Logging into Mastodon</h2>
<h3>Changing settings, configuring scripts & testing</h3>
<p>If you used a fully-managed host like Masto.host (mentioned earlier), you&#x27;ve already created an account and logged in. If you&#x27;ve followed the guide for creating your own server for Mastodon, then you were given a temporary password to login with. Now it&#x27;s time to visit your website and sign into Mastodon. You&#x27;ll also want to immediately enable two-factor auth.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-web-signin.jpg" alt="Mastodon server logged out view after installing Mastodon" width="2000" height="1328" />
<small>Your new homepage (single user mode enabled) will look empty like this</small>
<p>After signing in, click <strong>Preferences</strong> in the sidebar. The first thing we want to do is confirm that upgrading your account to the owner role actually worked. You should see a tab for <strong>Administration</strong> along with others like Sidekiq and PgHero. It should look like this:</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-web-admin-tab.jpg" alt="Mastodon Admin Settings" width="2000" height="1813" />
<p>Feel free to browse the Profile tab to fill out your bio and related settings. Importantly, I think "Require follow requests" may be on by default which you probably want to disable.</p>
<p>Next, here&#x27;s a few things to setup:</p>
<h3>Fill out server details</h3>
<p><strong>Administration → Server Settings → Branding:</strong> Fill out the name and description for your server. This is displayed alongside your profile, homepage, and posts so it&#x27;s quite visible. You can also specify an image to display there.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-web-server-branding.jpg" alt="Mastodon admin settings for server branding" width="2000" height="1873" />
<h3>Disable new account creation</h3>
<p><strong>Administration → Server Settings → Registrations:</strong> If this server is just for you, you&#x27;ll want to disable account creation by changing the <strong>Who can sign-up</strong> setting to nobody.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-web-disable-signups.jpg" alt="Mastodon admin settings to disable new user registrations" width="2000" height="1027" />
<h3>Disable unauthenticated access to public timelines</h3>
<p><strong>Administration → Server Settings → Discovery:</strong> This is just a preference but since this is my own server, I only want my posts easily accessible. I wanted to disable the <code>/public</code> (the "Federated" tab) timeline which displayed posts from other people. I&#x27;m also a little concerned about liability related to my server hosting content from other people (as mentioned in <a href="https://paulstamatiou.com/mastodon/#self-hosting-your-own-mastodon-instance">my last Mastodon post</a>) so making those posts harder to find seems best.</p>
<p>As such, I unchecked <strong>Allow unauthenticated access to public timelines</strong>.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-web-discovery.jpg" alt="Mastodon admin settings for discovery" width="2000" height="2210" />
<h3>Adjust media and content retention</h3>
<p><strong>Administration → Server Settings → Content retention:</strong> This page has some important settings that control how much media and content is kept on your server. If you follow or interact with lots of people on Mastodon (or have any relays setup), you will see the size and costs associated with your cloud object storage provider rise.</p>
<p>You change safely set the <strong>media cache retention period</strong> to something like 7-30 days. I went with 7 and haven&#x27;t noticed any odd behavior. This will delete downloaded media files (from other servers, stored on your server or cloud storage) after the specified period. If your server requests the media again, it will be re-downloaded so there&#x27;s no real harm in setting it too low, you can always change it.</p>
<p>The other setting <strong>content cache retention period</strong> is a bit less safe to tinker with and will delete posts from other users on your server. I decided not to touch this and will see if I need to change it if my database grows too large over time.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-web-content-retention.jpg" alt="Mastodon admin settings for content and media retention" width="2000" height="1135" />
<h3>Setting up a cron job for periodic cleanup tasks</h3>
<p>The media retention setting in the admin interface is just one setting. You have far more control at your disposal with the <code>tootctl</code> admin command in the command line. In fact, running these commands regularly is a recommend part of setup, mentioned under <a href="https://docs.joinmastodon.org/admin/setup/#cleanup">periodic cleanup tasks</a>.</p>
<p>For this, I have several of the commands running as a cronjob. I put them in a bash script for a cronjob to run. I could have put them directly in the crontab editor as a weekly task but it&#x27;s easier to keep it in one file where I know it will run serially, without having to specify different run times for each job so they don&#x27;t run at the same time, potentially bogging down your server.</p>
<p>Here&#x27;s a list of the commands I run regularly. I put them in a bash script named <code>cleanup.sh</code> that I store in my home directory <code>/home/mastodon</code>:</p>
<pre><code># This does the heavy lifting and removes locally cached copies of media attachments from other servers
# By default its set to delete media older than 7 days. 
# Adjust days with --days, eg --days 3 for a more aggressive setting
RAILS_ENV=production /home/mastodon/live/bin/tootctl media remove

# Remove local thumbnails for preview cards (the thumbnail when links are shared, etc)
# The default is 180 days and under 14 days is not recommended as they will not be refetched
RAILS_ENV=production /home/mastodon/live/bin/tootctl preview_cards remove --days 60

# Deletes remote accounts that never interacted with local accounts 
# Removes many avatar and header images as part of this
RAILS_ENV=production /home/mastodon/live/bin/tootctl accounts prune

# Removes files that do not belong to existing media attachments 
# For example if you attached a file to a post composer but never posted it
# This command and the one after it are slow to run, so I like to keep them for last
RAILS_ENV=production /home/mastodon/live/bin/tootctl media remove-orphans

# Remove unreferenced statuses from the database, such as statuses that 
# came from relays or from users who are no longer followed by any local accounts, 
# and have not been replied to or otherwise interacted with
RAILS_ENV=production /home/mastodon/live/bin/tootctl statuses remove
</code></pre>
<pre><code># Switch to the mastodon user and home directory 
sudo su - mastodon
# Create bash script 
vim cleanup.sh
# Make the script executable
chmod +x cleanup.sh
# Add the bash script to crontab
crontab -e
</code></pre>
<p>In crontab, add this line and then save:</p>
<pre><code>@weekly ./cleanup.sh
</code></pre>
<p>I set it to run weekly but you may prefer to run it more often. I&#x27;ve been running my own Mastodon server for a month now and with this setup my cloud media storage is only at <code>8.5GB</code> with my usage.</p>
<h3>Use custom CSS to hide or modify things</h3>
<p><strong>Administration → Server Settings → Appearance:</strong> This part is completely optional but I found myself wanting to hide certain parts of the site navigation that aren&#x27;t useful to others as my Mastodon server is only for me. I hid the sign in buttons for logged out users. I hid the "Local" tab for me when logged in: useless for me as I&#x27;m the only account on the server. I also hid the "Learn more" button that shows up next to the server details (felt pretty obvious that the server was just for me and I wanted to simplify things a bit).</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-web-appearance.jpg" alt="Mastodon admin server settings for appearance." width="2000" height="1593" />
<pre><code>// hide sign in buttons (you&#x27;ll have to manually visit /auth/sign_in)
.navigation-panel .navigation-panel__sign-in-banner, 
.ui__header__links a[href="/auth/sign_in"],
.ui__header__links button { display: none !important; }

// Hide the "Local" tab for logged in users (only do this if you&#x27;re the only user on the server)
.navigation-panel a[href="/public/local"] { display: none !important; }

// hide server details "Learn more" button
.server-banner .button { display: none !important; }
</code></pre>
<h3>Bonus: Clean up the admin UI with an Arc Boost</h3>
<p>If you&#x27;re running this Mastodon account for you, and you only, you may find the default admin dashboard has a lot of space taken up by useless information, such as showing you the number of new accounts created. I prefer to keep some of that hidden to clean up this page.</p>
<p>Unfortunately, just adding CSS to hide it as in the previous step does not seem to work for admin pages. So I turned to a feature from my browser, Arc, called Boosts. It&#x27;s an easy way to locally inject CSS (or JS as needed) into any website. Other browsers have similar ways of doing things with extensions. I created an Arc Boost to simply hide a few dashboard modules:</p>
<pre><code># Not pretty, but it does the job
.dashboard .dashboard__item { display: none; }

.dashboard .dashboard__item:nth-child(3), 
.dashboard .dashboard__item:nth-child(9) { display: block; grid-column: span 3; }

.dashboard .dashboard__item:nth-child(12),
.dashboard .dashboard__item:nth-child(13) { display: block; }
</code></pre>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-admin-ui-cleanup2.jpg" alt="Mastodon admin UI with a few modules hidden with CSS." width="2000" height="1667" />
<small>Admin UI, with a bit less clutter for single-user instances.</small>
<h3>Try posting an image</h3>
<p>And one last thing you&#x27;ll want to do is try posting with an image attached. This will confirm your cloud object storage configuration works correctly and that your system can resize images. What you&#x27;ll want to look out for is that dragging an image into the post composer shows a thumbnail preview, and osting it shows the image without requiring you to refresh the page.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-web-test-media-upload.jpg" alt="Mastodon admin settings" width="2000" height="1462" />
<h2>Migrating your account</h2>
<h3>If you have an existing Mastodon account on another server</h3>
<p>Now you&#x27;re ready for the fun part: moving your existing Mastodon account over to your new server, along with your followers. Mastodon does a great job with this and while it&#x27;s not perfect for reasons I&#x27;ll mention below, your followers will automatically move with you. You can read a bit about the process from the <a href="https://docs.joinmastodon.org/user/moving/#move">Mastodon documentation</a>, but it unfortunately does not go into much detail.</p>
<p>Here are the key things to know about migrating your account:</p>
<ul>
<li>
<p><strong>Your posts don&#x27;t move with you.</strong> Posts on your existing Mastodon account do not move with you to the new server. This is unfortunate, but likely a product of how the federation is done (every server that interacted with your posts would have to update). If you only care about the content of your posts and not the engagement around them, you could repost them one by one to your new server (before you do the migration), and edit the date in the database to the original date. But that&#x27;s weekend project territory to write a script to do that for you... I digress.</p>
</li>
<li>
<p><strong>Your followers move with you.</strong> Your followers will get transferred pretty immediately. When I migrated my account, all of my ~3,000 followers were moved within a day with maybe 75% in the first few hours. It&#x27;s not entirely flawless though, I did lose about 20 followers in the process.</p>
</li>
<li>
<p><strong>You have to manually re-follow accounts you follow.</strong> You have to export a CSV file of accounts you follow from the old server and upload that on the new server. It&#x27;s really easy, but it does mean that people you follow will receive a notification that you followed them. It&#x27;s not ideal but people will start poking around and realize you just moved servers. I&#x27;ve noticed it dozens of times with people I follow and quickly pieced it together.</p>
</li>
<li>
<p><strong>Your old profile shows a banner that you&#x27;ve moved to another server.</strong> And your old account will be in a locked down state. You can login but you can&#x27;t post or edit anything aside from exporting data from the preferences page.</p>
</li>
<li>
<p><strong>You can&#x27;t migrate your account again for 30 days.</strong> So make sure you&#x27;re using a username and domain you like.</p>
</li>
</ul>
<p>Lets get started! The actual first step is creating an account on your new server, which you&#x27;ve already done.</p>
<h3>Step 1: Create an account alias on the new server</h3>
<p>Setting up a Mastodon account migration is a two-way process. The new server needs to be aware of the old account, and the old server needs to send everything to the new server that&#x27;s expecting it.</p>
<p>So the first step is to log into your new server, open <strong>Preferences → Profile</strong> and click on the link under "Moving from a different account." On this page you need to provide your old Mastodon account in the format <code>myusername@example.com</code>.</p>
<p>This step is harmless and reversible—the actual migration does not start until the later steps.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-migration-step1-make-old-acct-alias.jpg" alt="Mastodon account migration: adding an account alias of the old account on the new server" width="2000" height="1207" />
<small>On the new server, add an alias for your old account.</small>
<h3>Step 2: Export your account data from the old server</h3>
<p>Next, you&#x27;ll want to export data from the old server. Most importantly, you&#x27;ll want to export a CSV of accounts you follow so you can later import this on the new server. You can also export files for your muted accounts, blocked accounts, bookmarks, lists, and blocked domains. Go to your old server to download these files: <strong>Preferences → Import and Export → Data export</strong>.</p>
<p>On this page you can also request an export of your posts and uploaded media from the old server. This is just for you to have as you can&#x27;t import posts on the new server. Also, it may not work you depending on your old server. I&#x27;ve tried to request my archive on my old server numerous times and it never generated a download for me.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-migration-step2-download-exports.jpg" alt="Mastodon account migration: export data from the old server" width="2000" height="1235" />
<small>Export data from the old server, especially the list of accounts you follow.</small>
<h3>Step 3: Begin the migration on the old server</h3>
<p>Now it&#x27;s time for the actual migration. This will move followers from your old account to your new account. This cannot be undone, so be sure you&#x27;re ready and have setup your server to your liking before proceeding. This is also a good time to edit anything on your old account (edit bio, delete any posts, etc) as you won&#x27;t be able to change it later.</p>
<p>On the old server, go to <strong>Preferences → Profile → Move to a different account</strong> and click the link mentioned. This will take you to the account migration page. Carefully read the bulleted list to understand the implications of this move. Then, enter your new account&#x27;s handle and the password used for your old server.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-migration-step3.jpg" alt="Mastodon account migration: Starting the migration on the old server by providing the new account handle" width="2000" height="1462" />
<small>Starting the migration on the old server by providing the new account handle.</small>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-migration-step3-profile-redirect.jpg" alt="Mastodon account migration:" width="2000" height="1210" />
<small>Your old account will now display header saying your account has moved.</small>
<p>Now the migration will start. As mentioned earlier, your posts will not move to the new server, only your followers.</p>
<p>If you have a lot of followers or a particularly low-end server, it may be a good idea to keep an eye on your server as this migration process will keep it busy for a while. You can take a look at system resources with the <code>top</code> or <code>htop</code> commands.</p>
<p>And you can see what Mastodon is doing by looking at the Sidekiq dashboard, accessible in <strong>Preferences → Sidekiq.</strong> You can click around to see what jobs are running or failing. For the most part you don&#x27;t need to worry too much. Common job failures are often related to other instances having timeouts. The only cause for concern would be an error indicating connectivity issues with your database, which could mean you may want to adjust the Sidekiq concurrency (mentioned a bit later) in <code>/etc/systemd/system/mastodon-sidekiq.service</code>.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-migration-step3-server-active.jpg" alt="Mastodon account migration:" width="2000" height="1394" />
<small>Moving your followers will keep your machine busy. You may wish to keep an eye with <code>htop</code>.</small>
<h3>Step 4: Import your following list</h3>
<p>The last step of the migration process is to import the CSV files you exported in step 2, the most important of which is the list of accounts you follow. On your new server go to <strong>Preferences → Import and export → Import</strong>. Select what type of CSV file you&#x27;re importing in the dropdown, select the CSV file and upload.</p>
<p>You can safely import all lists except the following list before you&#x27;ve actually started your migration (step 3) if you wish.</p>
<p>I recommend waiting a while after step 3 has had time to move most of your followers over before importing your following list. Your server may be quite busy with step 3 so it doesn&#x27;t hurt to do this an hour later.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-migration-step4-new-server-import.jpg" alt="Mastodon account migration: Importing following list and other CSV files" width="2000" height="1243" />
<small>Importing your list of accounts you follow</small>
<p>That&#x27;s it! All of your followers should get moved over shortly and you&#x27;re ready to start using your own Mastodon server. It&#x27;s probably a good idea to have a post or two so your followers don&#x27;t see an empty profile if they happen to venture to your profile.</p>
<p>If you want to have a bit of fun, you can start looking into adding custom emojis (sometimes called <a href="https://emojos.in">emojos</a> in the context of Mastodon) to your server. Take a look at <strong>Preferences → Administration → Custom emojis.</strong> where you can upload an image and assign it a shortcode. You can even use them in your username.</p>
<hr/>
<h3>What to expect</h3>
<h3>Missing some posts and replies? Yeah, that&#x27;s normal...</h3>
<p>After you&#x27;ve had some time to use your new server, you may see some odd behavior that may lead you to something is broken with your server. Profile pages for accounts may be almost entirely empty, or only have a few posts. Post detail views may not have all the engagement or replies you might expect compared to visiting the original post URL on the remote server.</p>
<p>I&#x27;m just here to tell you this is normal. It&#x27;s not a good thing, but it&#x27;s the current state of how Mastodon works.</p>
<p><strong>Missing posts on a profile:</strong> When you follow someone on your server, or visit the profile of someone you don&#x27;t follow, Mastodon does not go and fetch all of their posts. That would be taxing on their server and yours. So what happens instead is you get some basic profile info, a post or two (pinned ones) and that&#x27;s it. Then, the next time your server sees a post from this user (because you follow them or other some action lead to your server seeing this post), it will then appear on their profile. This is not ideal and it wouldn&#x27;t be unreasonable for Mastodon to fetch a few more posts with a way to request them on demand.</p>
<p><strong>This will get a bit better over time.</strong> Your server is brand new, you only just followed accounts and your server has yet to see a lot of new posts and fill up profiles with new posts going forward. You&#x27;ll still stumble across a user account that your server has never seen before an experience the same blank profile behavior but at least now you know why that is.</p>
<p><strong>Missing replies on posts</strong> from other accounts (not your own posts) is a similar situation; your server may have low federation and not be aware of some of those replies. Understanding why this is the case ends up going down a rabbithole of understanding federation more and how your server even comes to know about posts, and under what conditions another server sends a post to your server.</p>
<p>This <a href="https://github.com/mastodon/mastodon/issues/14017">Mastodon GitHub issue</a> outlines the situations where your server comes to know about posts:</p>
<ul>
<li>Someone on your instance follows the person who posted, at the time it was posted</li>
<li>Someone you (or anyone else on your instance) follow boosts or replies to that toot</li>
<li>Under some conditions, if that post was a reply to someone you (or anyone else on your instance) follow</li>
<li>The post mentions anyone on your instance</li>
<li>The post was a pinned post when the account was discovered by your instance</li>
<li>Someone on your instance manually fetches a post by pasting the URL in the search bar</li>
</ul>
<p>This is a hot topic these days and I&#x27;ve seen discussions happening around people wanting to add buttons in Mastodon clients to explicitly load all replies on a post, or <a href="https://github.com/mastodon/mastodon/issues/17213">older posts on a profile</a>, from the remote servers. There&#x27;s various technical issues with some of these routes, but I&#x27;m curious to see if this situation evolves as I for one would love a refined experience here.</p>
<h2>Maintaining, debugging, and optimizing your server</h2>
<h3>A few things to be aware of</h3>
<p>This section is for people running their own server, <em>not</em> through a fully-managed host like Masto.host.</p>
<h3>Updating Mastodon</h3>
<p>You&#x27;ll need to keep up to date with Mastodon updates to get new features, performance and security updates. You can check for new updates on the GitHub project page but it&#x27;s probably easiest to subscribe to the atom feed in your news reader of choice, such as NetNewsWire.app. Here&#x27;s the <a href="https://github.com/mastodon/mastodon/releases.atom">releases feed</a>, or <a href="https://github.com/mastodon/mastodon/releases">the website</a> if you prefer.</p>
<p>The steps you need to follow for each update may vary, but additional steps will be mentioned in the release notes for each release. Generally you&#x27;ll need to SSH into your server, fetch the latest release with git, and restart some services. Find the complete steps here: <a href="https://docs.joinmastodon.org/admin/upgrading/">Upgrading to a new release</a>.</p>
<p>You should check now that your server is on the latest Mastodon version. At the time of this writing, the DigitalOcean 1-click installer is running an outdated version.</p>
<h3>Updating your Ubuntu server</h3>
<p>Along with maintaining and keeping Mastodon up to date, you&#x27;ll want to do the same with your server. If you followed along with the DigitalOcean route explained above, your machine uses Ubuntu OS, apt package manager and has a specific package called <code>unattended-upgrades</code> installed by default. That package will automatically install essential security updates, but <a href="https://www.digitalocean.com/community/tutorials/how-to-keep-ubuntu-20-04-servers-updated">you can modify it to update even more</a>.</p>
<p>I don&#x27;t want to get too in the weeds about linux server maintenance as everyone seems to have their own specific practice about when to update things, how to update them, and when to leave it alone.. you know, if it ain&#x27;t broke don&#x27;t fix it. Some people may prefer to update all packages every week. Not including security essentials, that&#x27;s a bit too much for me and feels like I&#x27;d constantly be signing up for a potential debugging session if anything unexpected happens.</p>
<p>Personally, I just update available packages whenever I get around to it, perhaps every month or two. Usually with these:</p>
<pre><code># Refresh list of available updates 
sudo apt update
# View list of available upgradable updates
apt list --upgradable
# Upgrade packages 
sudo apt upgrade
# Remove unneeded packages not installed by you 
sudo apt autoremove

# Alternatively, instead of the lines above:
sudo apt update && sudo apt upgrade –y && sudo apt autoremove -y
</code></pre>
<h3>When things go wrong</h3>
<p>I wanted to provide a few pointers for things to look into when things go wrong with your Mastodon server. There&#x27;s no way I can provide a general solution to what could be a specific problem you may encounter, but here&#x27;s a few things may be a good place to start:</p>
<ul>
<li>
<p><strong>Check service status:</strong> Run this to get a quick look at the core Mastodon services: <code>mastodon-web.service</code>, <code>mastodon-sidekiq.service</code>, and <code>mastodon-streaming.service</code>.</p>
<pre><code>sudo systemctl status mastodon-*
</code></pre>
<p>In addition to status of the 3 core Mastodon services (you&#x27;ll want to see "active (running)" in green), this command will show the last 10 lines from the logs for each service.</p>
</li>
<li>
<p><strong>Check the logs</strong>: This may sound obvious but knowing how to check and work with logs is critical. It&#x27;s the best way to know what&#x27;s going on with your machine. To access any of the logs for the aforementioned 3 services, we use a tool called <code>journalctl</code> to read and filter system logs that are saved in the binary "journal" by systemd. You can always run <code>man journalctl</code> to see more details on how you can use it; it&#x27;s very powerful.</p>
<p>It&#x27;s a good idea to go through the logs for each Mastodon service after you&#x27;ve set everything up to make sure that things are working smoothly. Here&#x27;s a few examples of how you can use it:</p>
<pre><code># Show the last 50 lines of the mastodon-web log
# and keep showing new lines as they come in (that&#x27;s the -f follow flag)
sudo journalctl -u mastodon-web -n 50 -f

# Or read the mastodon-streaming log 
sudo journalctl -u mastodon-streaming -n 50 -f

# Or the mastodon-sidekiq log 
sudo journalctl -u mastodon-sidekiq -n 50 -f

# Or only show me sidekiq logs that have priority level 4 (warn) or higher
sudo journalctl -u mastodon-sidekiq -f -n 100 -p 4

# And you can always pipe it to grep
# For example to show any lines from the web logs that have a status code of 500
sudo journalctl -f -u mastodon-web -n 500 | grep "status=500"
</code></pre>
<p>You can do a lot with these commands. This helped me initially discover database connection issues when I over-eagerly tried to optimize configs, and helped me notice that I forgot to require SSL for my remote database.</p>
</li>
<li>
<p><strong>Restart things:</strong> You can restart or reload (like a restart but no downtime as it reloads the config, if supported by the service) these services with a command like:</p>
<pre><code>sudo systemctl restart mastodon-web
</code></pre>
</li>
<li>
<p><strong>Check sidekiq:</strong> Sidekiq is the background job processor for Mastodon. It&#x27;s how Mastodon manages receiving new posts, sends our your posts, and more.</p>
<p>Generally you don&#x27;t need to worry too much about what it&#x27;s doing, but there&#x27;s one key scenerio to be aware of: if you have a massive queue of jobs that are piling up. What this looks like is the "Enqueued" tab in the Sidekiq dashboard will show a large number that&#x27;s not going down in a reasonable amount of time.</p>
<p>This would mean your machine cannot keep up. You may notice significant delays in receiving new posts on your server. A Mastodon instance running well would have likely have few to no tasks busy or queued, and when when queued tasks are added, they get processed quickly. If this happens to you, it could mean your server is underpowered and trying to do too much (don&#x27;t use any relays if you are), or could benefit from optimizing your sidekiq setup (more later).</p>
<p>There&#x27;s also a tab for dead jobs in Sidekiq. These are tasks that have failed repeatedly and will not be retried. You&#x27;ll just want to glance at those to ensure the issues are not related to you. Even if some jobs fail, you&#x27;ll likely see that they are HTTP connection or timeout errors with other servers and likely not your issue.</p>
</li>
</ul>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-sidekiq.jpg" alt="Mastodon sidekiq job processor" width="2000" height="1102" />
<small>Access the sidekiq dashboard directly in <strong class="semibold">Preferences → Sidekiq</strong></small>
<h3>Optional: Extend your post character limit beyond 500</h3>
<p>It&#x27;s your server, you control the code so why not extend your server&#x27;s character limit well past the default limit of 500 characters? Doing this will take just a few minutes, all you have to do is change a number in 2 files, precompile assets, and then restart some services.</p>
<p>This article goes into detail about the process: <a href="https://write.as/sweetmeat/customize-mastodon-to-change-your-post-character-limit">Customize Mastodon to Change Your Post Character Limit</a>. However, keep in mind that you&#x27;ll have to reapply these changes with every Mastodon update.</p>
<p>I changed my character limit to 15,000. In reality I won&#x27;t be posting things that long, though I did take advantage of a 1,000 character reply which was very handy and I didn&#x27;t have to try to split it up into multiple replies or aggressively truncate my thoughts. The change works seamlessly: people on other Mastodon (or other ActivityPub software) servers will see the longer posts, and all Mastodon clients should see the updated limit in their post composer interfaces.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-extended-char-limit.jpg" alt="Mastodon composers with extended character limit: Ivory and Mastodon web" width="2000" height="1282" />
<small>Extended character limit recognized by <a href="https://tapbots.com/ivory/" title="Ivory for iOS by Tapbots">Ivory</a> and Mastodon Web.</small>
<h3>Optional: Change your join date</h3>
<p>One annoying thing of creating a new Mastodon server, or migrating to a new one, is that your join date—shown prominently on your profile—reflects the date you created the new account. It doesn&#x27;t inherit the date of your previous account(s) that you migrated.</p>
<p>Since you&#x27;re running your own server and have access to the database, the join date is easy to change. You can change it to your original account creation date, or any date you like. Why not? It&#x27;s your server, do with it what you want. SSH into your server, or use the web console from your hosting provider and run the following commands:</p>
<pre><code>sudo su - mastodon 

# Enter PostgreSQL interactive terminal for the Mastodon database
psql -d mastodon_production

# Update the join date for your account...
# Replace YOUR_USERNAME with your username (does not include domain name)
# Replace date with your desired date, using the exact same format 
UPDATE accounts SET created_at=&#x27;2018-01-01 00:00:00&#x27; where username=&#x27;YOUR_USERNAME&#x27;;

# Exit the PostgreSQL interactive terminal
exit
</code></pre>
<h3>Optimizing Mastodon for your server</h3>
<h3>Proceed at your own risk</h3>
<p>If you&#x27;re just running your own single-user Mastodon instance that you expect to be low traffic, you don&#x27;t need to touch anything in this section; the defaults are fine for your system. But if you have a beefy server with extra RAM and cores to put to use, you have a lot of followers, and/or you just generally want to nerd out on squeezing more performance from your server then read ahead.</p>
<p>As a word of caution, changing things in various Mastodon config files can easily take your server offline. I recommend doing this before you&#x27;ve done a migration, or late at night to minimize the effects of downtime. Also, I highly recommend setting up Rewind AI on your Mac so you can easily retrace your steps when you&#x27;re changing things and running commands.</p>
<p>By following this guide, you&#x27;ve already done an important performance tweak: using a cloud object storage solution for hosting all media for your Mastodon posts. The most common things advanced users will do includes modifying sidekiq to use separate processes for each queue, as well as setting up pgbouncer for PostgresSQL.</p>
<h3>Resources</h3>
<p>Scaling Mastodon can be a deep topic depending on your needs. I&#x27;m only concerned with running Mastodon as a single-user instance, but it&#x27;s helpful to better understand the pieces of Mastodon and what can and should be changed and when.</p>
<p>The Mastodon website has a page about <a href="https://docs.joinmastodon.org/admin/scaling/">scaling your server</a>. It&#x27;s particularly good to learn the relationship between threads and processes with the web server (threads max out your CPU first, processes max out your RAM first), as well as learning about pgbouncer to help reduce any database connection bottlenecks.</p>
<p>Then there&#x27;s the lengthy and advanced article <a href="https://hazelweakly.me/blog/scaling-mastodon/">Scaling Mastodon: The Compendium</a>. Most of the topics in there might be a bit overkill for a small single-user instance though.</p>
<h3>Sidekiq</h3>
<p>I mentioned a bit about what to be on the lookout for <a href="#sidekiq">with sidekiq earlier in this article</a>, such as having a backed up queue. The first thing I did with sidekiq is slightly increase the number of threads. By default using the DigitalOcean droplet, you may have a default of <code>25</code> for <code>DB_POOL</code> and the concurrency flag <code>-c</code>.</p>
<p>However, the number of <code>max_connections</code> for the Postgres database by default is 100. Counterintuitely, if you opted for a separate managed database from DigitalOcean you may have only 25 database connections available, in which case you may opt to setup their pgbouncer feature called "connection pools"; that&#x27;s what I did. If you do the same, you&#x27;ll need to change your database connection info so Mastodon connects to pgbouncer on a different port.</p>
<p>What I did was edit <code>/etc/systemd/system/mastodon-sidekiq.service</code> and change the <code>DB_POOL</code> value to 50, as well as the number after <code>-c</code> on the ExecStart line. You don&#x27;t want to tell sidekiq to consume all of our available database connections as each Puma web server thread will need a database connection too.</p>
<pre><code>Environment="RAILS_ENV=production"
# Edit this 
Environment="DB_POOL=50"
Environment="MALLOC_ARENA_MAX=2"
Environment="LD_PRELOAD=libjemalloc.so"
# and the number after -c 
ExecStart=/home/mastodon/.rbenv/shims/bundle exec sidekiq -c 50
</code></pre>
<p>Then I also configured sidekiq to automatically restart every 6 hours. There seems to be an <a href="https://github.com/mastodon/mastodon/issues/16495">open issue</a> where sidekiq memory usage continually creeps up over time. Honestly, this was one of the firs things I configured and never ran without this setting so I&#x27;m not entirely sure how necessary it is. But I haven&#x27;t had any issues.</p>
<pre><code>Restart=always
RuntimeMaxSec=21600
</code></pre>
<p>After modifying <code>mastodon-sidekiq.service</code>, you&#x27;ll need to run these:</p>
<pre><code>systemctl daemon-reload
systemctl restart mastodon-sidekiq.service
</code></pre>
<h3>Puma</h3>
<p>The other thing I did was adjust the number of threads and proccesses used by puma, the Mastodon web/app server. If you expect a lot of web traffic, or just like to be prepared, you may be interested in tweaking puma as well.</p>
<p>I initially looked into this because had some unused RAM on my server and wanted to let puma use a bit more. In the process I learned that the <a href="https://ruby.social/@evanphx/109365852402052564">it&#x27;s recommended to allocate</a> 1.5 processes per CPU core. So my server has 2 cores, so I can get away with 3 processes for puma. I set it to also use 10 threads per process.</p>
<p>Edit <code>/etc/systemd/system/mastodon-web.service</code> and add these two lines (or modify if they already exist):</p>
<pre><code># Set this to 1.5 * number of cpu cores
# Find your # of cores by running: cat /proc/cpuinfo | grep processor | wc -l
Environment="WEB_CONCURRENCY=3"
# The number of threads per process. If you&#x27;re RAM constrained, you may want to lower this.
Environment="MAX_THREADS=10"
</code></pre>
<p>Save the file and restart the service:</p>
<pre><code>systemctl daemon-reload
systemctl restart mastodon-web.service
</code></pre>
<p>That being said, you don&#x27;t really need to mess with puma much. For a single user instance the vast majority of your traffic will be from people interacting with your posts via a Mastodon app/client through their server—not directly via your website—which is not served by the web service.</p>
<hr/>
<p>This is barely scratching the surface with what&#x27;s possible for optimizing and scaling Mastodon. I&#x27;m just running my own single-user instance and it&#x27;s been running great so far. If you&#x27;re not sure what to do, I would recommend not touching anything and seeing how your server works for a while. You can keep an eye on system logs as <a href="#go-wrong">mentioned earlier</a>, as well as sidekiq.</p>
<h3>The end</h3>
<p>This article has been in the works for a while now but hopefully it has helped you get a better understanding what&#x27;s involved with hosting your own Mastodon server, how to keep it running smoothly, and how to tweak it to your liking.</p>
<p>It&#x27;s a bit of work to get running but the benefits of owning your online identity and data with Mastodon are well worth it. If you&#x27;ve enjoyed this article, please share it with anyone that might find it useful, and of course follow me on Mastodon on my new instance: <a href="https://stammy.design/@stammy">@stammy@stammy.design</a>.</p>]]></description>
            <link>https://paulstamatiou.com/hosting-your-own-mastodon-server</link>
            <guid isPermaLink="true">https://paulstamatiou.com/hosting-your-own-mastodon-server</guid>
            <dc:creator><![CDATA[Paul Stamatiou]]></dc:creator>
            <pubDate>Tue, 07 Mar 2023 00:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Mastodon]]></title>
            <description><![CDATA[<img src="https://turbo.paulstamatiou.com/uploads/2022/12/copyright-paul-stamatiou_com-stammy-mastodon-ivory.jpg" alt="A Mastodon app called Ivory" />
<small>A Mastodon app called Ivory</small>
<p><a href="https://paulstamatiou.com/odeo-launches-twttr-hellodeo/">I first wrote about Twitter</a> (née twttr) just over 16 years ago. Over the years, Twitter’s place and impact in the world has become clear. It’s not just a place to hear about breaking news, keep up with celebrities or see what your politicians are saying. It’s a place where communities are formed and thrive. It is the global town square.</p>
<p>But that’s all been changing daily ever since Elon Musk took over. This has become the tipping point for many to reconsider their reliance on big tech companies with closed platforms and to be in control of their data. This whole Twitter/Elon saga sucks, but maybe it’s just the kick we needed.</p>
<p>And with that, I’m starting to spend more time on Mastodon, and I’ll tell you why. Follow me on Mastodon: <a href="https://stammy.design/@stammy">@stammy@stammy.design</a> (you’ll have to search for it on your Mastodon server).</p>
<hr/>
<div><h3>Part 2: Hosting your own Mastodon server</h3><p>Want to have complete control and host your own Mastodon server?</p><p>Shortly after I wrote this post, I loved Mastodon so much I decided to host my own server and document the process for those that would want to do the same. In <strong><a href="https://paulstamatiou.com/hosting-your-own-mastodon-server/">Hosting your own Mastodon server</a></strong> I show two ways to host your own server (using a fully-managed Mastodon host, and using a VPS provider). I go into everything from scripts to backup your database and run media clean up tasks, to advanced settings to optimize your server, and much more.</p><a href="https://paulstamatiou.com/hosting-your-own-mastodon-server/" title="Hosting your own Mastodon server"><img src="https://turbo.paulstamatiou.com/uploads/2023/01/copyright-paulstamatiou_com-mastodon-mbp.jpg" alt="Hosting your own Mastodon server" /></a></div>
<hr/>
<p>Twitter quickly became a core part of how I used the internet, made friends, learned things, kept up with the world, killed time, and so much more. I eventually went to <a href="https://paulstamatiou.com/joining-twitter/">work at Twitter for nine years</a>. Twitter, the company, had lots of ups and downs, but the people behind it cared so much about the platform and its place in the world. It’s the critical conversational layer of the internet. Creators have active social media accounts elsewhere online, but they always relied on Twitter to truly connect and have conversations with their community. It was the vital hub.</p>
<p>Well, it’s a different bird site now. I don’t intend to summarize the series of events and drama that have unfolded ever since Elon Musk took over Twitter, nor do I have the energy for that, but if you’ve seen even a portion of all the headlines, you get where I’m coming from.</p>
<p>Seeing the company&#x27;s culture get slaughtered so quickly was hard. It was a culture woven around caring for coworkers, caring for people that used Twitter, and caring about the good of the service.</p>
<p>A few weeks ago was the last straw for me. Reputable accounts were randomly banned, and Twitter announced that people could no longer Tweet links to other social networks that were deemed competitive. Then more people were banned for saying they were leaving. And then, suddenly, this big policy suddenly vanished.</p>
<p>I lost a lot of hope and confidence in Twitter and how it is being run. I still think Twitter will be around for some time, but I’m not sure how much I want to continue investing in it as much as I used to.</p>
<p>I had seen some folks migrating away to alternate services in recent months but didn’t think much of it. Twitter was here to stay, right?</p>
<h3>Fool me once...</h3>
<p>The Twitter/Elon saga has a silver lining that I can appreciate. It shows us that we’ve all become too comfortable with just a few large tech companies amassing our info, controlling our data, and what we do with it.</p>
<p>If you’re the typical user of internet services from large companies, you probably haven’t had too many issues. Sure, maybe you got locked out of your Google account once, and it took a long time for support to help you out, but for the most part, you didn’t have to think about it. The big companies were mostly staying in their lane and not doing anything too egregious (aside from miscellaneous privacy dramas). But they could have been.</p>
<p>This Twitter drama is a perfect example of what can go wrong and how quickly it can go wrong. It’s too much. I’ve invested a lot of time into Twitter (thanks to <a href="https://twitter.com/stammy">the 53,000+ of you</a> that have been following me there).</p>
<p>I no doubt expect Elon to reverse some of his decisions from the regular backlash from users and press, but there’s no trust anymore. Even if a new CEO or a new owner is announced, I don’t know if Twitter can ever be truly trusted again. Fool me once, shame on you, fool me twice, shame on me..</p>
<p>All this to say, I think it’s time we take more control of our data. I’ve been trying to reduce my reliance on Google accounts and services already. I’m sure I end up moving on to Proton or elsewhere in 2023.</p>
<p>This does all make me a tad nostalgic for the early 2000s. We were all just running our own little blogs in a corner of the internet and keeping up with each other with RSS readers. Social media was just our own little websites. Why can’t we just go back to that?</p>
<h3>Mastodon</h3>
<h3>A decentralized social network built on an open protocol</h3>
<img src="https://turbo.paulstamatiou.com/uploads/2022/12/mastodon-site.webp" alt="The Mastodon server I use, stammy.design" />
<small>The Mastodon server I use, <a href="https://stammy.design/@stammy">stammy.design</a>, though most Mastodon sites looks like this.</small>
<p>I’ve started spending more time on <a href="https://joinmastodon.org">Mastodon</a>, open-source software for running a decentralized social networking service that’s not somewhat similar to Twitter. It’s decentralized in that there’s no single website or company running the show. It’s not a single platform.</p>
<p>Instead, Mastodon is comprised of a network of independent servers, which you may see referred to as Mastodon instances. Each server is run by a different person that manages and moderates it. You can sign up for an account on any server you want, and you can follow people on any other server just like you would on Twitter. (There are exceptions, like if one server blocks another server—defederation).</p>
<p>Mastodon was first released in late 2016 by <a href="https://mastodon.social/@Gargron">Eugen Rochko</a>, who wanted to create a platform not controlled by a single company or person. Mastodon was developed as a non-profit, and the platform is ad-free. It has made specific design choices to reduce harassment and give users more control over their experience and create a safer environment.</p>
<p>As a long-time Twitter employee, I had heard of Mastodon many times (as well as a predecessor, <a href="https://en.wikipedia.org/wiki/Diaspora_(social_network)">diaspora</a>) but never took much time to dive deeper. It always felt like a rudimentary platform 10 years behind Twitter. In hindsight, it was foolish to think of it in terms of features rather than protocols. That was the real innovation with Mastodon, not whether it had certain product features.</p>
<p>Mastodon servers communicate with each other with open-source software using a standardized, open protocol called ActivityPub for sharing updates. There are quite a few other open-source projects using ActivityPub, such as <a href="https://pixelfed.org/">Pixelfed</a> and <a href="https://pleroma.social/">Pleroma</a>, but Mastodon is the most popular. You can even run your own Mastodon instance all by yourself if you want.</p>
<p>You may also see it referred to as a <a href="https://en.wikipedia.org/wiki/Distributed_social_network">federated social network</a> and <a href="https://en.wikipedia.org/wiki/Fediverse">fediverse</a>. There’s also a bit of nuance here when it comes to federation. It’s a form of decentralization, but not every instance needs to connect with another instance. A Mastodon instance itself can be entirely self-contained, with users on it following each other only (though not common). While a huge benefit, federation also leads to some product constraints.</p>
<h3>Federated, like email</h3>
<p>Federation also means that you not only have to know someone’s username but also their server. This leads to email-like usernames, such as mine: <a href="https://stammy.design/@stammy">@stammy@stammy.design</a>. You need both bits of information to follow someone, which makes it a tad harder to use than a centralized service. Someone can always just search for you with your username only, but it’s not reliable for various reasons related to how the federation is done.</p>
<p>This also means your username can’t really be taken. It could be taken on a particular Mastodon server, but you can always use another server or self-host Mastodon on your own domain. It also leads to there being no such thing as verified accounts on Mastodon. There’s no central authority deeming which account is verified or not.</p>
<h3>And it’s growing.</h3>
<p>Mastodon is having a bit of a moment right now. The non-profit that runs Mastodon even <a href="https://arstechnica.com/tech-policy/2022/12/twitter-rival-mastodon-rejects-funding-to-preserve-nonprofit-status/">turned away multiple VC investment offers</a>. With all that’s happening at Twitter, people have been longing for a more stable product, one where their data could be more trusted, one that’s ad-free, supported by communities, and moderated by communities. One where terms and policies don’t change daily.</p>
<p><a href="https://blog.mozilla.org/en/mozilla/mozilla-launch-fediverse-instance-social-media-alternative/">Mozilla announced</a> they will be launching their own instance—<code>Mozilla.social</code>—next year in pursuit of building a healthy alternative to today’s social media platforms. Even the <a href="https://www.washingtonpost.com/technology/2022/12/17/how-to-join-mastodon/">Washington Post</a> wrote about how to get started with Mastodon.</p>
<blockquote>
<p>"While there is no shortage of social media platforms new and old, this is a radically different approach to social media that offers something traditional social media cannot. This may be one of the reasons why <strong>Mastodon has recently exploded in popularity, jumping from approx. 300K monthly active users to 2.5M</strong> between the months of October and November, with more and more journalists, political figures, writers, actors and organizations moving over."</p>
<p>—<a href="https://blog.joinmastodon.org/2022/12/twitter-suspends-mastodon-account-prevents-sharing-links/">Mastodon</a></p>
</blockquote>
<h3>Getting started with Mastodon</h3>
<h3>It’s not easy, but it’s worth it.</h3>
<p>Now that we’ve got a basic grasp of Mastodon, how it’s federated like email but similar in functionality to Twitter, it’s time to give it a try.</p>
<p>But maybe a bit of a heads-up first. While Mastodon may feel comparable in look and functionality to Twitter, it’s probably best to approach Mastodon with the mindset that it is a new platform rather than trying to view it as a Twitter clone. There are key differences that will take some getting used to, and it will be a bit harder to get started.</p>
<p>The first challenge is signing up. You can’t just go to the Mastodon website and create an account. You first need to pick <em>where</em> you want your account by picking a Mastodon server you wish to call your home.</p>
<h3>Pick a server, follow anyone on any server</h3>
<p>The concept of Mastodon servers ends up being a confusing part of the Mastodon onboarding and usage experience. Even after you have an account on one server, you can’t just log into any other Mastodon server. You always have to log into yours. But you will be able to follow anyone on your own server, even if they’re on a different Mastodon server.</p>
<p><strong>So how do you find and pick a server, and does it matter which one you pick?</strong> There are several schools of thought on this, but I’ll try to explain it as best I can.</p>
<ul>
<li>
<p><strong>The argument for picking any server:</strong> You can easily change servers later on if you want. Just pick a server that looks interesting and go for it. If you already know other Mastodon users that you want to follow and don’t need too much assistance with discovering content and accounts, you’ll be okay.</p>
</li>
<li>
<p><strong>The argument for carefully picking your server:</strong>
Picking a server is like deciding where to live in a city or what subreddit you want to frequent. You’ll more easily run into the same people and content if you pick a server that’s relevant to your interests. You’ll also be more likely to find people who are interested in the same things as you.</p>
<p>This is especially important if you are new to Mastodon and don’t know of many other people you’d want to follow that are on Mastodon.</p>
<p>With Mastodon, in addition to your typical Home timeline comprised of people you explicitly follow, you also get two bonus timelines: a local timeline comprised of people on your specific Mastodon server and a federated timeline of posts from people your Mastodon instance knows about (not a full firehose of all Mastodon posts, just the one your instance subscribes to via relays and from people the instance follows).</p>
<p>Having a high-quality local timeline gives you an opportunity to more easily discover great content related to your interests, helps other people discover you, and vice versa. This is important for a lot of reasons, the leading of which is that it’s harder to discover people to follow on Mastodon. There is no algorithmic timeline injecting relevant content you may like into your timeline, and searching on Mastodon is not great.</p>
<p>So that’s one part of it. The other part is maybe more important: picking a server is also like picking your landlord. Do you trust the admin of the server to host your identity? Do you think they have the technical know-how to maintain and secure the infra as needed? Are they making backups? What if they get lazy, and you’re stuck on a 2-year-old version of Mastodon lacking all the new features? Do they have a plan for financially supporting the infra? Or are they running an overloaded server that is extremely slow?</p>
<p>And finally, each Mastodon server has its own set of rules in place. The rules give you an idea of the type of community you would be joining. People that don’t abide by the rules can be actioned on by the server’s moderators and admins.</p>
</li>
</ul>
<h3>Finding your server</h3>
<p>If there are already a lot of people you want to follow on a particular server, that’s probably a good place to start. Examples of Mastodon servers I come across often include ones like <code>mastodon.design</code>, <code>front-end.social</code>, <code>hachyderm.io</code>, <code>infosec.exchange</code>, <code>indieweb.social</code> and more.</p>
<p>An easy way to find where your friends are on Mastodon is by using <a href="https://debirdify.pruvisto.org/">Debirdify</a> or <a href="https://fedifinder.glitch.me/">fedifinder</a>. You authenticate your Twitter account, and it will tell you where people you follow on Twitter are on Mastodon if they’ve made Mastodon accounts. It’s an easy way to get an idea of Mastodon instances you may want to use.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2022/12/debirdify-stammy.webp" alt="Debirdify screenshot" width="2144" height="3496" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2022/12/fedifinder-stammy.webp" alt="Fedifinder screenshot" width="2144" height="1616" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2022/12/movetodon-stammy.webp" alt="Move to don screenshot" width="1924" height="1616" />
<small>Debirdify, Fedifinder and Move to don</small>
<p>You’ll quickly notice that <strong>not all servers have open, public registration</strong>. Some may just be entirely closed or require an invite and are meant for a smaller community. Others require approval by the admin before you can join. And others may only be temporarily closed, so the admins have time to upgrade their servers to deal with the influx of new users, and you may just need to try again later.</p>
<p>You can, of course, just browse yourself and see what’s out there. Tools like <a href="https://instances.social/">instances.social</a>, <a href="https://mastodonservers.net/">MastodonServers.net</a>, <a href="https://fedidb.org/network">FediDB</a>, and the <a href="https://joinmastodon.org/servers">official Mastodon servers page</a> can help with that.</p>
<p>I’m on <s>macaw.social, a small private Mastodon instance created by former Twitter employees meant for former Twitter employees and friends</s> <a href="https://stammy.design">stammy.design</a>, my self-hosted Mastodon instance.</p>
<p>If this is all a bit confusing, you can always just pick from one of the huge Mastodon instances like mastodon.social, mas.to, and mastodon.cloud. However, since most of these are getting a ton of new users now, they are more likely to feel slower until they scale up their infrastructure.</p>
<hr/>
<h3>Self-hosting your own Mastodon instance</h3>
<h3>A bit more than meets the eye</h3>
<p>Of course, the beauty of the Fediverse is that you can just host your own instance, own your data, and have complete control of your Mastodon identity! If you know that this is what you want to do, there are a few routes to take.</p>
<ul>
<li>
<p><strong>Managed hosting:</strong>
There are a few hosting companies that specialize in hosting Mastodon servers, such as <a href="https://masto.host/">Masto.host</a> among <a href="https://docs.joinmastodon.org/user/run-your-own/#so-you-want-to-run-your-own-mastodon-server">others</a>, though at this time some have paused new signups due to high demand.</p>
</li>
<li>
<p><strong>DIY hosting:</strong> And then you can just do it all yourself following the <a href="https://docs.joinmastodon.org/admin/install/">official guide</a> on any server where you can set up Postgres, Redis, Ruby, and Sidekiq. You’ll need to have an email host so your Mastodon instance can send emails to you, and you’ll likely want some cloud storage, such as S3, for your media and files. You’ll also want to have a system in place for regular database backups. Here’s an article I found outlining someone’s experience <a href="https://www.micahwalter.com/notes-on-running-a-mastodon-server-on-aws/">setting up their instance on AWS</a>.</p>
<p>Running a server yourself is a bit more involved than setting up a simple static website or WordPress install. And depending on how many relays you set up (more on that later), you may find yourself tuning the Sidekiq background job processor config so it can run faster. If you still want to DIY but prefer a bit of assistance, the hosting provider DigitalOcean has a <a href="https://www.digitalocean.com/community/tutorials/how-to-install-mastodon-with-digitalocean-marketplace-1-click">"1-click" setup for Mastodon</a>. It’s still not a walk in the park, but it saves you quite a bit of work in the command line.</p>
</li>
</ul>
<p><strong>But with great power comes great responsibility.</strong> By hosting a Mastodon instance, you’ll be liable for the content on your server created by your users <em>and</em> anyone you follow as well as what they boost (boosts are like ReTweets).</p>
<p>Yes, you read that right. The way Mastodon works, <strong>everything you view on your Mastodon account, including media, is actually hosted on your server</strong>, even if the Mastodon user you follow is on another instance. Their instance just sent that post to yours, essentially. So any text or media in their posts is now hosted by you. And if your instance has any relays setup, you’ll have a lot more content being cached and served from your instance.</p>
<p>This goes down the path of needing to register a designated DMCA agent if you want to be careful. The EFF has a detailed article on the topic: <a href="https://www.eff.org/deeplinks/2022/12/user-generated-content-and-fediverse-legal-primer">User Generated Content and the Fediverse: A Legal Primer</a>. This <a href="https://twitter.com/rahaeli/status/1593819064161665024">a long thread</a> and <a href="https://denise.dreamwidth.org/91757.html">accompanying blog post</a> also outlining some of the legal ramifications of hosting your own Mastodon instance.</p>
<p>So until you’re 100% sure you want to take on that commitment and liability, maybe start off by joining an instance hosted by a seasoned admin and donate to help them manage infra costs and things.</p>
<div><h3>A note about relays</h3><p>I mentioned relays a few times above, so what are they? Relays are servers running specific software that can help supply smaller instances with content from other Mastodon instances. Why would you want this? To help you discover content and accounts.</p><p>Remember how I said that Mastodon comes with three timelines you can follow: home (people you follow), local (accounts on your instance), and federated? The federated timeline is composed of posts from any accounts anyone on your instance follows, in addition to anything provided by relays that the instance is subscribed to.</p><p>Unfortunately, I’ve found it challenging to find good relays with communities and content I would want to feed into my own instance. Many instances I would want to add as a relay don’t run a relay. There’s little incentive for them to add it anyways: more work for their server and more costs associated with that.</p><p>At the same time, adding random relays from unknown communities isn’t a good idea either. The content could be questionable, and you’ll be hosting all that media yourself, which opens you up to more liability and more hosting costs.</p><p>That’s one benefit of not running a single-user instance just for yourself. It’ll be a bit more work for you to discover new content and accounts you enjoy as you won’t have much of a local or federated timeline at your disposal.</p></div>
<hr/>
<h3>How to find people to follow?</h3>
<p>You’ve found a Mastodon server you like, created an account, and now you want to find out who to follow or how to find people you already follow on Twitter. There are a few great tools to help with this.</p>
<ul>
<li>
<p><strong><a href="https://movetodon.org/">Move to don</a></strong>: This is probably the easiest way to get started. Connect with your Twitter account, and it just shows you people you follow that are now on Mastodon, providing you an easy way to follow them all or individually. You’ll want to keep checking it over days/weeks/months as more people sign up for Mastodon. <strong>Update:</strong> It seems Twitter has disabled Move to don&#x27;s API access but <a href="https://mastodon-flock.vercel.app/">Mastodon Flock</a> seems like a good replacement.</p>
</li>
<li>
<p><strong><a href="https://twitodon.com/">Twitodon</a>, <a href="https://debirdify.pruvisto.org/">Debirdify</a> and <a href="https://fedifinder.glitch.me/">Fedifinder</a></strong>: I mentioned some of these tools earlier for helping you find instances, but they also help you find people to follow from your existing network on Twitter. However, at the moment, they are a bit manual and rely on providing you with an exported CSV file of user accounts for you to upload and import into your Mastodon instance.</p>
</li>
<li>
<p><strong><a href="https://followgraph.vercel.app">Followgraph for Mastodon</a></strong>: This is another great tool, but unlike the others doesn’t need you to connect your Twitter account. Instead, you just provide it with your Mastodon handle (or anyone else’s), and it recommends other accounts to follow based on who your followers follow.</p>
</li>
<li>
<p><strong><a href="https://fediverse.info/explore/people">Fediverse.info</a></strong>: Another tool for helping you find people to follow. This one works by letting you browse by hashtags people have put in their bio.</p>
</li>
</ul>
<p><strong>Following Twitter accounts directly on Mastodon</strong>
And finally, if you’re devoted to Mastodon and don’t feel like checking Twitter all that often anymore, you can use some <a href="https://github.com/NicolasConstant/BirdsiteLive">software called BirdsiteLive</a>—an "ethical ActivityPub bridge to Twitter"—to follow people that are only on Twitter. It needs to be hosted to use, but you can <a href="https://fedidb.org/software/birdsitelive">find live instances of it on FediDB</a>. Basically, you just type in a Twitter username, and it gives you a Mastodon username to follow. At this time, one example instance that’s online is <a href="https://bird.makeup">Bird.makeup</a>.</p>
<p><strong>Cross-posting between Twitter and Mastodon</strong>
If you’re interested in posting to both Mastodon and Twitter at the same time, you can use a tool called <a href="https://moaparty.com/">Moaparty</a> or <a href="https://mikeindustries.com/blog/archive/2022/12/how-to-automatically-post-your-tweets-to-mastodon">do it yourself with IFTTT</a>. However, as a word of caution, some Mastodon folks don’t appreciate this behavior and may even consider it spammy. I agree with that sentiment: treat Mastodon as its own thing.</p>
<h3>Mastodon apps</h3>
<h3>And how developers have truly embraced Mastodon</h3>
<img src="https://turbo.paulstamatiou.com/uploads/2022/12/stammy-on-mastodon-ivory-app.webp" alt="Ivory Mastodon client" />
<small><a href="https://tapbots.com/ivory/">Ivory</a>, the Mastodon client for iOS and macOS, by <a href="https://tapbots.com/">Tapbots</a></small>
<p>Now for the fun part: exploring the world of Mastodon apps and clients.</p>
<p>There are several ways to interact with Mastodon. You can, of course, use the standard Mastodon web interface for your server, as well as the official Mastodon iPhone and Android apps to log into your server.</p>
<p>If you want a more advanced web experience, you can go to Preferences ’ Appearance and enable the "advanced web interface" to give you a multi-column layout reminiscent of TweetDeck (there&#x27;s also <a href="https://mastodeck.com/">Mastodeck</a>). And if you would prefer a simpler web client, take a look at Pinafore.social. <strong>Update:</strong> it looks like Pinafore is shutting down but the <a href="https://elk.zone/">Elk web client looks amazing</a>.</p>
<p>But I’m not here to tell you about the official apps. I want to talk about the growing and thriving developer community that is fully embracing Mastodon and the potential of the decentralized protocol. To paint a picture of why this is such a big deal, you also have to understand how much of a hassle it has been over the last decade to build anything on top of the Twitter API. It was especially hard to see as a long-time employee.</p>
<p>Long story short, Twitter made it hard. Hard to even get an API key and get your app approved. Hard to get bugs fixed or new features accessible via the API. Hard to access the data developers wanted. Hard to not hit arbitrary constraints or limits. Things were always changing, rugs were pulled, announcements about new priorities and new rugs were made, only for them to be pulled again (read <a href="https://www.theverge.com/2021/11/15/22779149/twitter-api-version-2-official-decentralized">this</a>, <a href="https://techcrunch.com/2022/11/02/twitter-cancels-its-chirp-conference-for-developers-amid-management-transition/">this</a> and <a href="https://techcrunch.com/2022/12/15/developer-platforms-are-all-about-trust-and-twitter-lost-it/">this</a>).</p>
<p>No one knows this pain better than the team at Tapbots, makers of a popular third-party Twitter client called Tweetbot. I’ll be the first to say I did not like Tweetbot—not due to anything about the app itself; it was beautifully executed and well-built—I was just designing for the official Twitter apps. Tweetbot had nice details, but I never really used it much, though oddly enough, quite a few of the Twitter iOS engineers used it over the years, if that tells you anything.</p>
<p>Needless to say, the Tapbots team had to deal with all the ups and downs that came with building on top of the Twitter API. Twitter wasn’t necessarily fond of third-party clients that they couldn’t effectively monetize or control.</p>
<p>Mastodon brought the winds of change, an open web not controlled by any single entity. <a href="https://tapbots.social/@mark/109524033562967560">Mark Jardine</a> from Tapbots wrote a thread outlining his experience building on top of Twitter, contrasted with their new focus on Mastodon:</p>
<blockquote>
<p>“As much as Twitter has brought us success, it has also been extremely frustrating for the past 6-7 years trying to build something great with a nerfed API.”[…]</p>
<p>“Building an app for an open and decentralized social platform felt so refreshing. Inspirational! I haven’t been so excited designing something in a long time. With Tweetbot, we were always fighting with the API limitations while knowing in the back of our minds that someday the API could be taken away.”</p>
<p>“I didn’t realize it then, but that killed a lot of our excitement and enthusiasm. With @ivory, we are just ecstatic every single day. It’s just been a pure joy to make software again.”</p>
<p>—<a href="https://tapbots.social/@mark/109524033562967560">@mark@tapbots.social</a></p>
</blockquote>
<p>Tapbots is building a lovely Mastodon client for iOS and macOS called <a href="https://tapbots.com/ivory/">Ivory</a>. But they’re not the only ones ramping up development on a Mastodon client. There’s also Mammoth, an app in development by iOS developer <a href="https://mastodon.social/@JPEGuin">Shihab Mehboob</a> along with his team. I’ve also been testing Mammoth, and if you’re used to the official Twitter mobile apps, you’ll find Mammoth familiar.</p>
<p>Then there’s Metatext, Toot!, tooot, Mastoot, Mast, Tusker, and Woolly, <a href="https://github.com/Dimillian/IceCubesApp">IceCubesApp</a>, among others. Some of these are in Testflight and are best found by following the developers on Mastodon. The official Mastodon site has a <a href="https://joinmastodon.org/apps">list of public third-party apps</a> as well.</p>
<h3>Using Mastodon</h3>
<h3>Toots, boosts, and bad search, oh my!</h3>
<p>So you’ve made it. You have an account, you’ve followed some people, and you have installed a lovely Mastodon app. Time to get to know Mastodon a bit better. If you’re coming from Twitter, you’ll pick it up quickly, but there are a few quick differences:</p>
<ul>
<li><strong>Tweets → Toots</strong>: This was the Mastodon word for a post for a long-time, but a recent software update renamed the "Toot" button to simply "Publish." Some folks still refer to posts as toots.</li>
<li><strong>ReTweets → Boosts</strong>: Sharing a post on Mastodon is done by boosting, much like ReTweeting. If anything, boosting is encouraged and seemingly more common on</li>
<li><strong><s>Quote Tweets</s></strong>: Mastodon has no equivalent of Quote Tweets. You can only boost a post. This was an <a href="https://blog.joinmastodon.org/2018/07/cage-the-mastodon/#:~:text=Another%20feature%20that%20has%20been%20requested%20almost%20since%20the%20start%2C%20and%20which%20I%20keep%20rejecting%20is%20quoting%20messages">intentional design decision meant to curb abuse and harassment</a>. However, with the <a href="https://en.wikipedia.org/wiki/Eternal_September">Eternal September</a> of Twitter users flooding Mastodon, it is a bit of a hot topic and has come up often recently. Here’s <a href="https://macaw.social/@dml/109569707633229305">some more thoughts on the topic</a> from an engineer I worked with at Twitter who knows the problem space well. But they eventually find their way on Mastodon; the Mastodon founder <a href="https://mastodon.social/@Gargron/109623910323239777">recently expressed some interest</a> in a version you can opt out of.</li>
<li><strong>280 character limit → 500 character limit</strong>: Toots are 500 characters! Enjoy the extra space to share your thoughts without easily getting misinterpreted. You can also reply to your own toots to create a thread, though the composer doesn’t have the built-in functionality to create a thread that Twitter has (and that I designed while at Twitter). However, since it is open-source software on top of ActivityPub, anyone running their own instance <a href="https://write.as/sweetmeat/customize-mastodon-to-change-your-post-character-limit">can modify this limit</a> to be much larger.</li>
<li><strong><s>Verification</s></strong>: As mentioned earlier, Mastodon has no concept of account verification, though some users add <code>:verified:</code> to their username and it gets rendered as a checkmark on their avatar in some Mastodon apps. Separately, links on your profile can get verified if you add a <code>rel="me"</code> link on your site.</li>
<li><strong><s>Direct Messages</s></strong>: Mastodon doesn’t really have a concept of direct messages at this time. While you may see a DM tab in some Mastodon clients, they are really just toots with the privacy setting set to "only those mentioned." But the account you mention can mention someone else in their reply, and they will get added to the DM. It’s important to note that they are also not encrypted, so your Mastodon instance admin (along with the admin of any instance you&#x27;re sending to) would be able to see it in the database if they really cared to look it up.</li>
<li><strong>Lists</strong>: While both Twitter and Mastodon have the ability to create and follow custom lists of accounts, they work a bit differently on Mastodon. You can only add people to a list that you’re already following. On Twitter, you could add anyone to a list even if you didn’t follow them, which made it great for creating separate timelines you could hop between as you wished. However, I did see some chatter about Mastodon considering this, under the moniker <a href="https://github.com/mastodon/mastodon/issues/16556">exclusive lists</a>.</li>
</ul>
<p>There are also a few other features like following hashtags (though it has some limitations) and the ability to put a post behind a Content Warning (the "CW" icon in the Mastodon post composer). Aside from that, you get the expected functionality of being able to attach video, images, and polls in addition to being able to adjust post privacy settings.</p>
<p>There’s one more thing, and this one may take some getting used to. Full-text search of the contents of Mastodon posts isn’t really a thing. You can search for accounts, and you can search for hashtags. Searching for accounts works pretty well, especially when including the full <code>@username@example.com</code> format. Searching for hashtags is a bit more limited and will only surface results that your instance knows about from local posts and federated posts. But your server doesn’t instantly know about all posts on the fediverse, so you may not see all the results you expect. You can get some very limited searching for your own posts, mentions, favorites, and bookmarks if your server admin setup <a href="https://docs.joinmastodon.org/admin/optional/elasticsearch/">ElasticSearch</a>.</p>
<p>Search could get better if someone made their own service dedicated to indexing, relaying, and searching the fediverse, but that is no small technical (and expensive) feat.</p>
<p>Isn’t it pretty bad that there’s no good search? Well, along with the lack of Quote Boosts, this is framed as a purposeful design decision (though it also feels like a technical challenge):</p>
<blockquote>
<p>"Mastodon deliberately does not support arbitrary search. If someone wants their message to be discovered, they can use a hashtag, which can be browsed. What does arbitrary search accomplish? People and brands search for their own name to self-insert into conversations they were not invited to."</p>
<p>—<a href="https://blog.joinmastodon.org/2018/07/cage-the-mastodon/">Mastodon</a></p>
</blockquote>
<h3>My thoughts on Mastodon</h3>
<h3>Vast potential mixed with non-trivial constraints</h3>
<p>Mastodon brings a lot to the table with its federated model of sharing utilizing an open protocol. It’s easy for anyone to host their own instance and own their data while participating in a large network with many communities. It’s not owned by anyone, nor can it be. It’s an open-source project run by a non-profit. Anyone can fork the code and do what they wish.</p>
<p>But, it’s not easy for anyone to get started. There’s no question about it, you cannot come from a centralized and well-capitalized product like Twitter and expect the same of a decentralized, open-source project. Mastodon is very rough around the edges when you approach it from a mindset of the former:</p>
<ul>
<li>
<p><strong>Hard to sign up. Hard to find communities</strong>: Okay, so I just installed the app... I can’t just create an account? I have to pick a server? Even with the official Mastodon app providing a list of instances to choose from, it’s still confusing. How can I see an example of the content and people on each server to know I’m choosing the right one? What are the implications of choosing a server? Is it publicly facing? Can I change it later? Is it easy to change? Et cetera.</p>
</li>
<li>
<p><strong>Hard to find people</strong>: Once you have an account, you’re still in for more uphill battles. How can you even find good, relevant, and interesting accounts to follow? You have to rely on word of mouth or third-party tools.</p>
</li>
<li>
<p><strong>Hard to find content</strong>: It’s hard to continually discover the type of content you enjoy. There’s no algorithmic timeline to inject new content into your home timeline. You have to rely on... hashtags, people you follow boosting content from others, and remember to continually check the federated and local timelines of your Mastodon instance. Using hashtags started to feel so thirsty even years ago, but now it seems like a necessity?</p>
</li>
</ul>
<p>Federation brings power. It brings constraints.</p>
<h3>Challenge 1: Following accounts and engaging with posts not on your server</h3>
<p>One early challenge you’ll run into with federation is simply around following people as well as engaging with posts you find on other instances. Let’s say I find a link to a Mastodon post externally (as in not something I come across while logged into my own Mastodon server). It could be a link on someone’s blog, from a chat app, and so on. By clicking that link, I am going to the post hosted on Mastodon instance that is not my instance. Even though I may be logged into my own Mastodon instance, this other instance doesn’t know or care about that. I’m just a visitor and have no account with that instance. I can’t favorite the post, reply, or even follow the author.</p>
<p>Instead, the onus is on me to find a way to that same profile or post, but within my Mastodon instance where I’m logged in and can carry out any actions I want to take. <strong>This is super annoying</strong> and happens all the time. For example, I can’t link you to my Mastodon profile <a href="https://stammy.design/@stammy">@stammy@stammy.design</a> and have you tap follow. That would only work if you already had an account on stammy.design. So you have to copy the username, then go to your Mastodon website or app and search for my account.</p>
<p>What’s the solution? Nothing great. A partial solution for desktop is to use a <a href="https://github.com/bramus/mastodon-profile-redirect">Chrome extension that redirects profiles</a> to your own instance, but it doesn’t work for posts (you can&#x27;t just reformat the URL as the ID of the post isn’t the same across instances). And I’ve seen some chatter about an <a href="https://github.com/mastodon/mastodon/issues/19954">intents/handler-style way to deal with this</a>.</p>
<h3>Challenge 2: Sometimes you just don’t see things</h3>
<p>A recurring theme with federation and Mastodon is around how your instance only knows about things it knows about. It doesn’t automatically know about every post across every Mastodon server online. This can lead to some unexpected behavior:</p>
<ul>
<li>
<p><strong>Profiles you visit may be empty at first.</strong> They won’t have any posts if your server has never encountered this account before (and no one else on your server has followed or interacted with the account). Following the account will start to get new posts from that account, but don’t expect it to instantly fill it up with every historical post from that account.</p>
</li>
<li>
<p><strong>Not all public replies to a post may be visible.</strong> This one is the most concerning. Your server may not know about all the replies to a post, and therefore you may only be seeing a slice of the conversation on a post. Simon Willison has a great dive into the issue <a href="https://fedi.simonwillison.net/@simon/109559268498004036">in this thread</a> on his personal instance.</p>
</li>
<li>
<p><strong>You may not be able to see a complete list of someone&#x27;s followers</strong>. Similar to the above, your server likely has a limited view into who follows that account.</p>
</li>
<li>
<p><strong>Boost and favorite counts may not be accurate.</strong> Same story here; your server only knows what it knows about. If you want to get a real understanding of a post&#x27;s true engagement, your Mastodon client may have an action in a menu for something like "open original post."</p>
</li>
</ul>
<p>So, how can you get your Mastodon server to know more? If you’re on a larger instance or tend to mainly communicate with people on the same server, you’re less likely to run into these issues. There’s not much of a fix aside from the admin adding a ton of relays to ingest as many posts from the fediverse as it can, but that’s not ideal for various reasons.</p>
<h3>Challenge 3: Moderation and incentives</h3>
<p>And one last challenge I see is typically listed as a good thing about Mastodon: moderation. I’m annoyed with Twitter because it seems like they are continually changing the rules, banning people arbitrarily, and I didn’t want my identity held hostage. Well, the exact same thing can happen on Mastodon and more.</p>
<p>How do you moderate a federated network? You leave it up to the instances to moderate themselves. You just have to trust the admins of each instance to do the right thing, and the idea is that by picking your instance, you’re picking a community you embrace and feel part of, and everyone will follow the established rules. And if you’re doing all that, you shouldn’t have an issue, right?</p>
<p>This quote from Noah Smith in his article <a href="https://noahpinion.substack.com/p/the-internet-wants-to-be-fragmented">The internet wants to be fragmented</a> sums up nicely why moderation is great:</p>
<blockquote>
<p>"<em>Community moderation works.</em> This was the overwhelming lesson of the early internet. It works because it mirrors the social interaction of real life, where social groups exclude people who don’t fit in. And it works because it distributes the task of policing the internet to a vast number of volunteers, who provide the free labor of keeping forums fun, because to them maintaining a community is a labor of love. And it works because if you don’t like the forum you’re in — if the mods are being too harsh, or if they’re being too lenient and the community has been taken over by trolls — you just walk away and find another forum."</p>
</blockquote>
<p>That seems fine, and if you don’t like it, you can find another instance or host your own. But what if you couldn’t move your account? If you don’t get along with your instance admin, it seems <a href="https://twitter.com/alexqgb/status/1594079081649184769">they can even block your move to another instance</a>.</p>
<p>Okay but that’s like the worst-case scenario, right? Yea, that’s true. But there’s one more unpleasant situation. Running a Mastodon instance is a non-trivial amount of work. There’s technical setup and regular maintenance to keep on top of, there are real costs associated with hosting, and there’s legal risk as well.</p>
<p>Since there are no real incentives to host and moderate a Mastodon instance, you could end up on a poorly run instance. If you’re not on a well-run instance, best case scenario, sometimes your server is a little slow or isn’t always running the latest software, but it is generally okay. The worst case scenario is that, uh, your server goes down permanently, along with your Mastodon identity and all your data.</p>
<p>All this to say, choosing your Mastodon server is an especially important task. One thing that would make this better is if Mastodon had a more streamlined way to be able to donate to Mastodon admins to pay for server costs. I imagine seeing some Stripe link in settings and being able to set up a small recurring donation.</p>
<h3>Here’s why I like Mastodon</h3>
<p>While those challenges complicate things, they don’t overshadow the brilliance of Mastodon and the protocol for me. One of those reasons is that it feels more intimate, just a small place with the people I follow. No one or thing unexpectedly forcibly getting injected into my home timeline.</p>
<p><strong>On Twitter, you have three groups of accounts: celebrities and other verified accounts, brands, and then just regular people. On Mastodon, you only have people</strong> (and with so many instances to choose from, no one can really squat on your desired username). No ads either. The Mastodon home timeline is always in reverse chronological order—not algorithmic or ranked like Twitter’s timeline is by default. This means your timeline is saner. It’s not filled with threads spewing the same nonsense that gets injected into your timeline by the algorithm. It’s not filled with ads.</p>
<p>And with the longer character limit, you can more easily converse with people or share your thoughts without losing much in translation or spending lots of time trying to reword things to fit logically in one or multiple posts.</p>
<p>Mastodon feels like the early days of Twitter, with people just sharing thoughts, not worrying about how to optimize for engagement. It feels more intimate, authentic, and close-knit. My only advice for those starting out on Mastodon is to boost posts you think others should see to help with discovery, and also, you can favorite your heart out knowing it doesn’t do unexpected things like injecting the post into others’ home timelines because there’s no algorithmic timeline.</p>
<p>As I mentioned earlier, Mastodon’s open-source software, open protocol, and strong API without limitation (as compared to Twitter) make it a dream for developers. I’ve been seeing this flurry of excitement from developers building Mastodon apps. I’m excited to see what else gets built on top of, or for, Mastodon and ActivityPub.</p>
<p>The challenge will then be how the Mastodon project and broader community deal with the huge influx of new users. Will they develop efficient product development processes to deal with the flood of feature requests, complaints, and associated chatter in a principled manner? Will there be enough people to push for great design?</p>
<p>So far, everything on Mastodon feels like a page out of early Twitter. Nothing bad about that; it’s easy for people to join and generally understand how things work. But shouldn’t it evolve to best embrace the unique affordances and constraints of Mastodon? What will it mean for future functionality to look, feel and act like the decentralized network it is? People designing for the official Mastodon project need to think less about Twitter and more about what it means to be Mastodon. Perhaps third-party Mastodon clients and forks can lead the way before they get adopted.</p>
<h3>An open web, owned by its users</h3>
<h3>Yes, another "bring back blogging and RSS"</h3>
<p>This is the part where I talk about my growing desire to have more control over, and own, my data and my online identity. I want to move away from relying too much on just a few large centralized tech companies when they control too much of my data. I think about worst-case scenarios. What happens if I get locked out of this account for a day, a week, for good? It’s with that mindset that I need more control, access to the raw data, and more.</p>
<p>That way of thinking is often a bit overkill and can lead you down a complex path (have you ever tried hosting your own email??), but 2023 is the year I begin to detach myself from large tech companies like Twitter and Google. And for the services I do rely on, I expect encryption. And it was nice to see Apple roll out iCloud Advanced Data Protection recently. I love Signal and ProtonMail. It gives me comfort knowing that even if my account was compromised, the attacker would also have to know a separate encryption key to get into my mailbox.</p>
<p>I’ve been running paulstamatiou.com for 17 years. First hosted from a Mac mini in my dorm room at Georgia Tech. Starting this site and continuing to maintain it has been one of the best things I’ve done. It gives me a space to tinker, write, share thoughts, show work, and publish photos.</p>
<p>I miss the days when if you wanted to have a space online, you had to make it yourself. Personal blogs were their own communities. The comments sections were helpful and thriving. They were hard to discover, but we got by. We had feed readers, blog rolls, Technorati, and trackbacks.</p>
<p>Every day, I would be excited to open my feed reader and see if anyone whose feed I subscribe to had posted anything new. Seeing that unread count badge on a favorite blog was like a little present.</p>
<p>In those days, you followed people. Sure there were a few big publications you might keep track of, but you didn’t really follow "developer blogs" or "design blogs." It was always just people’s personal blogs publishing whatever felt interesting to them. They had their own take and personality.</p>
<p>We’ve seemed to have lost a bit of that personality and authenticity. We’re living in a world where it often feels like everything is carefully curated and polished just so for engagement. This was well before we became far too accustomed to busy feeds, videos, threads, gamification, listicles... the constant need to be entertained and get a serotonin hit. Personal blogs offered a glimpse into the real lives and thoughts of their creators.</p>
<p>In recent years, we made way for the rise of personal newsletters. It was only after my inbox had become unmanageable from Substack and other newsletters that I started <a href="https://paulstamatiou.com/hello-rss/">using an RSS reader again</a>. A modern one that could also manage newsletters and declutter my inbox. But the type of content I long for is not there. (By the way: you can just add <code>.rss</code> to any Mastodon profile or search URL and get an RSS feed).</p>
<p>I’m hoping that the recent interest in Mastodon will get people to start thinking more about taking control of their data and online identity. Mastodon has a great shot at recreating that feeling of community that personal blogs used to have. It can be your own space.</p>
<p>I only ask that you don’t think of it as a Twitter replacement but as a new thing. A new way to communicate, connect and build communities. A decentralized product like Mastodon will have some learning curves, no doubt. But it’s a start. And it’s a start that’s not owned by a billionaire.</p>
<p>If you’ve read this far, thank you! You can follow me on Mastodon by copying my full username and pasting it into the search of your Mastodon website or app to find my profile and hit follow: <a href="https://stammy.design/@stammy">[object Object]</a></p>]]></description>
            <link>https://paulstamatiou.com/mastodon</link>
            <guid isPermaLink="true">https://paulstamatiou.com/mastodon</guid>
            <dc:creator><![CDATA[Paul Stamatiou]]></dc:creator>
            <pubDate>Thu, 05 Jan 2023 00:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Craft]]></title>
            <description><![CDATA[<p>After 10 years of working at large companies with thousands of employees, I recently joined a 10-person startup. It&#x27;s called <a href="https://a16z.com/2022/11/01/investing-in-rewind/">Rewind</a> and I am absolutely loving my new role for a lot of reasons. It&#x27;s a bit different from my previous roles: I’m a product designer but I also spend time building my designs in Xcode. I love having a hands-on route to directly affecting product quality.</p>
<p>Much of my career as a designer has led me to hold product and design quality in the highest regard. It&#x27;s not easy. I want to be proud of the things I ship and <a href="https://bryanhaggerty.com/blog/2012/11/proud_enough_to_put_your_name_on_it/">put my name on them</a> (<a href="https://www.folklore.org/StoryView.py?project=Macintosh&story=Signing_Party.txt&sortOrder=Sort+by+Date&topic=Apple+Spirit">see also</a>). That 10 year old post from Bryan Haggerty is still as true as ever:</p>
<blockquote>
<p>“With small teams, the output, whether it’s an app, web site or any other product, represents the people behind it and the tremendous amount of effort they expended to make it. And it’s common for those people to willingly put their name on it, <strong>taking accountability for what’s great and what needs to be improved.</strong>”</p>
</blockquote>
<p>I’ve worked on numerous projects with large teams where the work shipped felt like a string of excuses—a reflection of tight timelines, cut scope and endless constraints. It never feels great to ship something to real people that is not an accurate representation of the intent you and the team had.</p>
<p>As a designer I&#x27;m motivated not only by identifying and successfully solving problems for people through software, but also by the care, attention to detail and craft I&#x27;m able to put into it along with the team.</p>
<p>I want someone to use something I&#x27;ve created and feel that was intentional. That it not only had their exact needs in mind but went beyond to care about the details and have personality. <strong>This is a post about well-made, high-quality products and why shipping quality is hard.</strong></p>
<hr/>
<p>I’ve always been something of a hybrid designer and developer. I initially studied computer/electrical engineering when I went to college in 2004. Eventually I felt that was too far removed from the end user experience of the devices we use. I transitioned to a major that combined design and computer science. However, when I graduated I felt like I wasn’t great at either. I spent the 5 years after college working on several startups I cofounded before landing at Twitter in early 2013.</p>
<p>When I joined the Twitter design team I was designing in Photoshop. For things that demanded higher fidelity, I would dive into After Effects to make small UI videos—a far cry from the interactive mobile prototyping we take for granted today.</p>
<p>The next year I became immersed with interactive mobile prototyping. I fell in love with a Javascript animation library called Framer.js—it felt like a superpower. I could make fully interactive prototypes for web and mobile experiences that felt real (old examples <a href="https://paulstamatiou.com/twitter-video/">here</a> and <a href="https://paulstamatiou.com/work/">here</a>).</p>
<p>Prototyping got me a step closer to what the actual product would feel like. It was my interactive canvas for testing out ideas and concepts rapidly. Prototyping dramatically elevated my design process, helped me think through implementation details, interactions, motion, and communicate concepts.</p>
<p>Of course, while high-fidelity visual designs and a complete interactive prototype can help you communicate your concept and get people excited, it won&#x27;t help the final product get built.</p>
<p>For that you need a lot more. You need to make your case for what the problem or opportunity is—most often validated with at least directional data and/or research insights—and why your specific solution could work. You need to ensure it weaves into broader company initiatives as well as goals for your team and org. And you need a plan to get your product out there in a timely manner along with ways you&#x27;ll further learn and validate your approach. An executive team won&#x27;t be thrilled to hear you want to spend a year building something based solely on a hunch.</p>
<p>That&#x27;s where the challenge of building quality products starts to creep in. <strong>The constant tension of shipping faster versus shipping better.</strong> Falling into a cycle of "Ship, then iterate" is a trap. It ends up being more <em><strong>shiterate</strong></em>. Things happen and that "fast-follow" V1.1 release or V2.0 you had imagined probably won&#x27;t. There&#x27;s always a new shiny initiative, re-org or new leadership hire that throws a wrench into things and changes all plans. Don&#x27;t rely on a future release to clean up today&#x27;s mess.</p>
<p>Having spent many years going through this constant quality versus speed tug-of-war I focused a lot of time and energy on product strategy as part of my design process. I crafted a story about our customers to our teams and leaders. I wrote a ton of internal documents; product briefs, design briefs, customer problems, product opportunities, vision, et cetera. I spent time evangelizing efforts, working on decks to show where we could go, how we could get there and what it could unlock, while addressing the opportunity cost as well as challenges like built-up tech and design debt.</p>
<p>But even that doesn’t ensure that the thing you&#x27;ve designed will result in the high-quality shipped solution you envisioned. There are a lot of reasons why shipping well-crafted, quality products is hard, especially on a large team.</p>
<h3>What is quality?</h3>
<h3>And why is it so hard?</h3>
<p>I often use the word quality when referring to apps, products and services I hold in a high regard but another word that often comes up in this context is <em>craft</em>. Craft, as in something that is handcrafted where something someone spent a lot of time on and maybe even embedded their own personal touches and personality in it. Often something handcrafted feels more premium.</p>
<p>There’s a reason high-end car manufacturers boast about their handcrafted cars. Something so premium that an individual person spent time obsessing over the details. Some even prominently display a plaque on the engine with the <a href="https://turbo.paulstamatiou.com/uploads/2022/11/mercedes-amg-engine-plaque.webp">signature of the engineer</a> that built it. This goes back to that quote earlier about putting your name on something and taking accountability.</p>
<p>Quality and craft are not just words designers toss around when referring to some veneer of polish adorned on top of a product with superficial visual design tweaks and unnecessary, over-the-top animations.</p>
<p>Quality is all-encompassing.</p>
<ul>
<li>It’s accessibility so that everyone can use it.</li>
<li>It’s performance and ease of use so it respects the user’s time and helps them accomplish their tasks when they need.</li>
<li>It’s reliability so they can feel good about having this tool in their pocket for when they need it.</li>
<li>It&#x27;s durability with designs and components that can scale to withstand future needs and uses.</li>
<li>It’s well-considered.</li>
<li>It’s the feeling that a lot of time and care went into creating the product: that someone has already thought of you.</li>
<li>Of course, it can also be a bit extra and bring delight in unexpected places and important moments.</li>
</ul>
<p>Apple gave a talk about the qualities of great design where they interviewed people on their thoughts around quality:</p>
<img src="https://turbo.paulstamatiou.com/uploads/2022/11/apple-wwdc-quality.webp" alt="Apple WWDC Quality" />
<small><a href="https://developer.apple.com/videos/play/wwdc2018/801/">The Qualities of Great Design</a> - WWDC</small>
<p>Quality happens throughout the entire project whether you&#x27;re cognizant of it or not. It happens when identifying the customer problem to solve, designing a solution, validating it, building it, maintaining it, and even when you sunset the product. A focus on quality drives a way of working in which you dynamically either embrace constraints when you need to or challenge them when you see an opportunity.</p>
<p>People hire services not just based on what they can do but how it makes them feel.</p>
<p>Quality has a direct relationship to that. Quality products can take your users from "I&#x27;m merely using this thing to accomplish a task" to "this is something I <em>love</em> using and I&#x27;m telling everyone I know about it."</p>
<p>I’m writing this article in a macOS app called Ulysses right now. I love it because it’s quality software. It&#x27;s approachable, <em>actually</em> easy to use, fast, and I can personalize it to my taste.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2022/11/ulysses-app-paulstamatiou.webp" alt="Ulysses app for macOS" />
<p>It makes me feel good about the work I’m doing. I could have written it in a myriad of other text editors filled with bells and whistles but I chose Ulysses because I know I can rely on it to let me focus on what I’m trying to write. Quality products make me excited to use them.</p>
<p>If we all generally agree that quality is a good thing, then why aren’t there more high-quality apps and services out there? <strong>Because quality is hard.</strong></p>
<h3>What affects quality?</h3>
<p>Lots of things can affect the quality of your product, especially on large teams, including culture, incentives, skills and tools. Here’s just a few that are top of mind:</p>
<ul>
<li>
<p><strong>Leadership, organizational support and incentives.</strong> Does the organization care about quality? What does quality mean to them? How does it tie into the career ladder, promotions and prioritization frameworks? Do they focus more on execution speed over quality?</p>
<p>Is quality baked into the normal product development process, or is it often relegated to low priority "polish" tickets that pile up. Will leadership pause a launch if the quality is below their bar? What is that bar?</p>
<p>If support for quality does not come from the top, it&#x27;s far too easy for ICs to skirt over issues and pay a little less attention to details they think their reporting chain won&#x27;t notice.</p>
<p>Do different roles (like engineering, product, design) have different motivations for getting their work done? This, again, ladders up to what the org thinks about quality.</p>
</li>
<li>
<p><strong>Culture around quality.</strong> To maintain a shared, company-wide understanding of the company&#x27;s specific stance is on quality, how does quality get rewarded, celebrated and prioritized? Is there a process in place for delaying a release and having a retro when the quality bar slips? Who decides when quality has slipped? Who&#x27;s accountable for addressing it?</p>
<p>Does everything need to have the same level of quality at the company? Are there certain things that need more or less? Unclear alignment around what deserves quality amongst teams can lead to issues.</p>
</li>
<li>
<p><strong>Trouble identifying issues.</strong> Do you have the right people with the right skills and motivations to flag quality-related issues? Do they have the right tools?</p>
<p>Focusing on quality is often thankless work. Tons of time can go into rigorously testing builds, logging issues, providing feedback and coming up with solutions given the constraints.</p>
<p>Does everyone have an eye and the time for design QA? For the items that are more visual/motion related, are the designers skilled enough at visual design to even know there are issues or be motivated enough to address them? Are there other designers they can rely on on the team for pixel-level details if that’s not their strength?</p>
</li>
<li>
<p><strong>Poor ticket/engineer fit.</strong> The onus is not just on designers to help identify and document issues to be addressed. What happens when a particular engineer picks up the next ticket and it involves a specific set of knowledge they may not have, for example like knowing about the nuances of animating collection views on iOS.</p>
<p>Does the engineering manager wait until there&#x27;s an engineer better suited to tackle this ticket? Does the assigned engineer compromise with the designer on a solution if this is too intricate to tackle for them? What resources does that engineer have at their disposal?</p>
</li>
<li>
<p><strong>Inadequate tooling for effective design/engineer pairing.</strong> Back when a designer and engineer might have worked in the same office with each other, they could sit down to iterate on a new build. They could easily try 10 or more different values for a specific animation, build and test together over the course of 30 minutes.</p>
<p>Contrast that with the new way of working remotely. The designer may feel less comfortable going back and forth suggesting small tweaks to engineering builds, so they only suggest a few iterations so as to not feel like they’re annoying the engineer too much. And these iterations will be less refined because the pairing iteration speed is so much slower. Do you send over ipa/apk files? Does the designer have the dev environment setup on their machine and pull the branch to build and test themselves? Or, worse, does the designer just have to wait a day or two to be able to provide feedback on a build when the code is reviewed and merged into an internal dogfood build they can easily access.</p>
<p>Relying on screenshots and video clips sent over Slack can only get you so far. Perhaps in the future there will be tools for this. I&#x27;d love something like high-fps, low-latency interactive VNC sessions for remotely controlling someone else&#x27;s Xcode simulator for example.</p>
</li>
<li>
<p><strong>Liberal use of "MVP" or "it&#x27;s just an experiment".</strong> Does the team use those terms to skirt around typical quality standards and ship something subpar? Does everything worked on, even experiments, demand the same care as a more mainstream release that goes out to all users?</p>
<p>That&#x27;s a slippery slope because it&#x27;s all too easy to simply ramp up that experiment to 100% of your users if it performs well, without addressing quality issues that were neglected prior to shipping to that initial set of users.</p>
<p>No one wants a slice of cake that is just a piece of the bottom layer. You need to have a taste of each layer with each bite, including the icing. So even if it’s not your entire vision, it has all the right pieces involved. Ditch the term MVP and use <a href="https://blog.asmartbear.com/slc.html">SLC (Simple, Lovable, Complete)</a>.</p>
</li>
</ul>
<p>Most companies struggle to prioritize small quality and “fit & finish” design issues. On their own, these tickets seem like they&#x27;ll have remarkably low impact for the product. How will fixing the alignment of this button help us have a better launch, higher customer retention or a more stable app? However, <strong>compounding effects come into play</strong> with this kind of work. One or two of them won’t make a difference. But when you’ve fixed a dozen or so? It’s noticeable.</p>
<p>Building that understanding into the way you work is key. But it&#x27;s not the singular solution. It still goes back to many of points above. Does your team have the skills and incentives to identify and adequately fix those issues? Does the organization continually reinforce and celebrate work that ladders up to quality, craft and great design?</p>
<p>I didn’t write this section aiming to get to some sort of grand revelation about how you can build great software with one simple trick. <strong>Quality is hard.</strong></p>
<p>I’m not saying designers, PMs and engineers should be holding up their projects for months to “get it right”. I&#x27;m saying that teams should be working in a way where everything is considered and there&#x27;s a framework for identifying, discussing and prioritizing quality-related issues so that quality is a bit less of a sisyphian task.</p>
<blockquote>
<p>“But the desire to ship quickly was counterbalanced by a demanding, comprehensive perfectionism. Most commercial projects are driven by commercial values, where the goal is to maximize profits by outperforming your competition. In contrast, the Macintosh was driven more by artistic values, oblivious to competition, where the goal was to be transcendently brilliant and insanely great.”</p>
<p>—<a href="https://www.folklore.org/StoryView.py?project=Macintosh&story=The_Macintosh_Spirit.txt">The Macintosh Spirit</a></p>
</blockquote>
<h3>Quality is a way of working</h3>
<h3>It&#x27;s not something you&#x27;ll get to later</h3>
<p>We&#x27;ve identified that quality is hard and that it&#x27;s tied to a whole slew of things from culture and leadership to experience and tools. Quality is the way you work. Focusing on quality doesn&#x27;t have to mean that suddenly your project scope has become bloated with a slew of tasks that will take 25% longer to complete. It can be prioritizing more <em>complete, well-considered</em> chunks of functionality (goes back to the SLC concept above).</p>
<p>What doesn&#x27;t work in my experience is marking tickets you can&#x27;t get to before your deadline as design debt, tech debt or polish to tackle later. Polish is an easy word to equate to design tickets but it&#x27;s an especially poor choice as most people tend to think it&#x27;s defined as optional, obsessive and unnecessary details.</p>
<p>I&#x27;ve been immersed in thinking about and working on quality for years at large companies. It&#x27;s insanely hard to change a company&#x27;s perception of quality and process, but here are a few things that help:</p>
<h3>Balance long-term and short-term design</h3>
<p>Build a working style that always pairs thinking about the long-term design direction of your surface area along with the short-term. By only thinking short-term it&#x27;s far too easy to design or build yourself into a corner, only too realize you&#x27;ve built a cluttered UI or relied on complicated interactions and flows. Doing so also helps you become a strong ally to your product partners so you can craft a story of where you see the product going and how it could potentially best address customer needs in the future.</p>
<p>I used to think doing long-term (so-called vision work) was bogus. Designers would get assigned to these "vision projects" by various executives, spend months on some explorations and a deck, only for the work to be archived in some internal wiki, never to be touched again. They tended to be run only by designers, not informing or consulting with adjacent roles and teams along the way.</p>
<p>As much as designers want to go off in a corner and come back with magical designs and a roadmap, this really needs to be a team effort, even if your stakeholders are more in the "inform" role of the DACI framework.</p>
<h3>Close the gap between design and engineering</h3>
<p>Bring design and engineering closer. There’s still a ton of onus on the designer to help illustrate and share their vision with their team. Sometimes designers are limited by what they can make with the tools at their disposal and their skills. If they can’t design or prototype at least a sliver of what’s in their head, how can they expect their engineering counterparts to not only build it but build it well? It may even limit the types of design solutions you explore if you&#x27;re unsure how to even communicate it. However, by building stronger relationships with your engineering coworkers you can try to bridge that gap more effectively.</p>
<p>For me, Figma is where initial hunches live; a starting point. Not final designs. it&#x27;s not until I start building and really using it that I get more signal to understand what aspects of the design feel good and which aspects don&#x27;t. That&#x27;s a big reason why I dislike teams that treat their visual designs as complete and "ready for handoff." Please, never treat design as something you just handoff to engineers. That&#x27;s a great way to devalue the contributions of the engineers on your team and lead to a worse product. Treat it more like a conversation between design and engineering.</p>
<p>Some larger teams have dedicated prototyper or design/UI engineering roles. That&#x27;s one way to help bridge this gap, though for me they always felt one-step removed from product design and I wanted to also be leading the design in addition to coming up with the final solutions. If you have these roles, it&#x27;s important to not just assign them from project to project merely to prototype something a team needs for a research study or other short-term need. Instead, have them paired up with design and research for 100% of the project.</p>
<p>It&#x27;s also important as a designer to know when to push on something and maintain your quality bar and when to compromise. That&#x27;s your superpower. Everyone will hate working with you if you hold a high quality bar but don&#x27;t know how to work within the context of your business goals and customer needs. Getting as close to the technical side will help you. Here&#x27;s a good post on this topic from an engineer&#x27;s perspective: <a href="https://www.joshwcomeau.com/career/effective-collaboration/">Effective Collaboration with Product and Design</a>.</p>
<p>Then there&#x27;s tooling that can help improve speed of iteration; making it faster for designers to receive and test builds from engineers (as mentioned in the previous section). And finally, provide resources for engineers to learn more of the intricacies of front-end development, UI and motion frameworks. This may be more important for companies that tend to hire more full-stack engineering roles.</p>
<p>Of course, all of this gets a lot easier if you&#x27;re a designer who can also code your designs.</p>
<h3>Determine what quality means for your team & set your quality bar</h3>
<p>Depending on the company, industry and team, quality will mean different things. For one product and customer type it may mean a huge focus on reliability and speed while for another it may be a focus on delight and attention to detail.</p>
<p>A shared understanding of what types of work meets and what type of work doesn&#x27;t meet your quality bar, along with executive support, can help with prioritization. Doing so can help realize the compounding effects of smaller quality and design tickets.</p>
<p>This entails understanding how a user-facing visual refinement is a very different type of ticket than something like a performance bug or crasher. If you only have one type of work queue, it&#x27;s very easy to only prioritize the bugs and crashers. But when do the other types of quality tickets get prioritized? Try to dedicate a certain amount of time to each type of work for each sprint. This goes back to the SLC concept: you want your slice of cake to be vertical so you can taste all the layers, including the icing (yes, I love this silly analogy).</p>
<h3>Don&#x27;t always jump to using existing patterns</h3>
<p>This is probably the most controversial one. In the design industry there&#x27;s a remarkable push behind design systems. They have a myriad of benefits including speeding up design and development time, making it easier to maintain accessibility, as well as evolve and maintain large surface areas in your product. But if design systems are not run well, they can hold you back.</p>
<p>Poorly run design systems can preclude valid design explorations in pursuit of consistency and efficiency; just using what&#x27;s already there.</p>
<p>For brand new products, don&#x27;t to be too eager to start on a design system. You often don&#x27;t know what this thing is yet. You don&#x27;t know where the product is going, what needs to scale, what the customer needs are, how they&#x27;ll react to your initial version or what the personality of the product will be.</p>
<p>But this familiarity with existing systems can get in the way of helping you tackle new kinds of problems. You may prematurely bucket it into a problem you&#x27;ve seen before. Design systems are just one of the tools at your disposal. Applying your design systems thinking (or any other patterns you&#x27;ve worked with before for that matter) all too eagerly may prevent you from noticing the obvious. That maybe there&#x27;s a different way of thinking about the problem at hand. Apple touches on this a bit in this video about <a href="https://developer.apple.com/videos/play/wwdc2018/802/">intentional design</a>.</p>
<p>A related tool I like to employ sometimes, especially to break out of my own personal design aesthetic and tendencies, is to ask myself, how would [another company] design this? I might think to myself "Airbnb loves to have these huge headers, bold colors, dynamic cards and sheets, so they may approach it like this." Then I&#x27;d mock that up.. and do the same with other companies. I may hate it, but it will get me thinking.</p>
<h3>Sunset or re-evaluate old functionality</h3>
<p>Incentivize and commit to sunsetting features that are no longer your core focus, have low usage, or are otherwise detrimental to your product. If you work on a product with millions of users, even low usage things will be sizable and may have secondary effects that are hard to gauge. This is hard, thankless work. It requires support from leadership to allow a team to focus on removing something instead of spending that time that could more directly move tangible metrics.</p>
<p>But without this rigor, your product could all too easily become cluttered, slow and become harder to maintain over the years.</p>
<h3>Use what you&#x27;ve built before you ship</h3>
<p>I&#x27;ve seen it happen all too often. You&#x27;re working on a project. You build a prototype and work with a researcher to get some initial qualitative feedback or you ship a small experiment to gather data. By the time the research insights have been finalized or the experiment data has had enough time to account for novelty, you don&#x27;t have much time left to explore significant refinements or alternative design directions. Your team is already on the hook to ship this before the end of the quarter or has tight timelines to get this code merged before the biweekly deadline to ship to Apple. So you end up compromising with a less-than-ideal refinement, even though you don&#x27;t think it&#x27;s the solution your users really deserve.</p>
<p>Always leave adequate time after gathering new insights to not only design refinements, but build them and live with them for a bit first. It&#x27;s too easy to compromise on quality in the face of existing timelines.</p>
<h3>Joining Rewind</h3>
<h3>Why going to a startup is the perfect fit for me</h3>
<p>Earlier this year I decided to leave my job, focus on my wedding and take a few months off. I had a lot of time to think about what I wanted to work on next. I wasn&#x27;t sure if I wanted to join another large company, a startup, or transition to contracting with a few companies.</p>
<p>One thing was clear though. I wanted a different kind of design challenge. Designing for mobile had started to feel boring. It felt so repetitive. The same constraints. It felt like I was just going around employing the same few patterns, especially when working on larger teams less interested in taking risks and trying new things.</p>
<p>It would be a bonus if I could find a company where I could more readily influence product quality by diving into the codebase myself. I had a strong desire for interesting work with a great team where I could be proud of what we built together. That&#x27;s what we all want right?</p>
<p>Dan Siroker happened to reach out to me around this time. Dan and I had crossed paths a decade ago in Y Combinator when he was starting Optimizely. We caught up and Dan showed me what he had been working on, complete with a live demo of Rewind. I was blown away by the ambition and concept. I immediately grokked it.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2022/11/rewind-app.webp" alt="Rewind for macOS" />
<p>Rewind is the search engine for your life. It&#x27;s a macOS app that fully utilizes the capabilities of Apple Silicon and macOS Ventura to record everything you see, analyze it and make it searchable in real-time. All while being private by design—everything is stored locally on your machine.</p>
<p>Rewind helps you out in those situations when you&#x27;re racking your brain try to remember where you saw something. Can&#x27;t find that tweet you know you saw once? Or wish you could go back 15 seconds to recover that long performance review you were writing before your browser crashed? You can search or rewind time. Once you&#x27;ve found what you&#x27;re looking for you can even copy text from it.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2022/11/rewind-app-1.webp" alt="Rewind app screenshot 1" width="3000" height="2147" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2022/11/rewind-app-2.webp" alt="Rewind app screenshot 2" width="3000" height="2147" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2022/11/rewind-app-3.webp" alt="Rewind app screenshot 3" width="3000" height="2147" />
<p>It&#x27;s the exact type of design challenge I was looking for. First, it&#x27;s a full-screen immersive app with no peers like it. There&#x27;s no playbook or existing design patterns for how to design something like this. Second, there&#x27;s a ton of privacy implications to ensure people feel safe using Rewind and know that they&#x27;re in control. And finally, since there&#x27;s no product quite like this, there&#x27;s a lot of hard product design and research iteration on the journey to find our specific product-market fit.</p>
<p>All this to say that Rewind was exactly the kind of team and company I was looking for. The product has the potential to change how we interact with computers.</p>
<p><strong>How does joining a startup relate to craft and product quality?</strong> Isn&#x27;t it harder for a small company to ship well-designed, high-quality software? Aren&#x27;t most startups busy scrambling to find PMF, scaling infra and putting out fires?</p>
<p>There&#x27;s no debating one aspect of startups compared to large companies with thousands of employees: startups are dramatically faster. Faster to make decisions, plan and build. You can talk about something in the morning then design and build it the same day. No more waiting until the next quarter.</p>
<p>But the main reason why I think it&#x27;s easier to influence quality on a smaller team is that I&#x27;m able to have a more general design role. I can be <a href="http://www.paulgraham.com/relres.html">relentlessly resourceful</a> and put the full extent of both my design and engineering skills to use. And the best unintended side-effect? I&#x27;m also learning more on the coding side as the talented engineers I work with provide tips and feedback on my code reviews.</p>
<p>I&#x27;ve only been at Rewind for a few months but this has been the exact kind of role I&#x27;ve been looking for for the last decade and I&#x27;m confident we&#x27;re going to build some great stuff.</p>
<hr/>
<h3>Quality is hard</h3>
<p>With the right team culture, process, tool, education, and incentives, achieving a higher level of product quality <em>should</em> be more attainable without dramatically impacting speed of execution. I&#x27;m not saying it&#x27;s easy. Quality will always be hard, but don&#x27;t you want to make something great?</p>]]></description>
            <link>https://paulstamatiou.com/craft</link>
            <guid isPermaLink="true">https://paulstamatiou.com/craft</guid>
            <dc:creator><![CDATA[Paul Stamatiou]]></dc:creator>
            <pubDate>Mon, 14 Nov 2022 00:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Revisiting the iPod]]></title>
            <description><![CDATA[<img src="https://turbo.paulstamatiou.com/uploads/2022/08/copyright-paulstamatiou_com-DSC05910-2000.jpg" alt="Apple iPod" />
<p>1,000 songs in your pocket.</p>
<p>You’ve probably heard that iconic marketing slogan before even if you never had an original iPod. Apple referred to the iPod as a "breakthrough digital device" when they announced it. The first iPod came at a time when the portable audio player landscape was.. nomadic (pun intended) at best.</p>
<p>MP3 players were already around when the iPod came out in 2001. Sales of early MP3 players were growing but they all had key limitations. You had to choose whether you wanted a smaller, flash memory player with extremely limited storage or a larger hard-drive based player.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2022/08/portable-audio-players-in-2000.jpg" alt="Various portable music players in ~2000" />
<small>Various portable MP3 and MP3 CD players in the early 2000s. Few were usable with just one hand on the go.</small>
<p>None of them were easy to use or elegant. They were often cluttered with buttons, had subpar software and were hard to navigate. There were also other options like MP3 CD Players and Sony MiniDisc players (I loved my <a href="https://www.minidisc.org/part_Sony_MZ-R70.html">MZ-R70</a>).</p>
<p><strong>The iPod was different.</strong> It was a sleek, shiny stainless steel and white device the size of a deck of cards. Its stellar industrial design turned heads. This was not just an audio player you used to play music. It said something about you the same way using a Mac vs a PC said something about you at the time. You were different; maybe a creative even. You valued well-crafted products.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2022/08/ipod-launch-graphic.png" alt="iPod launch graphic" />
<p>The iPod was a noteworthy device for a few reasons:</p>
<ul>
<li><strong>Size + Storage:</strong> While there were other devices like the Creative Nomad Jukebox and Archos Jukebox with 6GB drives, they were almost the size of CD players. With the iPod you didn&#x27;t have to choose between portability and storage. This was made possible by the iPod&#x27;s 1.8-inch hard drive, something Apple&#x27;s head of engineering first discovered from Toshiba while on a trip to Japan. Other players used traditional 2.5" notebook hard drives.</li>
<li><strong>Speed:</strong> The iPod used FireWire 400 instead of much slower USB 1.1 like competitive devices used at the time. You could load a CD onto your iPod in 10 seconds; about 30 times faster than other devices.</li>
<li><strong>Scroll wheel</strong>: This usefulness and simplicity of this cannot be overstated. I&#x27;ll dive into it more later.</li>
<li><strong>Elegant industrial design:</strong> As mentioned above, this thing is beautiful. Today we&#x27;d refer to it as a brick.. but it&#x27;s still a shiny brick.</li>
<li><strong>Anti-skip protection:</strong> The downside with hard-drive based mp3 players is they would skip when moved around. The iPod had 20 minutes of anti-skip protection thanks to its built-in 32MB flash memory buffer. This also had the benefit of increasing battery life to 10 hours by limiting how often the hard drive needs to spin up.</li>
<li><strong>iTunes + Auto-sync + Playlists:</strong> Apple made sure to make it known that the iPod with iTunes was the first "complete and seamless MP3 music solution." Using iTunes to manage your music and automatically sync it with your iPod was a dream compared to the clunky software required for other MP3 players. Notably, iTunes made it easy to create playlists and the iPod made them easy to play.</li>
<li><strong>Large backlit display:</strong> Featuring an LED-backlit LCD display with 160x128 resolution, the iPod could display six lines of text and song details at a glance.</li>
<li><strong>CD-quality sound:</strong> While it wasn&#x27;t a huge feature of the iPod, Apple boasted that the included headphones featured Neodymium transducer magnets to help you get enhanced frequency response to get the most out of the high-bitrate songs.</li>
<li><strong>White headphones</strong>: We expect it now with Apple devices, but at the time every other device came with black headphones and a black cord. Apple knew the iPod would live in your pocket and they needed a way to signal that you had one (and of course white to match the iPod itself). The white cord and earbuds became so popular Apple leaned into them for a whole <a href="https://www.youtube.com/watch?v=rgSQsu0yeH0">series of iPod dancing "silhouette" commercials</a>.</li>
</ul>
<img src="https://turbo.paulstamatiou.com/uploads/2022/08/copyright-paulstamatiou_com-DSC05925-3000.jpg" alt="Apple iPod" width="3000" height="2216" />
<p>All of these things combined made the iPod something the industry had to take note of. It wasn’t the most storage you could get in an MP3 player at the time<sup><a rel="footnote" href="#footnote-1" id="r1">1</a></sup>, it wasn&#x27;t the first MP3 player and it definitely was not the cheapest with it&#x27;s $399 price point at launch. But it was elegant, easy to use and when paired with iTunes, it was the complete package.</p>
<p>Using the iPod still wasn&#x27;t easy by today&#x27;s standards. First off, you had to have your own music library of MP3 files on your computer. The iTunes Music Store had not come out yet, nor were there any music streaming subscription services yet. So either you purchased them on some other website, pirated them from Napster, BitTorrent, Scour, IRC, Kazaa, LimeWire and their ilk or ripped them from a CD. Then you had to connect your iPod to your computer, fire up iTunes, sync your music, then disconnect it before you could play it.</p>
<p>But it was a different time. Managing your own music library was a burden to be proud of. People would boast about how many songs and gigabytes their library consumed and how they organized it. They were proud of the work they put into their libraries and cleaning up their audio file ID3 tags and customizing their WinAmp player.</p>
<p>Music piracy was an especially hot topic at the time. The iPod included no form of DRM and received some criticism that the iPod would only proliferate piracy. Anyone remember Apple&#x27;s <a href="https://www.youtube.com/watch?v=pleybGLgaEc">"Rip. Mix. Burn." ad campaign</a>? They showed the ease of ripping music to your Mac from CDs you owned. Apple also packaged the iPod itself with a sleeve that clearly said "Don&#x27;t steal music." on it.</p>
<p>Some industry critics lamented that Apple even bothered to enter the consumer electronics space; a space where products traditionally came with lower profit margins and stiff competition. The iPod was also Mac-only at launch. Would this turn people away or convince them to get a Mac? Eventually this was a non-issue as Apple quickly began supporting Windows PCs.</p>
<p>Here&#x27;s the iPod announcement in 2001:</p>

    <iframe width="560" height="315" src="https://www.youtube.com/embed/Mc_FiHTITHE?start=1279"
    frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
    allowfullscreen></iframe>
  
<h3>Design</h3>
<p>While clear in hindsight, the iPod&#x27;s scroll wheel<sup><a rel="footnote" href="#footnote-2" id="r2">2</a></sup> was core to the success of the iPod. It flawlessly solved the problem of scrolling long lists of songs, adjusting volume and navigating menus on a small display that lacked touch capabilities. Combined with audible click feedback, it was a breeze to use.</p>
<p>In particular, it was easy to use with <em>one hand</em>. Not many MP3 players at the time were. You could raise the volume, skip a song, scrub through a song or navigate menus easily—even without looking at the screen.</p>
<p>In addition, when navigating menus there was a simple horizontal animation to help you understand whether you were drilling into or out of the menu. This was something iPhone OS 1 (it wasn&#x27;t called iOS until iOS 4) ended up doing as well when it came out years later.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2022/08/copyright-paulstamatiou_com-DSC05912-3000.jpg" alt="iPod close-up" width="2000" height="1463" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2022/08/copyright-paulstamatiou_com-DSC05883-3000.jpg" alt="iPod side view" width="2000" height="1059" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2022/08/copyright-paulstamatiou_com-DSC05917-3000.jpg" alt="iPod front view" width="2000" height="1462" />
<p>The iPod wasn&#x27;t the first time a portable device had a control like the scroll wheel. For years, Sony had some variation of their—failed if you ask me—"jog dial" on devices like PDAs. However, it always felt like some afterthought bolted to the side of their devices; not nearly as precise or quick to use. And of course, Apple got some inspiration from the B&O BeoCom phone.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2022/08/ipod-inspiration-braun-beocom.jpg" alt="iPod inspiration: Braun T3 transistor radio and Bang & Olufsen BeoCom 6000 phone" />
<small>Apple was inspired by the form of the 1958 Braun T3 transistor radio and the function of the 1998 Bang & Olufsen BeoCom 6000 phone, which utilized a wheel to provide quick access to phone book contacts and provided audible feedback while scrolling.</small>
<p>While iPods are long gone and all iOS devices are touch-screen now, some of what Apple learned with the scroll and click wheel evolved into the digital crown found on the Apple Watch.</p>
<p>It&#x27;s hard to imagine today what using an iPod in the early 2000s truly felt like. It was a dedicated device, singularly focused on helping you do one thing—play your favorite music—and do it well. It didn&#x27;t need to multitask or have any other complexity to function. It was simple, elegant and polished device. We don&#x27;t really have things like that today. Every mobile device is meant to be flexible, multitask and do just about anything for you, lending them to be more like a jack of all trades, master of none.</p>
<h3>Finding an iPod</h3>
<p>I have always admired the first iPod.<sup><a rel="footnote" href="#footnote-3" id="r3">3</a></sup> In 2002 I purchased the second-generation 10GB iPod. I was in the middle of high school and that was a hefty purchase for me.</p>
<p>The second-generation iPod was nearly identical to the first-generation iPod except for more storage options (10GB and 20GB) and minor physical changes (notably, a touch-sensitive wheel replaced the mechanical scroll wheel, which was prone to getting dirty and requiring cleaning).</p>
<p>I eventually dropped that iPod with headphones plugged in and it broke the headphone jack. I opened it up, soldered it back on and unfortunately sold it. I’ve missed it ever since.</p>
<p>Earlier this year I began my search for a second-generation iPod like the one I had. I thought about looking for a first-generation but honestly I did not like how they had a piece of white plastic near the ports instead of the metal backing and was concerned about the high probability of the mechnical scroll wheel having issues.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2022/08/copyright-paulstamatiou_com-DSC05881-3000.jpg" alt="My second-generation 20GB iPod" width="2000" height="1376" />
<p>If you decide to do the same<sup><a rel="footnote" href="#footnote-4" id="r4">4</a></sup>, I can offer a few suggestions. First, we are talking about a 20 year old device (older if you opt for a first-gen) so you should be concerned about the state of the battery and hard drive. It&#x27;s quite common to find people on eBay selling iPods where they&#x27;ve already replaced the battery, so that might be of interest if you don&#x27;t want to do the work yourself or have to deal with it later.</p>
<p>Of course, the vast majority of the early iPods you see for sale will have tons of scratches and maybe even some dings. That&#x27;s to be expected for such an old device, unless you plan on spending much more on a near-mint model; I even saw one selling a never-opened, sealed box iPod for $10k! However, since the front of the iPod is just plastic, a devoted owner can find specific polishing compound and significantly restore the faceplate to its former glory. It won&#x27;t be perfect (at specific angles you may still be able to see the original scratches) but you likely would not be able to tell from eBay pictures.</p>
<p>After some months of casual searching I finally found one on eBay in good condition with a newly replaced battery that wasn’t outrageously priced. I paid about $190 including shipping.</p>
<h3>Connecting and using the iPod</h3>
<p>A few days later my <a href="https://twitter.com/stammy/status/1549814701378490368?s=21&t=yaSATtU4zxfZqg8xuNvt_Q">new-to-me iPod arrived</a>!</p>

<blockquote>A Tweet embed was not displayed. Read this article in a browser to see it as intended.</blockquote>
<p>Would I even be able to connect this FireWire iPod to my modern M1-based MacBook Pro running macOS 12? Not too long ago Apple Music (née iTunes) stopped syncing iOS devices and that functionality was moved to the macOS Finder itself.</p>
<p>All I needed to do was find a way to connect FireWire 400 to Thunderbolt 3. This took quite a few adapters and dongles:</p>
<ul>
<li>Thunderbolt 3 to Thunderbolt 2</li>
<li>Thunderbolt 2 to FireWire 800</li>
<li>FireWire 800 to FireWire 400 (couldn’t find an Apple adapter, got one from <a href="https://amzn.to/3C2FoB5">elago</a>)</li>
<li>FireWire 400 6-pin to 6-pin Apple cable</li>
</ul>
<p>These dongles definitely add up in cost, though I got at least one of them used on eBay. In total, I paid just under $90 for all of these. I had another FireWire cable that would have worked but I was seeking an authentic Apple cable. All-in this iPod setup cost me about $280. Worth it? Absolutely.</p>
<p>Fortunately, it worked flawlessly after I connected everything. After a brief moment the iPod showed a "Do not disconnect" message and the Finder app in macOS displayed the iPod: both as an iPod and as a connected hard drive.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2022/08/copyright-paulstamatiou_com-DSC05941-2000.jpg" alt="iPod connected to my Mac with FW400" width="2000" height="1333" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2022/08/copyright-paulstamatiou_com-macOS-ipod-finder-syncing.png" alt="MacOS Finder connected to a 2nd generation iPod" width="2000" height="1463" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2022/08/copyright-paulstamatiou_com-macOS-ipod-finder-podcasts.png" alt="MacOS Finder connected to a 2nd generation iPod" width="2000" height="1463" />
<small>iPod connected to my Mac with FireWire 400 and accessed via Finder.</small>
<p>Selecting the iPod in Finder, you have the ability to sync music, podcasts and more. It&#x27;s pretty basic and just loads up audio files it detects from your main Apple Music or Podcasts apps. Of course these are only for actual files you have; not for any music from Apple Music&#x27;s streaming service for example. I selected a few podcasts and synced them. A few moments later I was listening to them on the iPod.</p>
<p>After syncing was complete, I ejected the iPod from Finder and removed the FireWire cable.</p>
<p>It took a moment to remember how to turn on the iPod. I had to turn off the Hold switch and press a button to wake it up. Then I navigated some menus to find a podcast to play. Scrolling line by line with the scroll wheel with its audible feedback was so satisfying. <strong>All the nostalgia came flooding back.</strong></p>
<p>Then I heard the tiny 1.8-inch hard drive whir to life. I can&#x27;t remember the last time I used a device with a spinning hard drive like this after so many years of using devices with SSDs. Though, at the same time I was a little bit paranoid about using a portable device like this with a spinning disk that felt so delicate.</p>
<p>Of course there’s no Bluetooth with the iPod so I found my AirPods Max 3.5” minijack to Lightning cable to connect them:</p>
<img src="https://turbo.paulstamatiou.com/uploads/2022/08/copyright-paulstamatiou_com-DSC05929-2000.jpg" alt="AirPods Max connected to an iPod" />
<small>AirPods Max, meet iPod.</small>
<h3>Impact</h3>
<p>There&#x27;s no need to state how influential the iPod went on to become: for Apple, for the industry, for pop culture and more. The <a href="https://www.moma.org/collection/works/89465">first iPod is even in the Museum of Modern Art</a> now. Some 450 million iPod devices have been sold.</p>
<p><a href="https://www.apple.com/newsroom/2003/04/28Apple-Launches-the-iTunes-Music-Store/">Apple unveiled the iTunes Music Store</a> about 1.5 years after the first iPod. It became dead simple to select a 128kpbs AAC song from their collection of 200,000 songs (today it&#x27;s 43 million) at launch, pay 99 cents to download it and then sync with your iPod to have on the go.</p>
<p>The easiest way to fight piracy was with convenience and Apple really showed how powerful a complete package could be: elegant portable audio device, great music library software and a robust integrated music store.</p>
<p>The iPod wasn&#x27;t the first MP3 player but it&#x27;s impeccable industrial design, novel software and overall execution made it iconic.</p>
<h3>What&#x27;s next?</h3>
<p>There&#x27;s a lot of other interesting early Apple devices<sup><a rel="footnote" href="#footnote-3" id="r3">3</a></sup> that I&#x27;d love to collect if I had the space but this iPod was the perfect start. I&#x27;m also a fan of the first-generation iPod Nano. If you&#x27;re looking to get a taste of iPod nostalgia that might be an easy place to start. It was flash-based and had a USB connection.</p>
<p>Though I&#x27;m really curious about the tiny <a href="https://twitter.com/Stammy/status/1552318317532254211">third-generation iPod Shuffle</a>. It was poorly received due to its over-minimalism and lack of controls on device (Apple pushed the use of remote buttons on the headphones cord along with VoiceOver navigation).</p>

    <iframe width="560" height="315" src="https://www.youtube.com/embed/mE_bDNaYAr8"
    frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
    allowfullscreen></iframe>
  
<br><br><br><hr><br><h3>Footnotes</h3><p><a href="#r1">1</a><!-- --> A now-infamous comment about the iPod at launch was on the popular site Slashdot: “No wireless. Less space than a Nomad. Lame.”</p><p><a href="#r2">2</a><!-- --> The first-gen iPod had a mechanical scroll wheel while the 2nd-gen had a touch-sensitive scroll wheel. Later iPod generations called it the <!-- --><a href="https://en.wikipedia.org/wiki/IPod_click_wheel">click wheel</a><!-- --> when the menu/skip/etc buttons were merged into the wheel itself.</p><p><a href="#r3">3</a><!-- --> In addition to most early Apple products, I&#x27;d love to own a Macintosh Centris 650, Apple ][, Macintosh Color Classic, Macintosh SE, G4 Cube, iMac G4, QuickSilver PowerMac G4, PowerMac G4 MDD, Clamshell iBook G3 laptop, 12-inch and 15-inch Titanium PowerBook, eMac, iMac G3... the list goes on. I have fond memories of using several of these machines many years back.</p><p><a href="#r4">4</a><!-- --> There&#x27;s a <!-- --><a href="https://www.wired.com/story/ipod-modders/">whole community around iPod modding</a><!-- -->. People love to convert them to use SSDs instead of HDs, change the case and more. For example, the last generation iPod (the sixth-gen officially dubbed the iPod Classic, though you can also refer to all six generations as iPod Classics) can even be modified to add Bluetooth. I&#x27;m curious to look into converting mine to using an SD card for storage.</p>]]></description>
            <link>https://paulstamatiou.com/revisiting-the-apple-ipod</link>
            <guid isPermaLink="true">https://paulstamatiou.com/revisiting-the-apple-ipod</guid>
            <dc:creator><![CDATA[Paul Stamatiou]]></dc:creator>
            <pubDate>Sat, 06 Aug 2022 00:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Crypto design challenges]]></title>
            <description><![CDATA[<p><strong>It’s still early days in crypto.</strong> That’s what you’ll hear everywhere when you start digging into crypto and web3 today. For most new users this unfortunately feels a bit closer to the <a href="https://twitter.com/Stammy/status/1463516773420978181">wild west</a>. There are a myriad of situations where they might not know what&#x27;s happening and where they don&#x27;t trust the system, services or tools they&#x27;re using.</p>
<p>Early adopters face foreign terminology, complex UIs, unexpected and exorbitant fees, security issues, slow transactions, confusing errors, <a href="https://cryptoscamdb.org">scams</a> and more. That makes for one hell of an onboarding, even if you&#x27;re lucky enough to have a friend showing you the way.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2021/11/paulstamatiou_com-token-alert.png" alt="Token alert message" />
<small>A message like this is normal for advanced users, but can be confusing, scary and lacking guidance for newcomers.</small>
<p>This is the state of crypto today. That can work for now—early adopters are motivated enough to jump through hoops to try something new—but this won’t scale as billions of users join the crypto ecosystem in the coming years.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2021/11/paul-stamatiou-internet-crypto-adoption.jpg" alt="The state of crypto is like the Internet in 1998" />
<small>The state of crypto is like the Internet in 1998.</small>
<p>But this is all known; there are many new technologies and protocols vying to evolve, change or fix things. I’m most interested in the design side of things.</p>
<p><strong>Can we even design truly <em>great</em> experiences for common activities in crypto today?</strong> Does the underlying tech have to evolve significantly first? What&#x27;s the best we can do with today&#x27;s technological constraints?</p>
<p>The crypto users of tomorrow will have different motivations and expectations than the early adopters today. They won&#x27;t put up with clunky, confusing, unreliable, unsafe and expensive systems. Great design—for wallets, exchanges, identity, dApps, marketplaces, DeFi and more—will be the bridge to help get us there.</p>
<p>Everyone likes to say that in the future maybe crypto users won’t even know they’re using crypto; that the blockchain and complementary systems are just the technology powering everything behind the scenes. We can only get there if we <strong>design for trust</strong> and use that as a critical lens through which we analyze every aspect of the crypto experience today.</p>
<h3>Designing for trust</h3>
<p>So you might be thinking.. okay this is totally wrong and even the Bitcoin whitepaper established that cryptographic proof should be used instead of trust for decentralized systems. And that the ethos in the crypto community today is "Don&#x27;t trust, Verify."</p>
<p>Yea, that&#x27;s all true. But what I&#x27;m talking about is one level up than the blockchain itself. I&#x27;m talking about the interfaces people interact with to do what they need to do, which may happen to be directly on or indirectly related to the blockchain. It&#x27;s about elevating context and providing signals about their interactions so they can feel safer to make decisions about what actions to take and which actions to avoid.</p>
<p>Public blockchains like those that power Bitcoin and Ethereum are permissionless. Lack of trust, centralized servers and third parties is a feature. They&#x27;re entirely open networks where any participant or machine can see what&#x27;s happening. While this leads to a level of trust with the ability for anyone to track and verify all transactions, that’s where the trust ends.</p>
<p>As active web3 participants<sup><a rel="footnote" href="#footnote-1" id="r1">1</a></sup> we regularly interact with dApps, smart contracts and more that we should not simply trust by default. But there’s also a person&#x27;s trust of the blockchain itself. Ever had a transaction fail due to gas issues? Or new tokens you just sent to your wallet from your exchange not appear in a timely manner? Issues like this won&#x27;t inspire much confidence in crypto for new users.</p>
<p>A great crypto experience<sup><a rel="footnote" href="#footnote-2" id="r2">2</a></sup> designed for trust will help you make an informed decision by elevating all the information you need, especially if that information comes from multiple places. I’ll dive into that more a bit later.</p>
<div><p><strong>Current state of crypto</strong><br/>
<!-- -->I&#x27;ll be the first to admit that it&#x27;s easy to sit here and write about how I think crypto experiences today could be improved, especially while largely ignoring technical feasibility and challenges. It&#x27;s so early and it&#x27;s not easy building such expansive and composable decentralized infrastructure.</p><p>Unlike just about everything else we&#x27;ve come to expect with modern technology, popular blockchains like Ethereum are not instantaneous. In fact they&#x27;re slow and worse, expensive.</p><p>I mean if anything was possible, I don&#x27;t think anyone would think that the best way to store all their valuable assets would be in a little Chrome extension that injects JS into a website where malicious actors could <!-- --><a href="https://twitter.com/iam_preethi/status/1455523559070126083">trigger phishing prompts</a><!-- -->. It&#x27;s just the easiest way to quickly build things today.</p><p>Lots of crypto experiences are built around existing constraints. As usage, utility and demand increases in the future, we&#x27;ll be able to push on these constraints.</p></div>
<h3>What we can do today</h3>
<p>One of the reasons I&#x27;m so excited about web3 is that everything so desparately needs design help that almost any attention to detail anywhere in any common flow would be tremendously valued. <strong>It&#x27;s like getting in on the ground floor of helping define key interactions in browsers, email clients and other core tools during the formation of Internet.</strong></p>
<p>You can design how people interact with anything related to the blockchain: wallets, exchanges, dApps and more. You could have a lasting impact in a ridiculously fast growing space.</p>
<p>Crypto has been around for about a decade—long enough to prove there&#x27;s something here and see growth but still nascent enough that there&#x27;s plenty of things left to figure out, define and invent. How often do these opportunities come around?</p>
<p>But I digress..</p>
<p>Today, we can get very familiar with the technical constraints of crypto systems and design for trust and clarity over all touchpoints of someone&#x27;s journey. This article is in no way meant to be a complete overview of all design challenges in crypto. I wouldn&#x27;t be able to write that; this is just meant to highlight a few areas that have been top of mind for me.</p>
<p>There&#x27;s several high-priority areas to explore starting when someone first hears about crypto to learning about how and where to use it but I&#x27;m most interested in these:</p>
<ul>
<li>
<p><strong>Exchange experience & Onboarding</strong><br/>
As hundreds of millions of people interact with crypto for the first time, it&#x27;s very likely that their first experience will be with a centralized exchange where they can exchange their local fiat currency for their first Bitcoin, Ethereum, stablecoin or other crypto asset. There&#x27;s lots of responsibility and opportunity here to set new users up for success.</p>
</li>
<li>
<p><strong>Wallet experience</strong><br/>
For some, just holding crypto assets may be enough, but many will be drawn to all that web3 offers from various dApps to NFTs and more. A crypto wallet is the passport to web3 and making it clear how to set one up, become familiar with connecting to other services, dealing with transactions and more will be a key experience to get right.</p>
</li>
<li>
<p><strong>Web3 guidance & curation</strong><br/>
This is the discovery phase for slightly more advanced users that are now asking "What can I do with my crypto?" There are opportunities to help people discover what exists, what is safe to use and guide people along the way. It&#x27;s 1998 and people rely on AOL or the Yahoo! homepage to show them what&#x27;s out there. What&#x27;s the curated search engine for crypto?</p>
<p>There are a few projects in this space like <a href="https://rabbithole.gg/">Rabbithole.gg</a>, <a href="https://zapper.fi">Zapper.fi</a>&#x27;s Quests and <a href="https://Layer3.xyz">Layer3.xyz</a>, though I think most of them are a bit too complex or don&#x27;t yet do a great job yet on educating behind why someone would want to do a certain task. Another interesting one is <a href="https://context.app/feed/collectors">Context.app</a>, helping with NFT discovery.</p>
</li>
</ul>
<p>I also think there&#x27;s a huge opportunity around decentralized identity; I touch on that a bit in the next section.</p>
<h3>Exchange experience & Onboarding</h3>
<p>In the coming years, hundreds of millions of people will interact with cryptocurrency on-ramps—exchanges and similar services where they can receive their first cryptocurrencies and other crypto assets. For most people, this will be with a centralized exchange (CEX). Exchanges will be most people&#x27;s first time truly interacting with crypto. Exchanges will need to simplify, educate and guide these new users every step of the way.</p>
<p>Exchanges should explain the difference between different types of cryptocurrencies (including stablecoins), potential for volatility and potential for utility of each type. They should equip people with a basic understanding of security should they transfer their assets to a wallet outside the exchange.</p>
<p>But before all that, there&#x27;s a lot of opportunity to simplify the required KYC ("Know your customer") flows that require you to verify your identity. There&#x27;s nothing easy about these flows as they require a tedious process of uploading photos of your id. Even small enhancements like integrated camera flows instead of requiring switching to the camera app, letting you easily resume onboarding if you&#x27;re not in a place to do this yet (send me a reminder push notification in X hours) or letting you setup the rest of your account and upload your id when you can later would be welcomed.</p>
<p>At some point these people may want to do something more than just buy or sell their crypto. Exchanges can educate around dedicated, non-custodial wallets. Even small things like transferring Ether to a new wallet can be daunting. Exchanges can also begin to set the expectation that outside the exchange, transactions are usually not instant and that depending on the service, sometimes require significant fees and time.</p>
<p>I could go on and on. So much opportunity here.</p>
<h3>Wallet experience (Transactions)</h3>
<p>Wallets started out as only being responsible for managing and facilitating basic crypto asset transfers. Today they are responsible for a whole lot more. Modern wallets deal with showcasing NFTs, all sorts of tokens, dealing with complexities related to separate blockchains and Layer 2 assets, token swaps, connecting with dApps and more.</p>
<p>Wallets are a frequent and primary touchpoint for interacting with countless web3 services, protocols, other wallets and more. Designing for trust inside the wallet is of prime importance. There are no gatekeepers with decentralized services; just a lot of entities you&#x27;ll individually interact with. As such it’s important to make it clear exactly what’s happening each time you interact with another user, smart contract, dApp, et cetera.</p>
<p>A core part of all wallets is a way to list transactions. Too many wallets today treat this as a list of data without much thought about what it means for the user and within the context of trust.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2021/11/paulstamatiou_com-phantom-wallet2.png" alt="Phantom Solana Wallet (Chrome extension)" />
<small>Phantom Solana Wallet (Chrome extension)</small>
<img src="https://turbo.paulstamatiou.com/uploads/2021/11/paulstamatiou_com-metamask-wallet.png" alt="MetaMask Wallet (Chrome extension)" />
<small>MetaMask Wallet (Chrome extension)</small>
<p>Here are a few things I&#x27;ve been thinking about in regards to displaying transactions and assets:</p>
<ul>
<li>
<p><strong>Be hyper transparent around transaction status.</strong> We expect things today to be instant but the blockchain is one of the only pieces of modern technology that can feel very slow at times. We need to take great care in displaying transaction status. The average user should <strong>never have to visit Etherscan/Polygonscan/etc</strong> just to see how much time is left with their transaction. There should never, ever be any doubt in their mind about what&#x27;s happening to their money or transaction.</p>
<p>A basic "sending/pending" state is not enough. Can you imagine not having a progress bar when you were downloading an mp3 on dialup in the &#x27;90s?</p>
</li>
<li>
<p><strong>Make errors actionable.</strong> One of the most frustrating things is when a transaction fails. It&#x27;s annoying, sure, but with Ethereum transactions it also probably means you lost a lot of money in fees! Elevate as much of the error messaging and description as possible to the user. Suggest solutions the user can take if feasible, such as trying again but with more gas if that was the reason it failed.</p>
<p>Show me how much money I just lost on gas with this failed transaction. Don&#x27;t make me go to Etherscan to try to piece it all together; it can be rather confusing to discern on Etherscan with gas price, transaction fee, gas fee and gas usage, especially with EIP-1559.</p>
</li>
<li>
<p><strong>Show more context.</strong> Transaction data is far too cryptic today. Any way to add further context and humanize is needed. See if there&#x27;s ways to display social proof.</p>
<p>Who, what, where, when.. I received an NFT from an OpenSea contract, which I&#x27;ve used and trusted before. Or show that I swapped a token via Uniswap. Did I receive an NFT from a smart contract or another wallet? Show me a visual preview in the list of transactions, along with any indication of the other party (be it an OpenSea logo/name, or associated ENS name and avatar).</p>
<p>This can be taken much further, but may be better suited for future solutions where your wallet may be paired with a robust knowledge graph.</p>
</li>
<li>
<p><strong>Inform and put the user in control.</strong> Letting a user select how much gas to pay for a transaction is not enough. What other context can be provided to help them make a decision?</p>
<p>For example, if they are interacting with a smart contract to obtain an NFT and the contract has a ton of pending transactions, maybe the wallet could see how many NFTs are left by checking the contract&#x27;s remaining supply, see how many pending transactions would be ahead of them and try to roughly estimate how much gas may be necessary before the NFT supply runs out.</p>
<p>Or perhaps the wallet could see how many recent transactions with the smart contract with other wallets failed, potentially hinting that this contract should not to be trusted (like those scams where it tries to get people to visit a website) or has other issues.</p>
<p>Create first-class experiences around speeding up a transaction. If I have multiple pending transactions with the same smart contract, show me how this affects the queue and the position of each.</p>
<p>These may be contrived examples but the point remains. Approach this with a user focus, think about what people may need or want to know in the moment and try to bring it forward.</p>
</li>
<li>
<p><strong>Make transaction state global.</strong> Wallets today are not simple single-page apps. They often have multiple tabs or sheets, they could have various sheets and they can be closed or collapsed entirely. Most people will want to know the status of their pending transactions at all times, regardless of where they are in the wallet. Make it easy to see status from anywhere, including using actionable in-app toasts or browser/app push notifications when it makes sense.</p>
<p>A simple analogy might be a macOS menubar app like Google Drive. At a glance I can see that it&#x27;s busy syncing files or that it&#x27;s all done and at rest. I don&#x27;t have to go anywhere or do anything to see its state.</p>
</li>
<li>
<p><strong>Give me an "oh shit" undo/cancel button.</strong> It&#x27;s all too easy to make a mistake. Scenarios like trying to ape into a new NFT drop unfortunately mean that speed is the only way to have a chance.. but speed also means you might not be taking the time to think through your actions.</p>
<p>Did you accidentally approve a token on a contract you probably shouldn&#x27;t have? Unfortunately, scenarios like this happen more often than they should. Wallets need an emergency resources in times like this. Perhaps modern wallets could have a sort of emergency "oh shit" button.</p>
<p>A button like that may try to pay the necessary amount of gas to quickly cancel that pending transaction before it&#x27;s estimated to go through, or try evasive maneuvers like start moving your highest value tokens to a newly-created wallet on your behalf with extremely fast gas. I&#x27;d happily eat a huge gas fee if it meant saving much more valuable assets in an emergency.</p>
<p>These are just a few examples, but there are lots of ways to interpret designing experiences to <strong>guide users when things don&#x27;t go down the happy path</strong>.</p>
</li>
<li>
<p><strong>Show all assets across all networks/chains.</strong> A lot of things are being built on various blockchains and Layer 2 networks. With the exception of testnets, there&#x27;s no need to require switching between the Ethereum mainnet and Layer 2 networks like Optimism and Polygon. Just show everything together. It&#x27;s so annoying to hunt for your assets and forget what network they&#x27;re on. Modern wallets like <a href="https://rainbow.me/">Rainbow Wallet</a> do this today.</p>
<p>Furthermore, more wallets should support multiple blockchains such as Avalanche and Solana. This is a tremendous amount of engineering work, so it&#x27;s not to be taken lightly.</p>
<p>Why should we put the onus on new users to know the difference between various blockchains/Layer 2s and know what their wallet can and can&#x27;t support? It&#x27;s already hard enough to explain how to safely backup a seed phrase. This lets the people use whatever web3 service they want with minimal overhead.</p>
</li>
</ul>
<h3>Wallet experience (Security)</h3>
<p>And then there&#x27;s a whole realm of <strong>things related to wallet security</strong> that could be made easier to access, control and understand.</p>
<ul>
<li><strong>Make it easier to disconnect your wallet</strong> from connected apps and sites. Could a thoughtful implementation have preferences to enable automatically disconnecting after a certain time period, prompting you to disconnect older connections or only allowing a limited number of connections to be active at a time?</li>
</ul>
<img src="https://turbo.paulstamatiou.com/uploads/2021/11/paulstamatiou_com-metamask-connected-sites.png" alt="MetaMask connected sites UI" />
<small>Wallets tend to make their connected sites UI buried, with no education around when and why you may want to disconnect.</small>
<ul>
<li>
<p><strong>Introduce education and user controls for token approvals and token allowances.</strong> This one is for the more advanced users today but it really shouldn&#x27;t be due to the security implications. When interacting with a dApp that needs to access your tokens, you need to give the smart contract approval to use your tokens. Usually this allows unlimited use of all of your tokens and pose a risk where your tokens can be taken without further approval. It&#x27;s a best practice to remove token approvals for services you no longer trust or use. Similar to removing OAuth permissions on your accounts.</p>
<p>Services like <a href="https://revoke.cash/">Revoke.cash</a> and <a href="https://tac.dappstar.io/">Token Allowance Checker</a> exist for this purpose but this could be easier if part of the wallet experience. Some services like Zapper.fi have their own way to adjust allowances. Needless to say it could all be easier. You can read more about the topic here: <a href="https://kalis.me/unlimited-erc20-allowances/">Unlimited ERC20 allowances considered harmful</a>.</p>
</li>
<li>
<p><strong>Demystify common actions like connecting a wallet and signing a message.</strong> After you&#x27;ve used a few dApps, it becomes very common to see a lot of different dialogs you need to accept or confirm. This makes it all too easy for someone to absent-mindedly get into a habit of accepting these without quite understanding what&#x27;s happening.</p>
<p>Can modern wallets help educate customers about the risks associated with each action and provide ample recourse to undo them? Today, if you accidentally accept a dialog, most wallets don&#x27;t make it clear what you need to do to be safe, or if there is any risk from the action you took.</p>
<p>The team behind the <a href="https://walletconnect.com/">WalletConnect</a> protocol is working on a concept to merge "accept connection" and "sign message" that may only work for trusted apps and/or require strict restrictions.</p>
</li>
</ul>
<h3>What we can do tomorrow</h3>
<p>Dealing with existing technical constraints can definitely feel like we&#x27;re putting lipstick on a pig. If we put some of these shortcomings off to the side and consider a future wallet, things get a bit more interesting.</p>
<p>Here are a few potential areas of explore going forward:</p>
<ul>
<li>
<p><strong>Fix wallet addresses.</strong> Every crypto user deserves an easy way to reference their wallet. ENS is the current solution and it works (I love it and have several, including <code>stammy.eth</code>), but it&#x27;s not easy for a newcomer to setup, requires fees and has a small namespace where their ideal handle/domain is likely already taken.</p>
<p><strong>The next billion crypto users shouldn&#x27;t have to pay to make crypto usable.</strong> They shouldn&#x27;t have to deal with long addresses that could lead to huge issues like them losing funds. What&#x27;s the Gmail of wallet addressing? What if you could pick from several providers for a free shorthand address for your wallet? If you want pay for yourname.eth, thats fine. But that&#x27;s not for everyone. Could it be closer to email or ENS subdomains with providers you want to use or affiliate with like <code>stammy.exchange.eth</code> or <code>stammy@MyDAO</code>.</p>
</li>
<li>
<p><strong>Is wallet the right word?</strong> One challenge is that we’re designing for crypto as if it’s purely money (and maybe some NFTs) in a wallet. But the role of the wallet is growing and in the near future it will be so much more than that. Your crypto wallet can become your identity, your interests, your preferences, your knowledge graph, your communication. Perhaps we need a better word to describe its expanded role and control.</p>
<p>Websites are more frequently allowing you to "connect wallet" when often they mean just login. Connecting your wallet with your money can sound scary. Which brings me to the next point..</p>
</li>
<li>
<p><strong>Clarity & control around privacy and public assets.</strong> It takes some getting used to having all your assets publicly visible by anyone on the blockchain if they know your address. This is going to shock a lot of people when they first setup their wallet. Can you imagine paying a stranger for a coffee and them instantly being able to see all of your transactions and holdings? Creepy. But that&#x27;s what the blockchain enables.</p>
<p>Advanced users today get around this by maintaining multiple wallets, but surely we can&#x27;t expect everyone in the future to know how to do this on their own. Even then it&#x27;s not hard to track transactions if you accidentally transfer anything between the two wallets instead of using an exchange for that.</p>
<p>One partial solution is better wallet education and integration for supporting private-focused coins like Monero, Zcash and Mobilecoin. That&#x27;s fine for things that can be done privately, but you can&#x27;t exactly use those for other cryptoassets like NFTs or particular tokens. So what&#x27;s a more robust solution?</p>
<p>What if the wallet itself was safer by default? What if connecting your wallet to dApps was able to facilitate logging in, but by default did not show any assets. Depending on your permissions, the wallet could then allow exposing the wallet address where your assets actually live (potentially spread across multiple). Almost like Apple iCloud Private Relay for your wallet. I&#x27;m sure there are numerous technical and security feasibility issues with something like this, but I&#x27;m just trying to paint a picture of where we could aim in the future.</p>
</li>
<li>
<p><strong>Make it smarter, make it safer</strong>. Today “Connecting with wallet” is very convenient but very dumb. The dApp you connect to gets a unique identifier and some basic info about your holdings but not much else.</p>
<p><strong>How can we attach a knowledge graph to the wallet?</strong> A set of public and private preferences, a list of friends, a list of dApps you trust and how much, a list of blocked addresses, dApps and more. This graph data would ideally be a mix of public and private data stored off-chain.</p>
<p>Not only is this getting at a basic storage system for each wallet, it&#x27;s also getting at the start of a robust permissions system.</p>
<p>But the real super power of an approach like this? <strong>It can bootstrap all sorts of trust and security signals.</strong> You could see that 7 of your friends have used this smart contract before and didn&#x27;t report any issues, so you can trust it yourself too.</p>
<p>You could block or report a token as being a scam and it would instantly be hidden for your friends too. You could follow curated blocklists from entities you trust to make web3 safer for you. If anyone steals an NFT the community could blacklist it quickly enough that all NFT marketplaces could prevent any sale of that asset. There&#x27;s so much potential here. Companies like <a href="https://spruceid.com/">SpruceID</a> and <a href="https://idx.xyz/">idx</a> are exploring related things today.</p>
</li>
</ul>
<h3>What else?</h3>
<p>It&#x27;s such a promising time to be using web3 and especially working in web3. We haven&#x27;t even seen the killer apps of crypto that will bring waves of people into crypto.</p>
<p>This article was only meant to touch on a few areas where design help is especially needed, and from a design-only POV. I&#x27;m sure there are astounding technical challenges as well that may lead to varying alternative solutions. But it&#x27;s exciting to be here while it&#x27;s all getting figured out.</p>
<p>As a designer, I love to abstract complexity away from the user by relentlessly questioning what part of an interface is even necessary to present to the user and what we can automatically do for the user.</p>
<p>However, this will be one area we&#x27;ll have to be super careful about with crypto experiences. Crypto is different. It&#x27;s not like yet another Web 2.0 experience where abstracting things away (and likely putting that power back in the hands of the app/service). Web3 is about putting the user in control of their data and assets; giving them ownership, not taking it away.</p>
<blockquote>
<p>"Once understood, crypto is powerful in its simplicity. But it actually becomes more complicated the more you bury it under layers of abstraction. It’s clear to me now that the technology wants to be seen; it wants to be understood."</p>
<p>—<a href="https://thedefiant.io/crypto-wants-to-be-seen-op-ed-by-kayvon-tehranian/">"Crypto Wants To be Seen"</a></p>
</blockquote>
<p>With that, we&#x27;ll have to be careful about <strong>introducing thoughtful abstraction</strong>—simplifying and hiding complexity without diluting the essence of web3 or taking away control when it might be valued.</p>
<p>Examples of these types of decisions ahead might include:</p>
<ul>
<li>
<p>Do we hide that your wallet is non-custodial and introduce alternative recovery mechanisms? Or just do a great job at teaching people how to backup their key and understand the importance of that key.</p>
</li>
<li>
<p>Do we try to hide that there may be multiple Layer 2 networks you&#x27;re interacting with and automatically try to use the best network for the task at hand? Or focus on educating around what Layer 2 bridges do, the benefits of Layer 2 networks or other blockchains and provide transparency around where your assets live.</p>
</li>
</ul>
<p>These are the kinds of details we&#x27;ll have to figure out before we can get to that idealistic goal that everyone loves to talk about; that someday people won&#x27;t even know they&#x27;re using crypto. Is that even a goal? Or should we educate and empower people to embrace all that crypto and web3 have to offer? Of course, we&#x27;ll need to fix a few things first..</p>
<p>There&#x27;s a lot of noise in web3 today. It&#x27;s hard to know what technology, dApp or community is healthy and valuable. We need to build experiences that act as a great host to new users as if they had a web3 expert friend next to them guiding the way.</p>
<p>Maybe we can get there if we think about designing for trust. People trust other people and if web3 is all about decentralized networks, maybe we need to start tacking on more of those networks to the daily experience to help guide, secure and curate.</p>
<br><br><br><hr><br><h3>Footnotes</h3><p><a href="#r1">1</a><!-- --> I basically use the terms crypto and web3 interchangeably in this article but I realize there is nuance between the terms. Web3 tends to refer more towards the broader ecosystem and decentralized nature of how these systems work.</p><p><a href="#r2">2</a><!-- --> I reference "great experiences" often and I know it&#x27;s vague but there are so many things it can apply to: getting your first crypto, swapping tokens, connecting your wallet with a dApp, sending crypto to someone else, et cetera.</p><p><a href="#r3">3</a><!-- --> For the sake of simplicity, lets table the discussion of Layer 2 networks and alternative, faster blockchains like Solana. The current state of Eth gas is untenable and hopefully a multi-chain/L2 future full of composability can abstract away all the rough parts here. Even today the L2 experience is poor; I&#x27;ve watched friends click around for hours frantically trying to find their assets, forgetting what blockchain and L2 they had it stored on.</p><p><a href="#r4">4</a><!-- -->Another problem lies around proactively providing signals and controls to help users assess whether one of these entities can be considered trustworthy or not, but I&#x27;ll mention that in the next section.</p><p><a href="#r5">5</a><!-- -->Which thanks to ENS .eth domains it&#x27;s really not that hard to find someone&#x27;s wallet.</p>]]></description>
            <link>https://paulstamatiou.com/crypto-design-challenges</link>
            <guid isPermaLink="true">https://paulstamatiou.com/crypto-design-challenges</guid>
            <dc:creator><![CDATA[Paul Stamatiou]]></dc:creator>
            <pubDate>Wed, 24 Nov 2021 00:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[How I made $50K in 3 days with NFTs]]></title>
            <description><![CDATA[<link rel="preload" as="image" href="https://turbo.paulstamatiou.com/uploads/2018/01/copyright-paulstamatiou_com-cie1931-custom-chart.jpg"/><link rel="preload" as="image" href="https://turbo.paulstamatiou.com/uploads/2021/09/paul-stamatiou-crypto-mondrian-ranking.png"/><img src="https://turbo.paulstamatiou.com/uploads/2021/09/paul-stamatiou-CryptoMondrianDark-2000.webp" alt="Crypto Mondrian Dark NFT collection" />
<small>My code-generated NFT collection, <!-- --><a href="https://opensea.io/collection/cryptomondrian">Crypto Mondrian //DARK</a><!-- -->.</small>
<p>I first dabbled with cryptocurrency in 2011 when I wrote <a href="https://paulstamatiou.com/bitcoin-mining/">an article about mining Bitcoin</a> on AWS EC2 GPU clusters. My interest in crypto ebbed and flowed over the years before actively avoiding the space until earlier this year. It felt like there was a lot of noise and hype around volatile, speculative asset holding and not much innovation happening.</p>
<p>It wasn’t until a few months ago that I began to take a closer look at the state of crypto and see how much the landscape has evolved. The big thing for me was seeing how the blockchain has become programmable with smart contracts, little pieces of automatically-executing code running on the blockchain.</p>
<p>The new functionality afforded by smart contracts, along with the relative consumer ease of simply being able to connect your crypto wallet with any decentralized service and be able to quickly interact, has led to a flurry of new product developments. Most of these are categorized under the moniker dApps (decentralized applications that run on the blockchain or in a p2p capacity). A large chunk of dApps are in the so-called DeFi, or Decentralized Finance, space (yes, there&#x27;s lots of terms and abbreviations in the crypto space). I wrote a brief thread about <a href="https://twitter.com/Stammy/status/1417201411155120143">what I learned about crypto and DeFi</a> my first few weeks diving into it.</p>
<p><a href="https://ethereum.org/en/">Ethereum</a> was much more interesting to me now than Bitcoin. So much is being built on top of it with smart contracts and other <a href="https://coinmarketcap.com/tokens/views/all/">Ethereum-based tokens</a>. There are crypto-based games like <a href="https://axieinfinity.com/">Axie Infinity</a>, robust decentralized exchanges like Uniswap and Matcha.xyz, to communities and DAOs built around their own tokens like <a href="https://www.fwb.help/">FWB</a> and <a href="https://kong.land">Kong.land</a>. There&#x27;s far too much activity going on for me to accurately summarize the different types of innovation happening here and I&#x27;m definitely still learning myself.</p>
<p>NFTs are one particular realm of the crypto community that has been experiencing stratospheric growth over the last year. By now you’ve probably heard about them in some form. It could have been the news of digital artist <a href="https://www.theverge.com/2021/3/11/22325054/beeple-christies-nft-sale-cost-everydays-69-million">Beeple selling his NFT artwork for $69 million dollars</a>. Or maybe the news of Figma founder <a href="https://www.forbes.com/sites/alexkonrad/2021/03/18/figma-ceo-dylan-field-talks-cryptopunks-nft-beeple-metaverse/">Dylan Field selling a CryptoPunk NFT</a> for $7.5M.</p>
<p>NFTs are approaching mainstream status now—<a href="https://www.youtube.com/watch?v=oiN1_6pb_eE">Paris Hilton sold her own NFTs</a>, <a href="https://www.theblockcrypto.com/post/109655/jay-z-puts-a-cryptopunk-nft-as-his-twitter-profile-picture">Jay-Z bought a CryptoPunk</a> for $126k for his Twitter avatar and NBA player <a href="https://markets.businessinsider.com/news/currencies/steph-curry-nft-bored-ape-yacht-club-180000-ethereum-nba-2021-8">Steph Curry bought a $180k Bored Ape NFT</a> for his Twitter avatar and even Mila Kunis and Ashton Kutcher launching <a href="https://www.forbes.com/sites/nadjasayej/2021/07/26/is-stoner-cats-the-first-ever-nft-tv-show/">NFTs that unlock TV show episodes</a>.</p>
<p>One thing that stands out to me about crypto now, as opposed to the last time I was involved years ago, is that <strong>you can actually <em>do</em> stuff with your crypto now</strong>.</p>
<p>Before, it seemed like the most you could do was hold on to your crypto as an investment, sending it between wallets, or exchange it back to your local fiat currency. Now, people are able to spend their crypto.. largely on other crypto dApps or into the hands of creators with NFTs. And most of those people will continue investing in and building for crypto and decentralized services, so things continue growing and evolving.</p>
<p>However, all the press around NFTs reminds me of the hype around ICOs and speculative asset <em>hodling</em> of meme coins.. are NFTs just the latest example of a fleeting crypto fad?</p>
<h2>What are NFTs?</h2>
<h3>Digital art, collectibles, identity, tickets and more..</h3>
<p>I didn’t really get NFTs for a long time.. and honestly I don’t even know if I fully understand them now. Can’t someone just screenshot the NFT you paid a bundle for and have the same thing you have? That&#x27;s the common question you hear from anyone when they first hear about NFTs.</p>
<p>That&#x27;s like seeing <a href="https://paulstamatiou.com/photos/france/france-day-6/">the Mona Lisa in person</a>, taking a photo, turning that into a print on your wall and saying yours is worth the same. It&#x27;s not the original. With the public nature of NFTs on the blockchain, it&#x27;s easy for anyone to verify who owns it, who has owned it and when it first appeared. Anyone can look up your wallet address (or more recently ENS domain name if you set one up) to see what NFTs you own.</p>
<p>But let me take a step back for a moment..</p>
<p>NFTs are unique, non-fungible tokens on the blockchain. Regular cryptocurrency tokens like Ether or other <a href="https://coinmarketcap.com/tokens/views/all/">Ethereum-based ERC20 tokens</a> are fungible and can easily be traded and swapped for one another. They&#x27;re all the same thing.</p>
<p>By contrast, each NFT has a unique identifier allowing it to be paired with metadata that cannot be changed. While an NFT can be sold and transferred like any fungible token, each NFT has its own unique value and worth. This identifier also makes it possible to trace the ownership history for the NFT. It&#x27;s also possible to prove the scarcity of an NFT and know how many of a certain type exist and how many can exist.</p>
<p>Being able to programmatically prove ownership is where it gets interesting; NFTs can also be used like keys or digital tickets to unlock certain functionality, experiences, membership, events and so on.</p>
<p>And an NFT can never be taken from you. There is no middleman. This is not like <a href="https://slate.com/technology/2009/07/how-amazon-s-remote-deletion-of-e-books-from-the-kindle-paves-the-way-for-book-banning-s-digital-future.html">Amazon being able to remotely delete a Kindle book</a> you purchased because they want to. No one can take your NFT from your (non-custodial) wallet.</p>
<p>These traits of NFTs lead to some unique value propositions and capabilities. They can be used for digital art, content, collectibles and gaming but they can also be used for utilities like .eth domains like with the Ethereum Name Service or even tokenized real-world assets.</p>
<p>NFTs are status, identity, community, self-expression, access and more.</p>
<p>I could go on and get philosophical about the different ways NFTs provide value, but I&#x27;ll leave it at that. The value of an NFT always depends on what someone is willing to pay for it. The market always wins as they say; NFTs are no exception. Fortunately, now that market is open globally 24/7/365 and has a quick payment system. Not quite like the old days of trying to sell your Magic: The Gathering cards in person and not finding any buyers (just me?).</p>
<div><p>If you&#x27;d like to read up on NFTs more, I recommend checking out <!-- --><a href="https://ethereum.org/en/nft/">this NFT page on Ethereum.org</a><!-- -->, <!-- --><a href="https://opensea.io/blog/guides/non-fungible-tokens/">The OpenSea NFT Bible</a><!-- -->, <!-- --><a href="https://future.a16z.com/a-taxonomy-of-tokens-distinctions-with-a-difference/">Designing Internet-Native Economies: A Guide to Crypto Tokens</a><!-- -->, and <!-- --><a href="https://cdixon.org/2021/02/27/NFTs-and-a-thousand-true-fans">NFTs and A Thousand True Fans</a><!-- -->.</p></div>
<p>Even though NFTs have been around in some form since 2012 and then more media-focused from 2016, it&#x27;s still very early. I’m sure we’ll continue see a significant evolution of how they are used and how they are valued. Right now NFTs may get a bit of a mixed reputation due to the high level speculation on collectible assets and many buyers trying to quickly flip NFTs that are part of a limited set.</p>
<p>There are also private communities focused on investing in NFTs that have been growing, such as with <a href="https://pleasr.org/">PleasrDAO</a> and <a href="https://flamingodao.xyz/">Flamingo DAO</a>. While <a href="https://flamingodao.xyz/">Flamingo DAO</a> has done very well with their NFT investments so far, having experienced a 40X gain and <a href="https://twitter.com/litocoen/status/1432047312738660356">owning NFTs worth $1B+</a>, they take a longer view on what NFTs can provide:</p>
<blockquote>
<p>The growth of NFTs is just beginning, because NFTs represent the digitization and financialization of digital property and intellectual property. Trillions of creative works swirl around the Internet and are difficult to monetize, except through licensing models. NFTs hold out the hope of bringing back to the Internet an ownership economy. Creators can create, sell, and fractionalize ownership in their works, opening up a new chapter for creative endeavor. NFTs can be:</p>
<ul>
<li>fractionalized</li>
<li>combined into token sets</li>
<li>used as collateral for lending and stablecoin protocols</li>
<li>dynamic and interactive, incorporating outside data feeds</li>
</ul>
<p>Over the longer arc, NFTs hold out the hope of becoming increasingly financialized, interacting with other core blockchain-based financial primitives. They may prove to be a core primitive for decentralized identity solutions, and may increasingly serve as a cornerstone for monetizing emerging metaverses and other gaming platforms.</p>
<p>— <a href="https://docs.flamingodao.xyz/">What is Flamingo?</a></p>
</blockquote>
<p>Whatever your thoughts are on NFTs, it&#x27;s hard not to pay attention to what&#x27;s happening in the space. I very often think about how <a href="https://cdixon.org/2010/01/03/the-next-big-thing-will-start-out-looking-like-a-toy">the next big thing will start out looking like a toy</a> in the context of everything happening in crypto now, like the early days of the Internet.</p>
<h3>Common types of NFT projects</h3>
<h3>10k PFPs, collectibles, games and more</h3>
<p>With the basics out of the way, lets see what types of media-focused NFTs and cryptoart are common right now. First off, we have the very popular so-called “10k PFP” collections. These are sets limited to 10,000 media assets geared towards being used as a profile picture, usually because the image looks like some kind of being: human, alien or otherwise anthropomorphized entity.</p>
<p>There are the popular ones like CryptoPunks and <a href="https://boredapeyachtclub.com/">Bored Apes</a> and then there are the many derivative collections trying to capitalize on these types of sets. Owning an NFT from one of these collections has led to being a new sort of status and community.</p>
<p>There are interesting trading card-like NFTs like <a href="https://parallel.life/">Parallels</a> and gaming NFTs like <a href="https://zed.run/">Zed</a>. And then a section of the NFT space that I&#x27;ll just call experiments because I&#x27;m not sure what else to call them. Things like <a href="https://www.blitmap.com/">Blitmap</a>, <a href="https://collisions.substack.com/p/gimme-the-loot">Loot</a> and <a href="https://tunesproject.org/">Tunes Project</a> that test the waters of how certain types of NFTs can invite others to build on top of them. In this case of Loot, building a whole game ecosystem with characters, loot, music and more.</p>
<p>And of course, there&#x27;s a ton of NFTs that encompass all other forms of art. It has also been inspiring to see artists adapt to the new format and reap the benefits; getting paid more easily and generously than previously. There are computer-assisted artists making 2D and 3D creations by hand and there are all sorts of artists making digital versions of their hand-made creations. There&#x27;s even a painter <a href="https://opensea.io/collection/seasketch">selling NFT sketches</a> that come paired with an offer to unlock a physical painting, shipped to whoever owns the NFT during a particular time each year.</p>
<p>But there’s one type of NFTs that I became particularly fond of: <a href="https://en.m.wikipedia.org/wiki/Generative_art">generative art</a>. Generative art can be defined in many ways but at a high level it&#x27;s any art that was created in part or in whole with the artist being hands-off and having an automated computer system or program do the rest, leading to each creation being entirely unique.</p>
<p>One of the popular players in this space is <a href="https://artblocks.io/">Art Blocks</a>. This example below sold for 777 ETH (around $2.5M when it sold):</p>
<blockquote>
<p>Wow... just shocked. When I set this price (yesterday) I didn&#x27;t really expect it to sell this quickly. Thank you <a href="https://twitter.com/tylerxhobbs?ref_src=twsrc%5Etfw">@tylerxhobbs</a> for your fantastic work. I will certainly reinvest this in new and upcoming artists / donate a portion to charity. 🙏🤯 <a href="https://t.co/rbaJQ73D48">https://t.co/rbaJQ73D48</a></p>
<p>— Kevin Rose (@kevinrose) <a href="https://twitter.com/kevinrose/status/1430560685172297729?ref_src=twsrc%5Etfw">August 25, 2021</a></p>
</blockquote>

<h2>Making my NFTs</h2>
<h3>How I got inspired, built and listed them</h3>
<p>I knew I wanted to get involved with NFTs somehow. Over the past few months I had been seeing designers I follow experiment with and find success creating and selling their own cryptoart NFTs. Friends and family had been suggesting I do something with NFTs; I just didn’t know what.</p>
<p>I’m a designer and developer but my forte is definitely not the type of graphic and 3D design I had seen as being common with NFTs: detailed illustrations, 3D concepting/rendering and 3D animation. I didn’t want to design another collection of PFPs. It had to be something that I could feasibly write a simple program myself with regular web and mobile languages I already know.</p>
<p>I thought about picking up <a href="https://processing.org/">Processing</a>, which I had last touched in college more than a decade ago, and making some art out of things like <a href="https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life">Conway&#x27;s Game of Life</a> and other cellular automata. But I didn&#x27;t find that to be particularly aesthetically pleasing or how I could make it pleasing.</p>
<p>I began thinking about modern, abstract art I like, wondering if I could do a "crypto" take on that. I like geometric art and something with simple geometric shapes would be feasible for me to code with regular web/software technologies I already know. And hopefully by being heavily inspired by existing traditional artwork, these NFTs would might already feel familiar to viewers.</p>
<p>A few years ago I visited <a href="https://paulstamatiou.com/photos/amsterdam/">Amsterdam (my photoset)</a> and visited museums like the Stedelijk Museum of modern and contemporary art where I had seen lots of <a href="https://en.wikipedia.org/wiki/De_Stijl">De Stijl</a> pieces. Piet Mondrian&#x27;s compositions came to mind along with pieces by Gerrit Rietveld.</p>
<img src="https://turbo.paulstamatiou.com/p/2018/amsterdam/copyright-paulstamatiou_com-DSC1100-3000.webp" alt="" width="3000" height="2182" /><br /><br /><img src="https://turbo.paulstamatiou.com/p/2018/amsterdam/copyright-paulstamatiou_com-DSC1137-3000.webp" alt="" width="3000" height="2001" /><br /><br /><img src="https://turbo.paulstamatiou.com/p/2018/amsterdam/copyright-paulstamatiou_com-DSC1098-3000.webp" alt="" width="3000" height="2197" /><br /><br /><img src="https://turbo.paulstamatiou.com/p/2018/amsterdam/copyright-paulstamatiou_com-DSC1104-3000.webp" alt="" width="3000" height="2309" />
<p>I decided to try writing some code to generate Mondrian-inspired art that would be unique each time I ran it. But <strong>I wanted to make it feel like what crypto <em>feels</em> like to me</strong> at first glance. I think Mr. Robot, <a href="https://decrypt.co/79422/shadowy-super-coder-pack-315m-perks-ethereum-nft-devs">Shadowy super coders</a>, dark web, The Matrix, Blade Runner, Altered Carbon, Ready Player One.. <strong>lots of neon colors, glows and darkness</strong>.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2021/09/paul-stamatiou-crypto-vibes-moodboard-3000.jpg" alt="Paul&#x27;s moodboard of crypto vibes" width="2319" height="1948" />
<p>After I had a general idea of what I wanted to create, I thought about how to build it. I knew I wanted to do a limited set, something under 1,000. I figured 100 would be a nice way to get started and test the waters. Just enough that I would need to have whatever code I wrote be able to export directly to PNG. I didn&#x27;t want to hack around with taking screenshots for each of them.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2021/09/paul-stamatiou-crypto-mondrian-glow.png" alt="Paul&#x27;s moodboard of crypto vibes" width="2800" height="800" />
<small>The general vibe I was going for.. bright colors seeping into generous glows.</small>
<p>I decided to start by making a simple HTML page that used <code>canvas</code> and JavaScript to create the art and easily let me export the canvas. I had become familiar with canvas recently when making the <a href="https://stocketa.com">Stocketa</a> site:</p>
<blockquote>
<p>Spent a good chunk of the weekend building out the last bits of the new <a href="https://twitter.com/StocketaApp?ref_src=twsrc%5Etfw">@StocketaApp</a> website. Happy with how it&#x27;s turning out... will probably deploy later tonight Used Canvas to composite JPG frames (for smaller size) using PNG masks (for alpha) for Apple-like 3d scroll effect <a href="https://t.co/2OBNhIR3y8">pic.twitter.com/2OBNhIR3y8</a></p>
<p>— Paul Stamatiou (@Stammy) <a href="https://twitter.com/Stammy/status/1384509594991534082?ref_src=twsrc%5Etfw">April 20, 2021</a></p>
</blockquote>
<blockquote>A Tweet embed was not displayed. Read this article in a browser to see it as intended.</blockquote>
<p>After a Sunday afternoon of tinkering, I had a working concept. Every time the page loaded, a new random design would be created. I used the localStorage API to keep track of views and name each file for export, which I would simply do via a download button on the page. I was too eager to get this out and didn&#x27;t spend much time on additional code to automate things.</p>
<p>Much of the code revolves around randomly selecting the number of iterations to complete, what color palettes to use, modifying colors and the intensity of the glows. Some of them used color palettes of 3-5 colors I put together myself, while others I had the code pick from a random color and then find pentadic, tetradic or triadic colors to use or use varying alphas of a single color. Figuring out the colors took a decent chunk of time and I think there was still some room for improvement. I ended up having around 15 different color palettes I was having the code randomly select between at one point.</p>
<p>This is what it ended up being—a simple HTML page with a few hundred lines of JavaScript and a download button to export the canvas to a 4800x4800 PNG.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2021/09/paul-stamatiou-crypto-mondrian-chrome.png" alt="The single HTML file responsible for generating the artwork." width="1388" height="1304" />
<small>The single HTML file responsible for generating the artwork.</small>
<p>One issue I ran into and was with color profiles. Dealing with very saturated colors and lots of glows, I wanted to use the P3 color space instead of sRGB, which was the default color space/profile when exporting the contents of a canvas. This is something I became quite familiar with years back when writing <a href="https://paulstamatiou.com/building-a-windows-10-lightroom-photo-editing-pc/#the_display">my post about building a Lightroom PC</a>.</p>
<p><img src="https://turbo.paulstamatiou.com/uploads/2018/01/copyright-paulstamatiou_com-cie1931-custom-chart.jpg" alt="CIE1931 color space comparisons: ProPhoto RGB, Rec. 2020, Adobe RGB, DCI-P3, sRGB"/></p>
<p>Relying on sRGB meant some visible color banding that annoyed me. Unfortunately, it seemed like this was out of my control and it&#x27;s not yet possible to specify a color profile for canvas to use when exporting after a cursory investigation. It wasn&#x27;t a huge issue, so I moved on.</p>
<h3>Publishing PNGs as NFTs</h3>
<p>Now I had a pile of PNGs and needed to list them for sale as NFTs. This started out as a small project so I just wanted something very turnkey to manually list each piece. I already knew I wanted to use OpenSea. It&#x27;s hard to look at NFTs online and not come across them; something like 98% of all NFT trade volume flows through OpenSea.</p>
<p>The other nice thing about OpenSea is that there is no cost to the seller to mint each NFT. There&#x27;s a one time gas fee the first time you sell anything but I had done that a while back with another NFT that I&#x27;m not even sure how much that cost.</p>
<p>Minting an NFT is the process of putting your art/media and its associated metadata on the blockchain by creating a new, unique token (usually ERC-721 but there&#x27;s a newer format called ERC-1155 that supports both non-fungible and fungible tokens). In my case, I would be putting these on the Ethereum blockchain. It&#x27;s also possible to mint on other blockchains for lower costs, such as the <a href="https://rainbow.me/learn/a-beginners-guide-to-layer-2-networks">Ethereum-compatible sidechain Polygon</a>, or a faster blockchain, <a href="https://solana.com/">Solana</a>, but that&#x27;s outside the scope of this article. For now, we&#x27;ll stick with Ethereum. It&#x27;s currently the most popular for NFTs.</p>
<p>If I was doing a much larger NFT project, I would probably spend a bunch of time and money developing and deploying my own smart contract on Ethereum. NFTs are minted through a smart contract, small bits of code running on the blockchain itself. Owning your own smart contract gives you complete control over your NFT collection and doesn&#x27;t delegate any control over to a NFT marketplace. It just costs a lot to develop and deploy (for example, I tested deploying a simple smart contract and the estimated gas fees required to publish the smart contact to the Ethereum blockchain were around 0.25-0.35 ETH or ~$1,000).</p>
<p>This is a growing space so you&#x27;re at no shortage of options for how you want to publish your NFTs from <a href="https://niftykit.com/">Nifty Kit</a>, Bitski, Foundation, Rarible, Zora.co, UNifty.io, <a href="https://tryshowtime.com/">Showtime</a> and many more.</p>
<h3>Listing on OpenSea</h3>
<p>So I ended up sticking with OpenSea: easy to get started and no fees to mint NFTs, but they take a 2.5% cut on each sale. Other marketplaces like Foundation require you to pay gas to mint each NFT, which can get expensive quickly if you&#x27;re unsure your items will sell, with each item costing potentially around $100 of gas to mint.</p>
<p>There&#x27;s a bit of nuance to how OpenSea does things. They do so-called <em>lazy minting</em>. While you may need to pay an initial gas fee to list a new collection, each NFT listing does not require any fees. This works because the NFT is not actually minted yet. It gets officially minted once the buyer pays the gas fees to mint the artwork on the blockchain.</p>
<p>I created a new collection then began adding each NFT one by one; first adding the item, then marking it for sale at a set price. If I had a more complex set, I might have spent the time to add detailed metadata such as unique stats or traits of the individual NFTs to help people more easily filter and find what they&#x27;re looking for.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2021/09/paul-stamatiou-opensea-create-crypto-mondrian-3000.png" alt="OpenSea create Crypto Mondrian NFT interface" width="2702" height="2350" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2021/09/paul-stamatiou-opensea-sell-crypto-mondrian-3000.png" alt="OpenSea sell Crypto Mondrian NFT interface" width="2704" height="1600" />
<small><a href="https://opensea.io/collection/cryptomondrian">Adding and listing an NFT</a><!-- --> for sale on OpenSea.</small>
<p>When it came to pricing, I wasn&#x27;t really sure how to approach this. I started with the first few priced around $200, between Ξ0.05-0.065 (Ξ is the symbol for ETH, or ether). I wasn&#x27;t sure if these would sell at all and since I was manually uploading and listing each NFT, I started slow and released them in batches over a 3 day period. I listed the first three in a new <a href="https://opensea.io/collection/cryptomondrian">Crypto Mondrian //DARK</a> collection, Tweeted about it and then went out to dinner that Sunday evening.</p>
<p>Surprisingly, all 3 sold quickly. The next day, I released 20 more NFTs. Every few minutes I would hear the ding from my email app and then open my <a href="https://rainbow.me/">Rainbow Ethereum wallet</a> to see each new inbound ETH transfer from OpenSea.</p>
<blockquote>
<p>I&#x27;m blown away by the NFT community.. already sold 12 of my Crypto Mondrian //DARKs. 🤯 I just listed another 20: <a href="https://t.co/lPHCzp5spT">https://t.co/lPHCzp5spT</a> <a href="https://t.co/nOEb7zGfEq">pic.twitter.com/nOEb7zGfEq</a></p>
<p>— Paul Stamatiou (@Stammy) <a href="https://twitter.com/Stammy/status/1434923524754493443?ref_src=twsrc%5Etfw">September 6, 2021</a></p>
</blockquote>
<blockquote>A Tweet embed was not displayed. Read this article in a browser to see it as intended.</blockquote>
<p>I kept releasing in batches over a 3 day period at varying prices. As they started to sell I noticed people quickly listing theirs for sale at much higher prices so I experimented with increasing my prices.</p>
<p>It was interesting to see where the sales came from. While I think a good portion came from those that follow me on Twitter, I believe a large set of folks found me through various crypto community Discord and Telegram groups where my collection was eventually shared. I also saw lots of folks that purchased them ending up sharing the new NFTs they added to their collection with their own audiences. It was awesome to see it all come together.</p>
<p>By the end of day 3, all NFTs had sold (except #099 and #100 I wanted to keep for myself as a memento). To say that I was shocked that my Crypto Mondrian art was selling and selling well would be a huge understatement. The reaction far exceeded my expectations. The average sale price was around Ξ0.189, though that includes all sales (some of which were much higher like Ξ0.6-0.9) not just ones listed for sale by me directly.</p>
<p>My collection ended up being <strong>ranked #469 out of all NFT collections on OpenSea</strong> that week, and #132 in the Art category:</p>
<img src="https://turbo.paulstamatiou.com/uploads/2021/09/paul-stamatiou-crypto-mondrian-ranking.png"/>
<h2>Breaking down the sales</h2>
<h3>The grand total was Ξ14.085, just over $50,000 at the current ETH price</h3>
<img src="https://turbo.paulstamatiou.com/uploads/2021/09/paul-stamatiou-CryptoMondrianDarkCollection-3000.jpg" alt="All 100 Crypo Mondrian //DARK NFTs" width="3000" height="3000" />
<small><strong>All 100 <!-- --><a href="https://opensea.io/collection/cryptomondrian">Crypto Mondrian //DARK</a><!-- --> NFTs</strong></small>
<p>One interesting thing about certain NFT marketplaces like OpenSea is the ability for creators to specify a royalty percentage when listing their collection. This means that the creator will continually receive payment for any sale of their NFTs, even if they are not involved in the transaction and it is between two other users. This is amazingly creator-friendly. Currently, this is a feature of some individual NFT marketplaces, not actually part of any NFT standard.. yet.</p>
<p>That being said, I did set a 10% royalty on my Crypto Mondrian collection. OpenSea batches up the royalties and delivers them in a separate, single payment every few weeks.</p>
<p>Here&#x27;s a breakdown of the sales and royalties so far:</p>
<table><thead><tr><th>Payment received (minus 10% royalty and 2.5% OpenSea fees)</th><th>Number of sales</th></tr></thead><tbody><tr><td>Ξ0.0569</td><td>30</td></tr><tr><td>Ξ0.07</td><td>16</td></tr><tr><td>Ξ0.175</td><td>11</td></tr><tr><td>Ξ0.0875</td><td>11</td></tr><tr><td>Ξ0.35</td><td>6</td></tr><tr><td>Ξ0.306</td><td>5</td></tr><tr><td>Ξ0.131</td><td>5</td></tr><tr><td>Ξ0.219</td><td>4</td></tr><tr><td>Ξ0.0438</td><td>3</td></tr><tr><td>Ξ0.109</td><td>2</td></tr><tr><td>Ξ0.438</td><td>1</td></tr><tr><td>Ξ0.263</td><td>1</td></tr><tr><td>Ξ0.0788</td><td>1</td></tr></tbody></table>
<table><thead><tr><th></th><th></th></tr></thead><tbody><tr><td>Royalties accrued
(includes initial sales)</td><td>Ξ2.083</td></tr><tr><td>Grand total</td><td>Ξ14.085 ($50,417.96 @ current $3,579.55 ETH price)</td></tr></tbody></table>
<p>I&#x27;m extremely thankful and amazed at what was able to happen with this project, and the power of the crypto technology and community that enabled this to happen. It has been awesome to see creators quit their full-time jobs to pursue their passions, fueled by their newfound ability to quickly be able to earn a tremendous amount of money with NFT collections. It will be fun to see how this space evolves and what new types of things can be created using NFTs, even beyond art and collectibles.</p>
<p>On the other hand, it&#x27;s clear that a lot of people are interested in NFTs to be able to quickly flip them (often within hours or days of a purchase) and make a quick profit. As a creator, the first time I saw someone purchase my NFT and then immediately list it for 13x their purchase price.. that stung a bit. I get it though, and I have definitely been on the other side before. I wish there was a way to specify separate types of NFTs that might let me sell differently to those that enjoy the artwork vs those that are in it for the investment and speculation.</p>
<p>For example, I might sell an NFT at a discount if it meant the buyer would either not be able to sell it, or would not be able to sell it for some period of time. Not unlike a <a href="https://www.investopedia.com/ask/answer/12/ipo-lockup-period.asp">6-month IPO lock-up period</a> for employees.</p>
<h3>What&#x27;s next?</h3>
<h3>Just tinkering and learning</h3>
<p>I had a lot of fun diving into the world of NFTs lately. While I&#x27;m interested in continuing the journey with another collection, I won&#x27;t do anything unless it&#x27;s a slight evolution from what I just did with this set. Either a new style or something different (video? animated?).</p>
<p>I have been particularly interested in learning about smart contracts and would love to deploy a smart contract that is able to generate media completely on-chain. It&#x27;s been fun to watch all the smart contract experiments that <a href="https://twitter.com/dhof">Dom Hoffman</a> (creator of Loot, Blitmap, Vine..) has been tweeting out. As I wrote this, another interesting NFT experiment called <a href="https://mannys.game/about">Manny&#x27;s Game</a> was gaining popularity and had a unique set of rules.</p>
<p>But one thing seems to be certain with NFTs: creativity is valued highly. Being the second person to do something without evolving the format much won&#x27;t get you too far, especially in the future as the popularity of NFTs go up and down.</p>
<blockquote>
<p>Qualities to look for in NFTs on chain 🖼 good art 🌐 public domain 💻 open source 💎 unique 🤝 not anonymous 💗 healthy community ❌ not super markety 🧑‍🎨 committed artist 💸 you like it 💵 you can afford it 📉 ur cool if it goes down</p>
<p>— Dame.eth (@jacksondame) <a href="https://twitter.com/jacksondame/status/1437753067085107210?ref_src=twsrc%5Etfw">September 14, 2021</a></p>
</blockquote>
<p>But, of course, I have lots of work left on my other project <a href="https://stocketa.com">Stocketa</a>, where I recently added <a href="https://twitter.com/StocketaApp/status/1425456454316740612">basic crypto support</a>.</p>]]></description>
            <link>https://paulstamatiou.com/how-i-made-50k-in-3-days-with-nfts</link>
            <guid isPermaLink="true">https://paulstamatiou.com/how-i-made-50k-in-3-days-with-nfts</guid>
            <dc:creator><![CDATA[Paul Stamatiou]]></dc:creator>
            <pubDate>Sun, 12 Sep 2021 00:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Getting started with SwiftUI]]></title>
            <description><![CDATA[<link rel="preload" as="image" href="https://turbo.paulstamatiou.com/uploads/2021/06/paulstamatiou_com-swiftui-playgrounds-example.gif"/><p>It was just a year and a few months ago that I first began learning about and tinkering with Swift and SwiftUI. I followed tutorials and learned through lots of trial and error as I worked on my stocks tracker app, <a href="https://stocketa.com">Stocketa</a>. Picking up SwiftUI was one of the best decisions I’ve made.</p>
<p>SwiftUI is a massive advancement in making iOS development more accessible for all. I don&#x27;t consider myself a seasoned developer but I know enough to build somewhat polished prototypes and sites for my projects. I&#x27;ve tried to get into iOS development years ago with Objective-C and UIKit but it was just not for me.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2021/06/copyright-paulstamatiou_com-DSC05703-1500.jpg" alt="Xcode setup with SwiftUI live preview" />
<small>My Xcode setup. SwiftUI live preview on the right pane.</small>
<p>As a designer with many years of experience designing mobile interfaces, I always felt one step removed from the process and the final product. I could prototype a ton of stuff with web technologies and preview on mobile devices but it wasn&#x27;t the same. I&#x27;ve always wanted to design and build natively, with Apple&#x27;s own tools.</p>
<p>I love sweating the details of interactions and motion, but my ability to express myself and try out concepts using native devices and OS affordances always felt limited by my lack of knowledge of these tools. Sure, I could describe what I wanted to an engineer in many ways, but I wanted to build it myself.</p>
<p>There’s nothing quite like just doing it yourself, natively and SwiftUI has made this a reality for me. I&#x27;m here to share my enthusiasm and some resources so that it can be attainable for you too.</p>
<p>This is not meant to be a comprehensive guide or tutorial, but rather a brief reflection on my time with SwiftUI and some pointers on getting started.</p>
<h3>Stocketa & SwiftUI</h3>
<p>SwiftUI is not some beginner&#x27;s toy for getting into iOS development (though some long-time UIKit developers may say otherwise). <strong>You can make beautiful, full-blown, real iOS apps with all the motion, delight and flourishes you want.</strong> And this will only continue to improve as Apple invests more into SwiftUI in the coming years.</p>
<p>I have only had to use UIKit for a few minor things like getting more control over custom textfield designs and interactions. I&#x27;ve built custom bottom sheets, menus, onboarding flows and much more purely with SwiftUI. Here are some examples of what I&#x27;ve been able to build with SwiftUI:</p>

<blockquote>A Tweet embed was not displayed. Read this article in a browser to see it as intended.</blockquote>

<blockquote>A Tweet embed was not displayed. Read this article in a browser to see it as intended.</blockquote>

<blockquote>A Tweet embed was not displayed. Read this article in a browser to see it as intended.</blockquote>

<blockquote>A Tweet embed was not displayed. Read this article in a browser to see it as intended.</blockquote>

<blockquote>A Tweet embed was not displayed. Read this article in a browser to see it as intended.</blockquote>

<blockquote>A Tweet embed was not displayed. Read this article in a browser to see it as intended.</blockquote>

<blockquote>A Tweet embed was not displayed. Read this article in a browser to see it as intended.</blockquote>

<blockquote>A Tweet embed was not displayed. Read this article in a browser to see it as intended.</blockquote>
<h3>What is SwiftUI?</h3>
<p>Let me take a step back and explain what SwiftUI is in the first place and why I think it makes iOS development much more accessible to all.</p>
<p>SwiftUI is a framework for creating interactive user interfaces for iOS and macOS. It goes beyond just the visuals of how the interface looks and helps with everything from taps and gestures to accepting data input via things like text fields, color pickers and date pickers to working with your iPad&#x27;s trackpad pointer. And it does it in a way that, to me, feels very natural and fast.</p>
<p>It feels natural because <strong>SwiftUI code just feels like you&#x27;re writing some new type of HTML markup</strong>. It&#x27;s definitely way more than that, but when you&#x27;re just getting started it doesn&#x27;t feel foreign. You&#x27;re not trying to figure out what "super" means, what function overriding is or trying to grok what viewDidLoad() is for.</p>
<p>And it feels fast because you&#x27;re writing SwiftUI side-by-side with a live preview, so you see your changes as you type them. You don&#x27;t have to compile and send a build to your device or the simulator to get an interactive preview of your view.</p>
<p>SwiftUI was introduced two years ago with iOS 13 and brings a declarative style of programming for your user interface. The general idea is that all views of your app are based on the state of your data. Instead of telling a view exactly how and what you want it to do with imperative programming, with SwiftUI you tell it what you want and the view will react automatically based on the underlying data changing.</p>
<p>Want a circle to move across the screen when the user taps a button? You have a value on the object that it reacts to, along with an animation between the old and new value. This declarative style is similar to React web development too.</p>
<p>I&#x27;m flying through this but once you wrap your head around the declarative style it really just speeds up development.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2021/06/paulstamatiou_com-swiftui-playgrounds-example.gif" alt="SwiftUI example in Playgrounds"/>
<small>SwiftUI example in Playgrounds</small>
<h3>My SwiftUI first impressions</h3>
<p>It&#x27;s important for me to add the context here that my impressions of diving into iOS development with SwiftUI are based entirely on me being a designer, not an iOS developer already familiar with UIKit development. I&#x27;ve just been given keys to a Ferrari. Everything is amazing and I&#x27;m just happy to be in the driver&#x27;s seat and press that red engine start button. I have everything to finally build an iPhone app myself.</p>
<p>Contrast this viewpoint with, say, an existing iOS developer. My perception of the broader iOS developer community is that SwiftUI isn’t exactly universally loved. SwiftUI does not have feature parity with UIKit. The SwiftUI alternatives may not be as performant or may not be possible yet. It&#x27;s an entirely different way of crafting user interfaces and it has a few bugs here and there. I get that.</p>
<p>But SwiftUI is getting better every year and WWDC 2021 starts next week. With each iOS release we get more and more SwiftUI updates bringing us closer to parity. Swift 5.5 is coming soon and that brings lots of <a href="https://www.hackingwithswift.com/articles/233/whats-new-in-swift-5-5">very intriguing improvements like async/await</a> as well as <code>#if</code> for postfix member expressions (lets you do conditional view modifiers easily) that will be fun to explore.</p>
<p><strong>But I digress...</strong> my first impressions of developing with SwiftUI along with some of my current thoughts:</p>
<p><strong>SwiftUI live previews:</strong></p>
<ul>
<li>
<p><strong>First impression:</strong> Writing SwiftUI view code on one side of Xcode and then seeing the live, interactive preview of your interface is very slick and a fun way to learn as you figure out the ins and outs of SwiftUI.</p>
</li>
<li>
<p><strong>15 months in:</strong> SwiftUI Previews get extremely slow to load and refresh once you start having a larger app. They also get more complex as you have to do more work to manage the example data to use for the preview. Especially if you have certain things that rely on user state (such as a logged-in user from Firebase). And due to the static nature of the preview code, if you want to change a @State for example you have to resort to tricks like <a href="https://developer.apple.com/forums/thread/118589">wrapping the view</a>.<br/>
The key is to know what to use previews for. They can be very helpful for smaller subviews that work totally fine with static data. But it&#x27;s up to you if you want to spend the time to get it working well for more complex views. I tend to use it for smaller subviews and then just test on device for the rest.</p>
</li>
</ul>
<p><strong>On SwiftUI giving you native access</strong></p>
<ul>
<li>
<p><strong>First impression:</strong> SwiftUI gives you access to so much. Native UI components. Advanced gestures (of which you can use multiple at the same time!). The ability to animate virtually anything. The ability to use lots of views however you like, even applying a mask over them at once. Access to device things like gyroscope, accelerometer and haptics. The list goes on. It&#x27;s real, native app development and it&#x27;s great.</p>
</li>
<li>
<p><strong>15 months in:</strong> Yea this never gets old.</p>
</li>
</ul>
<p><strong>Building for native mobile vs Web</strong></p>
<ul>
<li>
<p><strong>First impression:</strong> Designing and developing natively for iOS feels so much faster and guaranteed compared to Web. There are only a few types of iOS devices so for the most part what you see on your device is exactly what someone will experience on their iPhone, down to the animations. You don&#x27;t have to worry about testing across many browsers and viewports compared to Web, nor worry about heavily optimizing file sizes.</p>
</li>
<li>
<p><strong>15 months in:</strong> You have to care about performance once your app does more. You&#x27;ll have to think about what thread you&#x27;re using else you may drop frames and introduce some scrolling jank. You&#x27;ll have to think about optimizing your views and heavily using sub-views to reduce what gets redrawn to the screen. You&#x27;ll have to care a bit about what functions do heavy computation and when.</p>
<p>But for performance with animations and masks, that&#x27;s still good. Most of the time when I drop some frames it&#x27;s due to some underlying data issue, not me doing something too crazy with lots of views, animations and masks.</p>
</li>
</ul>
<p><strong>SwiftUI&#x27;s modifier syntax</strong></p>
<ul>
<li>
<p><strong>First impression:</strong> Writing view code with all these chained modifiers (the .frame(), .foregroundColor() and other things chained under objects) is a bit funky and seems messy. Compared to web development where you actively try not to put too much style code in the view layout markup and abstract much of the styling out to a separate CSS file.</p>
</li>
<li>
<p><strong>15 months in:</strong> The way SwiftUI does things with modifiers is great but you need to get into the habit of abstracting commonly used groupings of modifiers into custom view modifiers (think of it like using a class in CSS.. kinda).</p>
</li>
</ul>
<p><strong>Working with a strongly typed language</strong>
While this is more about Swift than SwiftUI, you&#x27;ll run into it regardless: Swift is a strongly typed language.</p>
<ul>
<li>
<p><strong>First impression:</strong> It&#x27;s extremely annoying. I was dealing with non-stop warnings and errors that I wasn&#x27;t using the correct type when working with some data (Types are things like Bool, Int, Double as well as many other object types you can create). It was very confusing, especially trying to figure out why Optionals are a thing, how to unwrap them and so on.</p>
</li>
<li>
<p><strong>15 months in:</strong> I&#x27;m very comfortable now with Swift&#x27;s strong typing and really think it helps write faster, safer code. I&#x27;ll still run into various issues but most of the time it&#x27;s just Xcode looking out for me.</p>
</li>
</ul>
<h3>Learning SwiftUI</h3>
<p>It&#x27;s clear to me that SwiftUI is a powerful way to develop apps, especially for people with no prior iOS development experience. While there is always a learning curve with new frameworks and tools, especially code-based ones, SwiftUI is a fresh take on this with the Xcode live preview canvas that lets you see your UI as you&#x27;re writing it.</p>
<p>My goal with this article is share my high-level thoughts on SwiftUI and pointers on how to get started with some great resources that have helped me along the way. I hope to write a much more in-depth post about Stocketa and SwiftUI in the future.</p>
<h3>Where to start?</h3>
<p>I learned Swift and SwiftUI like I learn most things: a few tutorials to get the swing of things, then trying it out with my own project and all the trial and error that follows. Fortunately, SwiftUI has a ridiculously healthy and active developer community so there are always places to turn to for help.</p>
<p>Here&#x27;s the general flow you might follow while getting into SwiftUI:</p>
<ul>
<li>
<p><strong>Install Xcode or Playgrounds.app</strong>. While you&#x27;ll need Xcode to get the most out of SwiftUI and build a full app, there&#x27;s another option. Apple has a <a href="https://developer.apple.com/videos/play/wwdc2020/10643">MacOS and iPad app called Playgrounds</a> that&#x27;s perfect for prototyping and playing with Swift and SwiftUI.</p>
</li>
<li>
<p><strong>Get familiar with the SwiftUI basics.</strong> How to use frames, stacks and spacers to <a href="https://www.hackingwithswift.com/articles/217/complete-guide-to-layout-in-swiftui">lay things out in your interface</a>. Then how to use view modifiers to tweak visual elements of your designs.</p>
</li>
<li>
<p><strong>Dabble with basic interactions</strong> Advance to hooking up some button interactions with <code>@State</code> and bindings and trying built-in components like the ScrollViews, toggles and more.</p>
</li>
<li>
<p><strong>Play with animations.</strong> There&#x27;s lots of fun to be had with .transition() and .animation(). <a href="https://developer.apple.com/tutorials/swiftui/animating-views-and-transitions">Apple has a tutorial</a> on the basics too.</p>
</li>
<li>
<p><strong>Work with data and dive deeper into Swift.</strong> Up until now you could get pretty far with a minimal understanding of Swift itself but you&#x27;ll soon need to have a stronger grasp. Learning how to structure your models for objects, learn more about optionals and types, manipulating arrays, making network requests and so on.</p>
</li>
<li>
<p><strong>Getting better at manipulating data.</strong> At this point lots of your challenges will be around manipulating data and passing it around. Here you&#x27;ll probably face some decisions for your app. How do you store your data: do you use Apple&#x27;s Core Data, a SQLite library like <a href="https://github.com/groue/GRDB.swift">GRDB</a> or turn to a third-party solution like Firebase Firestore or <a href="https://realm.io">Realm</a>.</p>
</li>
</ul>
<h3>Resources</h3>
<p>Okay, now to the actual resources I&#x27;ve learned from and come to rely on for staying up-to-date with all things Swift and SwiftUI these days.</p>
<h3>Courses</h3>
<ul>
<li><strong><a href="https://developer.apple.com/videos/play/wwdc2020/10119">Apple WWDC Video: Introduction to SwiftUI</a></strong> — Start here and at least watch the first 10 minutes where it goes over SwiftUI layout basics. It pretty quickly starts going through states, interactions and gestures, which you might be better off learning more paced with some other resources if you&#x27;re just getting started.</li>
<li><strong><a href="https://developer.apple.com/tutorials/swiftui#swiftui-essentials">Apple: Introducing SwiftUI</a></strong> — Apple has their own tutorial for getting up to speed with SwiftUI, but if this is your very first time I personally don&#x27;t feel it&#x27;s that great and that following along with a video where things are described step by step might be better.</li>
<li><strong><a href="https://designcode.io/courses">Design+Code</a></strong> — This is where I started. Meng To and the team at Design+Code have several SwiftUI courses for all levels of experience. When I took the course there was only one and it was great for me to get a solid understanding of view layout basics.</li>
<li><strong><a href="https://cs193p.sites.stanford.edu/">Stanford CS193p - Developing Apps for iOS</a></strong> — Stanford has their own course covering SwiftUI, with all materials freely available online.</li>
<li><strong><a href="https://www.udemy.com/topic/swiftui/">Udemy SwiftUI courses</a></strong> — While I haven&#x27;t done any myself, there&#x27;s a lot of <a href="https://www.udemy.com/course/swiftui-masterclass-course-ios-development-with-swift/">highly-rated SwiftUI courses</a> on Udemy.</li>
</ul>
<h3>Hacking With Swift</h3>
<p>You can&#x27;t learn SwiftUI without coming across <a href="https://www.hackingwithswift.com/">Paul Hudson and his website Hacking With Swift</a>. It&#x27;s a goldmine of material and practically every Google search I had when I was getting started had one of his articles in the top results. I recommend subscribing to get access to more of his tutorials.</p>
<p>Aside from a plethora of articles, Paul also has several Swift-related books and two amazing, free courses that break down Swift and SwiftUI into bite-sized videos:</p>
<ul>
<li><a href="https://www.hackingwithswift.com/100/swiftui">100 Days of SwiftUI</a></li>
<li><a href="https://www.hackingwithswift.com/100">100 Days of Swift</a></li>
</ul>
<p>I dabbled with both but never fully finished them; I got too eager to start building my own project.</p>
<h3>Reddit</h3>
<p>There are a few solid sub-reddits I like to check occasionally to keep in the loop of things and sometimes share progress: <a href="https://reddit.com/r/SwiftUI">r/SwiftUI</a>, <a href="https://reddit.com/r/Swift">r/Swift</a> and <a href="https://www.reddit.com/r/iOSProgramming/">r/iOSProgramming</a>.</p>
<h3>Blogs</h3>
<ul>
<li><strong><a href="https://swiftwithmajid.com/">Swift with Majid</a></strong> by <a href="https://twitter.com/mecid">@mecid</a> — One of the first good Swift/SwiftUI blogs I found when just getting started. Lots of great articles written in an easy to digest way. Though some articles are definitely a bit advanced and not beginner friendly.</li>
<li><strong><a href="https://www.fivestars.blog/">Five Stars</a></strong> — An excellent resource from <a href="https://twitter.com/zntfdr">Federico Zanetello</a></li>
<li><strong><a href="https://peterfriese.dev/">Peter Friese</a></strong> — If you end up using Firestore for saving your data, Peter (who works on Firebase) has <a href="https://peterfriese.dev/swiftui-firebase-add-data/">some great tutorials</a> to get started.</li>
<li><strong><a href="https://www.swiftbysundell.com/">Swift by Sundell</a></strong> by <a href="https://twitter.com/johnsundell">@johnsundell</a></li>
<li><strong><a href="https://www.donnywals.com/the-blog/">Donny Wals</a></strong> — He also wrote a book on Core Data and a book on Combine.</li>
<li><strong><a href="https://swiftui-lab.com/">The SwiftUI Lab</a></strong> — Not as many recent posts these days but I read a few while learning.</li>
<li><strong><a href="https://sarunw.com/tags/swiftui/">Sarun Wongpatcharapakorn</a></strong></li>
<li><strong><a href="https://medium.com/tag/swiftui">Medium</a></strong> — I wish there was a better way to link to this, but there are some occasional good SwiftUI posts on Medium if you search by tag. <a href="https://betterprogramming.pub/search?q=swiftui">BetterProgramming</a> is one Medium publication to watch too.</li>
<li><strong><a href="https://www.vadimbulavin.com/">Yet Another Swift Blog</a></strong> — A bit more on the advanced side but some good Swift and SwiftUI topics here.</li>
<li><strong><a href="https://www.raywenderlich.com/3715234-swiftui-getting-started#toc-anchor-001">Ray Wenderlich</a></strong> — It&#x27;s not a blog, but a sort of professional developer subscription service. But they have plenty of free tutorials related to SwiftUI. My only gripe is that much of the content is written from the perspective of a developer trying out Swift/SwiftUI things, not as an overall beginner for mobile development. For example their intro to SwiftUI makes various references to UIKit development.</li>
</ul>
<h3>Newsletters</h3>
<ul>
<li>
<p><strong><a href="https://recreatecode.substack.com/archive?sort=new">Recreate Code</a></strong> — A newsletter with videos diving into using SwiftUI to build layouts of common UIs and apps from <a href="https://twitter.com/navdeep_ua">Navdeep Singh</a> and <a href="https://twitter.com/jsngr">Jordan Singer</a>.</p>
</li>
<li>
<p><strong><a href="https://www.avanderlee.com/">SwiftLee Weekly</a></strong></p>
</li>
<li>
<p><strong><a href="http://weekly.swiftwithmajid.com/">SwiftUI Weekly</a> by Majid Jabrayilov</strong></p>
</li>
<li>
<p><strong><a href="https://indiedevmonday.com/">Indie Dev Monday</a></strong></p>
</li>
<li>
<p><strong><a href="https://iosdevweekly.com/">iOS Dev Weekly</a></strong></p>
</li>
</ul>
<h3>GitHub & YouTube</h3>
<p>Whenever I&#x27;m really stuck on a problem and can&#x27;t find any relevant info on Google results, I usually turn to searching on YouTube and GitHub. I&#x27;m frequently surprised at what I&#x27;m able to find there that I wasn&#x27;t able to otherwise.</p>
<p>On GitHub you may find various examples apps showing the concepts you&#x27;re looking for. A few YouTube accounts that consistently have some SwiftUI content are <a href="https://www.youtube.com/channel/UC2D6eRvCeMtcF5OGHf1-trw">Code with Chris</a>, <a href="https://www.youtube.com/channel/UCbTw29mcP12YlTt1EpUaVJw">Sean Allen</a>, <a href="https://www.youtube.com/channel/UCK88iDIf2V6w68WvC-k7jcg">Rebeloper</a>, <a href="https://www.youtube.com/channel/UCsuV4MRk_aB291SrchUVb4w">Kavsoft</a> and of course <a href="https://www.youtube.com/channel/UCmJi5RdDLgzvkl3Ly0DRMlQ">Paul Hudson</a>.</p>
<h3>Tips from my experience</h3>
<p>So I just linked to a ton of resources. I wish there was one single thing I could recommend but for me I learned through a myriad of sources over time. Here are a few things I learned or wish I had known as I started getting the hang of Swift and SwiftUI:</p>
<ul>
<li>
<p><strong>Get inspired, find a project.</strong> I learn best when I have my own project to build instead of following tutorial after tutorial of a random app concept. If that&#x27;s you, it may be helpful to try to pick an area of interest and see if there&#x27;s a simple app you can build for it.</p>
<p>If you&#x27;re looking for app inspiration, or just want to discover new patterns or seek UIs to build yourself, I suggest continually checking the App Store and trying out lots of apps.</p>
<p>For me, that was a stock tracker app, <a href="https://stocketa.com">Stocketa</a>. (Which is currently in limited Testflight testing now as I continue development). I’ve been so impressed with what I’ve been able to accomplish purely with SwiftUI in this app.</p>
</li>
<li>
<p><strong>Learn a few Xcode shortcuts.</strong> I wish I had taken a bit more time to learn more about Xcode&#x27;s capabilities when I got started. There are so many handy shortcuts and settings that can make your life easier.</p>
<p>Read this post on <a href="https://peterfriese.dev/xcode-shortcuts/">Xcode shortcuts from Peter Friese</a>. Some of my faves:</p>
</li>
<li>
<p>Auto-indent code: <strong>⌃ (Control) + i</strong>.</p>
</li>
<li>
<p>Refresh the preview canvas: <strong>⌘ (Command) + ⌥ (Option) + p</strong>.</p>
</li>
<li>
<p>Open a file quickly: <strong>⇧ (Shift) + ⌘ (Command) + o</strong>.</p>
</li>
<li>
<p>Customize Xcode to make <strong>⌘ (Command) + d</strong> delete the current line.</p>
</li>
<li>
<p><strong>Building a custom bottom sheet is harder than it looks.</strong> Lots of app these days use nice, custom bottom sheets with varying capabilities. In SwiftUI we have the native <code>.sheet()</code> but you can&#x27;t control things like how high it opens. I built a few custom ones and they&#x27;re harder to get working flawlessly than you&#x27;d think. Especially if you want to be able to have multiple resting heights and seamlessly transition to scrolling with a single gesture when expanded.</p>
</li>
<li>
<p><strong>Use the <code>value</code> attribute for <code>.animation()</code></strong> for more control over when something animates. I use this everywhere. I only discovered it after filing a SwiftUI bug with Apple and the Apple engineer suggested using this for a particular issue I had.</p>
</li>
<li>
<p><strong>Use a view model.</strong> Eventually you&#x27;ll find yourself with increasingly more logic and functions in your views. It&#x27;s time to move that to a separate View Model file. An example would be a class that is an ObservableObject that your view uses. Read up on MVVM (Model-View-ViewModel) for more info on this architectural pattern.</p>
</li>
<li>
<p><strong><code>.mask()</code> is very useful.</strong> Especially if you&#x27;re using gradients to color certain elements or if you need to apply an alpha gradient on a view. You can also use stacks to use multiple elements in your mask.</p>
</li>
<li>
<p><strong>Customize SVG assets with "Template Image" render setting.</strong> Want to add an SVG to your Assets.xcsassets catalog and then be able to change its color directly in SwiftUI? You&#x27;ll need to set "Render As" to "Template Image" in Xcode.</p>
</li>
<li>
<p><strong>The <code>@AppStorage</code> property wrapper is your friend</strong> when you need to store tiny, non-vital local settings for the user. Out of the box it only supports a few value types, but you can <a href="https://lostmoa.com/blog/SaveCustomCodableTypesInAppStorageOrSceneStorage/">follow this guide on RawRepresentable</a> to store any type of data to it.</p>
</li>
<li>
<p><strong>The <code>resetTransaction</code> property of <code>@GestureState</code> can be handy</strong> to define the animation to use when a user releases their finger when doing a gesture (as opposed to applying a general animation for the entire view/object).</p>
</li>
<li>
<p><strong>Get to know the <code>.simultaneousGesture()</code> modifier.</strong> If you&#x27;re doing anything advanced with gestures, it&#x27;s helpful to know that SwiftUI can help you manage multiple gestures with this view modifier. There&#x27;s also <code>.highPriorityGesture()</code>.</p>
</li>
<li>
<p><strong><code>.contentShape()</code> is your friend if some views are not tappable</strong>. Every so often you&#x27;ll into a situation where you&#x27;re trying to make a view tappable (either inside a button or with <code>.onTapGesture()</code>) and only a certain part of the view will be tappable. By placing <code>.contentShape()</code> on this view, say after any padding or other visual modifications you have, you&#x27;ll make the entire area tappable.</p>
</li>
<li>
<p><strong>Disable interaction with <code>.allowsHitTesting(false)</code> when needed</strong>. This may come in handy when you&#x27;re doing more advanced things with gestures.</p>
</li>
<li>
<p><strong>Need more performance? Start by splitting your view into smaller sub-views.</strong> There are a lot of reasons why your app could see some slow downs or have some janky, frame-dropping behavior. But in my experience the best place to start is abstracting your larger views into smaller ones. SwiftUI updates a view whenever any part of the view state changes, so by splitting your view into a set of smaller views, you&#x27;re giving SwiftUI the ability to only update smaller views depending on what data changed state.</p>
</li>
<li>
<p><strong>Use <code>.compositingGroup()</code> to help with animation and rendering issues.</strong> This modifier basically applies view modifiers on the ancestor views before rendered. A bit hard to describe but in particular it&#x27;s helpful when dealing with opacity animations or shadows. And if the view doesn&#x27;t need to be interactive, there&#x27;s and <code>.drawingGroup()</code> which is similar but flattens your views and uses Metal rendering for increased performance.</p>
</li>
<li>
<p><strong>Consider caching slow functions with memoization.</strong> This only works for certain types of functions, but something worth knowing about. Here&#x27;s a <a href="https://www.hackingwithswift.com/plus/high-performance-apps/using-memoization-to-speed-up-slow-functions#manual-memoization">great article on memoization</a>.</p>
</li>
<li>
<p><strong>Core Data (storage) is not for everyone.</strong> I got it working in my early versions of Stocketa but then I wanted to have it sync with iCloud and found it to be slow and unreliable. The only answer was to do a lot of custom syncing another way. I moved to Firebase Firestore and was much, much happier (after figuring out how to best flatten my data structure a bit).</p>
</li>
<li>
<p><strong>If you just can&#x27;t get it to work.. quit Xcode.</strong> If you&#x27;ve tried everything and it should work but doesn&#x27;t, try quitting and reopening Xcode. Try "Clean Build Folder" in Xcode. Try clearing Xcode cache files (I like <a href="https://apps.apple.com/us/app/devcleaner-for-xcode/id1388020431?mt=12">DevCleaner.app</a> for this). If none of that works, maybe it&#x27;s Apple&#x27;s bug:</p>
</li>
</ul>

<blockquote>A Tweet embed was not displayed. Read this article in a browser to see it as intended.</blockquote>]]></description>
            <link>https://paulstamatiou.com/getting-started-with-swiftui</link>
            <guid isPermaLink="true">https://paulstamatiou.com/getting-started-with-swiftui</guid>
            <dc:creator><![CDATA[Paul Stamatiou]]></dc:creator>
            <pubDate>Wed, 02 Jun 2021 00:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Thoughts on email hosting]]></title>
            <description><![CDATA[<p>It happens to me all the time. I have some idea or other need and before I know it I&#x27;ve registered a few new domains. Eventually I may need to setup some email addresses on those domains. Then I need to decide if I really want to pay ~$5-6 per month to setup email by setting it up with Google Workspace Essentials (née G Suite), Fastmail, ProtonMail or their ilk.</p>
<p>Before you know it you have a handful of different email addresses on different domains for various needs and you&#x27;re paying $50+ per month for that privilege. And let&#x27;s be honest, most of these addresses get just a few emails per week, if any.</p>
<blockquote>
<p>There&#x27;s really no one that makes it easy to own/manage lots of email addresses.<br/>
I probably have 10 for various needs/projects, all on custom domains, and I love G Suite but it&#x27;s ~$6/mo per email. I use Fastmail for some too but it&#x27;s a hassle to setup/manage them all.<br/>
— Paul Stamatiou (@Stammy) <a href="https://twitter.com/Stammy/status/1372558128399708163?ref_src=twsrc%5Etfw">March 18, 2021</a></p>
</blockquote>
<p>It&#x27;s 2021. While email is becoming less and less the backbone of any new venture, it&#x27;s still a core and required piece of being an Internet citizen. It shouldn&#x27;t be this complex to manage and setup email for all of your domains.</p>
<p>There are definitely benefits to keeping all of our email accounts entirely separate:</p>
<ul>
<li>You want to separate business from personal.</li>
<li>You want each domain to have its own password and 2FA/security key setup for security. Not great if you have everything under one account or admin control — if one account gets hacked, they&#x27;re all hacked.</li>
</ul>
<p>While certain email providers can let you maintain separate user accounts together, they all seem to have the same sort of admin setup where an admin account can still control user accounts. That&#x27;s not quite what I&#x27;m looking for.</p>
<p>For something so common, it should be easy and not cost an extra $5 per month just to setup one more custom domain and a few addresses. I often don&#x27;t need all the assorted Google Workspace functionality, in fact I often prefer not having yet another Google account show up in the user account dropdown.</p>
<p>What I&#x27;m getting at is nothing novel: just easy and reliable turnkey email hosting. But a solution that is optimized for keeping accounts separate for security but somehow allowing for one account to pay for them. Similar to how you need to fetch an auth code to transfer a domain, perhaps you just need a payment code to setup billing.</p>
<p>You can go down the rabbit hole of self-hosting (<a href="https://thehelm.com">Helm</a> is an interesting solution here but I don&#x27;t want the server inside my house) and dealing with maintenance, deliverability issues and reliability. That&#x27;s not something I&#x27;m interested in.</p>
<p>There&#x27;s also a breed of services like <a href="https://migadu.com">Migadu</a> that offer one place for you to manage your domains and setup hosting for each. It actually seems exactly what I want, though I do have one concern about having one service, under the same login, manage everything for all email hosting for every domain I own. It just feels like it&#x27;s consolidating everything and making it dramatically easier for an attacker to gain access to everything in one go. It would be interesting if they had a way to have one payment account, but individual, 2FA logins for each domain (basically removing the notion of any sort of organization admin that can control all domains).</p>
<h3>What about email aliases?</h3>
<p>I&#x27;m holding off for an ideal solution like that but for now, there&#x27;s an adjacent set of solutions for slightly different needs. If you don&#x27;t absolutely <em>need</em> to have emails/domains kept separate and don&#x27;t mind mixing up the inbox, you can use email aliases.</p>
<p>Aliases let you send and receive email for another address on another domain, but all inside a different email inbox. So if your primary G Suite email is <code>yourname@domain.tld</code>, you can have an email alias that lets you send and receive email from that inbox for your other email account <code>nickname@otherDomain.tld</code>. There&#x27;s just one inbox though, but it&#x27;s up to you to filter and organize as you please.</p>
<p>This could be handy for emails/domains you have that are related: for example you may have a business domain and then a few emails on a different domain for the product owned by the business.</p>
<p>I recently discovered <a href="https://improvmx.com">ImprovMX.com</a> thanks to some replies to that tweet above. ImprovMX makes setting up email forwarding for any custom domain easy and I&#x27;ve used it for one of my domains so far. The only thing I don&#x27;t feel great about is that using this method, you&#x27;ll have to specify an SMTP server to send your email with and unfortunately that connection is password-only, no two-factor auth (even if 2FA was feasible you&#x27;d probably have to be asked with every email you send and email clients aren&#x27;t designed with that in mind).</p>
<hr/>
<p>Separately, someone also mentioned <a href="https://simplelogin.io">SimpleLogin.io</a>, which helps you make unique, temporary email address aliases. This is similar to how Sign in with Apple can hide your real email from the service if you enable the "Hide my email" setting. With SimpleLogin you can create all sorts of aliases that forward email to your real email, and completely hide your address. You can of course disable/delete the alias at anytime. I think I&#x27;ll be trying it out in the future when signing up for new things.</p>]]></description>
            <link>https://paulstamatiou.com/thoughts-on-email-hosting</link>
            <guid isPermaLink="true">https://paulstamatiou.com/thoughts-on-email-hosting</guid>
            <dc:creator><![CDATA[Paul Stamatiou]]></dc:creator>
            <pubDate>Sat, 20 Mar 2021 00:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Building]]></title>
            <description><![CDATA[<p>There’s no need to preface how wretched, horrible and hard 2020 was for all of us with the global pandemic and all that changed in the world. Most of us stayed home an insane amount and refrained from any kind of travel, domestic or international.</p>
<p>My girlfriend Katherine and I had plans for some big trips this year, which we of course shelved. In the past one of my most time-consuming hobbies was making really detailed photosets of my trips. Here&#x27;s one of my favorite: <a href="https://paulstamatiou.com/photos/africa/southern-serengeti-tanzania/">Southern Serengeti, Tanzania</a>.</p>
<p>I would spend months of spare time culling and processing thousands of captured shots and video clips then designing and building photosets around them. They were definitely a passion project, almost entirely for myself.</p>
<p>Over the last few years I was usually juggling 1 or 2 side projects: either writing some long article for this blog, or working on some large travel photoset. This year I didn&#x27;t feel strongly enough about any particular topic to deep dive into writing a long article about, nor did I have any travel photos to work on.</p>
<p>I felt the need to do or learn <em>something</em> to keep me occupied (which I even feel a bit weird about, I find it hard to just relax and do nothing). I had always been curious about Swift and SwiftUI but really thought that was an unattainable goal for me to be proficient at. I had very, very briefly dabbled with Objective-C development years back and was turned off by the whole thing. It was so confusing to me at the time.</p>
<p>In March I decided to spend some time diving into Swift and SwiftUI. After reading some cursory guides and tutorials, I needed a project to dive into. That&#x27;s how I learn best. I began working on a personal itch: having an easier, more approachable and elegant way to track my stock holdings. Since then I have probably spent 10-15ish hours per week for the last ~9 months learning and building my first real iOS app, <a href="https://stocketa.com">Stocketa</a> (Coming in 2021.. <a href="https://stocketa.typeform.com/to/gl6WWE">stay in the loop</a>).</p>
<p>It wasn’t all kittens and daisies. There have been many frustrating back-to-back days and weeks where I’ve been stuck on a problem or not been happy with a solution so I’ve redesigned and rebuilt entire features. I think I’ve rebuilt the holdings view of my app probably 4-5 times by now.</p>
<p>I really, really love building for iOS. I love being able to control the entire lifecycle of a product: idea, sketches, designs, coded and working on a real device with native iOS code.</p>
<p>I can spend an insane amount of hours on a particular animation or flow and get exactly to the intended fidelity and experience I’m aiming for.</p>
<p>Now this has me thinking that as long as I have some app that I’m working on as <a href="https://paulstamatiou.com/side-projects/">my main side project</a>.. I’m not so sure I’ll ever go back to spending months working on detailed photosets. While photosets are largely just for me, an app is a different beast entirely.</p>
<p>I can distribute and have others try out and hopefully find a recurring use for it. I’m not assuming my app or future apps will make me any money but there’s something nice about being able to share your work with others that they will be able to use with their own data, unlike my website where it’s a more defined one-way relationship.</p>
<p>But I digress, I’m sure I’ll find some lightweight way to share photosets in the future, but it likely won’t be to the level of care they have been in the past. Though I do plan to find time to pause working on the app to write about things I’ve learned and share more progress.</p>
<h3>Designing and developing</h3>
<p>Throughout the year all of this has had me thinking more about my career in the future.</p>
<p>When I went to college in 2004 I started out as an electrical engineering major. I grew up soldering and building little circuit boards so it felt like the natural thing to do. I was never really into software. Long story short, that changed for me and I became fascinated with the web, design and software world, eventually changing switching to a major that was a hybrid of design and computer science.</p>
<p>I graduated college not thinking I was a good designer <em>or</em> developer. I did both as needed with my first few jobs. They were startups, so wearing many hats is expected anyways.</p>
<p>I love working on design strategy, vision, visual design, interactions and motion just as much as learning how to setup a view model and pipe data through my app and having my designs come to life.</p>
<p>At times I feel like I’m hiding part of myself at my day job as I don’t really get to put all of my technical skills to use, aside from some interactive mobile prototypes (and I am trying to fit in more SwiftUI prototypes at work when I can).</p>
<p>This is not a dig at my employer or anything; just commentary on what I view as a slightly evolving landscape where development tools and frameworks have become so much more approachable that the definition of a "developer" is finally more accessible. This is a good thing! Designers that care so much about the end-to-end experience can now have greater control over the end result. I could have never been an iOS developer in the UIKit and Objective-C days.</p>
<p>I have no interest in going into full-time software engineering as a job. I don’t want to get caught up with process, semantics, code style and code reviews, I want to obsess over the (front-end) details and interactions until it’s right.</p>
<p>There are more and more design engineering roles these days but I feel like I would lose part of my autonomy as a designer in helping define the strategy, solution and experience. And some companies have design engineering roles that are much more on the engineering side where you’re going to be working in a production app. That’s definitely not me (please no UIKit!).</p>
<p>A common rebuttal to this is just "work at a startup!"—I am definitely jaded on that. Here’s a <a href="http://danluu.com/startup-tradeoffs/">good read</a> on the topic. I just think that the ROI is often so messed up with startups. Especially if you’re the first design hire and get to do all the fun and challenging 0-60 stuff. You’ll be putting in as much time and sweat as the founders but get 100x less compensation.</p>
<p>There&#x27;s nothing I need solved now, nor am I looking for a job (the opposite, I&#x27;m very happy at Twitter).. just wanted to share that I really love building, from design to polished app.</p>]]></description>
            <link>https://paulstamatiou.com/building</link>
            <guid isPermaLink="true">https://paulstamatiou.com/building</guid>
            <dc:creator><![CDATA[Paul Stamatiou]]></dc:creator>
            <pubDate>Thu, 31 Dec 2020 00:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[The Squire]]></title>
            <description><![CDATA[<p>I&#x27;m no stranger to keeping track of notes and documents across a myriad of apps, services and digital to-do lists. I use Notion, Apple Reminders app, Bear app, sometimes I use Ulysses, random plaintext TextEditor files and Google Docs.</p>
<p>But it really doesn&#x27;t matter what I do with my digital documents as I always end up having some pen and paper on my desk at all times to take notes, quickly sketch designs and manage more to-do lists. I usually rely on plain printer paper or a Moleskine notebook.</p>
<p>I was wandering around SoHo in Manhattan a few weeks ago when I went to a small boutique pen and stationery store ("Goods for the Study" on Mulberry St). I eventually came across the <a href="https://www.baronfig.com/tools/squire/metals?precious%20metals=stainless%20steel">BaronFig Squire</a> and it was by far the best pen I had tried out there.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2020/12/baronfig-squire-pen.jpg" alt="BaronFig Squire Pen" />
<small>Stainless Steel BaronFig Squire</small>
<p>First off, it&#x27;s a pricey pen. The stainless steel one I got is $95 but it starts at $55 for other metals and colors. But it has impeccable build quality: it&#x27;s a twist-to-open style pen and there is absolutely no wiggling or play in the mechanism. It&#x27;s also rather heavy which I appreciate. And finally the ink rolls out <em>very</em> smoothly, no matter what angle you&#x27;re using it at.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2020/12/baronfig-squire-pen-2.jpg" alt="BaronFig Squire Pen" />
<small>It has this subtle sword graphic along with their logo, though I wish it was blank.</small>
<p>It uses "Parker capless" style ink refills and I was readily able to find a few styles of compatible ink refills on JetPens.com: Schmidt P8126, Ohto Flash Dry PG-105NP, Uni SXR-600 Jetstream.</p>
<p>I purchased all of those refills looking for something slightly more fine but still ended up going back to the ink it came with (looked like a rebranded Schmidt P8126 anyways). My only complaint with it is that the default ink is ever so slightly too thick for my taste but I love how easily it comes out at all angles.</p>]]></description>
            <link>https://paulstamatiou.com/writing-baronfig-squire</link>
            <guid isPermaLink="true">https://paulstamatiou.com/writing-baronfig-squire</guid>
            <dc:creator><![CDATA[Paul Stamatiou]]></dc:creator>
            <pubDate>Mon, 21 Dec 2020 00:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Hello, RSS]]></title>
            <description><![CDATA[<p>It has been years since I’ve used RSS to keep tabs on interesting blogs I’ve found and websites I like. Social media took over and blogging went from being ubiquitous to being more of a novelty. Google shutdown FeedBurner 8 years ago; Google Reader was shuttered shortly after.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2020/10/copyright-paulstamatiou_com-DSC05584-1000.jpg" alt="Feedbin on my iPad Pro" />
<small>Feedbin on my iPad Pro</small>
<p>I used to follow a few hundred personal weblogs but eventually that number dwindled down as people stopped blogging. My consumption time naturally adjusted to focus on other sources like Twitter. Despite RSS standing for Really Simple Syndication, it couldn’t hold a candle to simpler and more interactive services… things everyone has like Twitter, Reddit, or even the Apple News app.</p>
<p>And then in recent years individual email newsletters became more mainstream with services like TinyLetter and Substack making it easy for people to build and reach their own community as well as monetize.</p>
<p>RSS has been considered dead to all but the most dedicated and loyal.</p>
<h3>Modern RSS readers</h3>
<p>It’s now almost 2021. Things I want to keep up to date with are now all over the place. My inbox is littered with various newsletters. I have to constantly manage Gmail filters (and remember to check them) for various subscriptions. While I get my fill of news and updates about interests from Twitter and some Reddit, I follow a lot and it’s easy to miss something.</p>
<p>This has been especially true in 2020 where there’s been enough political and pandemic news to dominate any platform. And beyond that, there are times when I want to step away from feeds of non-stop bad world news and go to a place that’s laser-focused on content from a few sources I’ve picked.</p>
<p>I decided to take a look at the current state of RSS readers in 2020. I was in for a surprise.</p>
<p><strong>RSS readers have evolved.</strong> That’s not even a good term for them now as they do so much more. They know that you get your news from multiple sources: email newsletters, Twitter, podcasts, YouTube and of course RSS too. They know that there’s often a deluge of updates you need help sifting through or that you need help keeping track of articles you find elsewhere.</p>
<p>I looked at what RSS readers were popular by checking out my website analytics. I’ve always seen Feedly and Newsblur in there as referrers, but have also started to see Inoreader as well. Feedly has a robust offering, and it was a product I used a bit many years ago. It has a higher price point than some other services but in the end I just didn’t like the design. It felt busy. Like another inbox I had to manage instead of a calm place I can go to relax, similar to firing up my Kindle. I felt the same way about Inoreader and others.</p>
<h3>Feedbin</h3>
<p>Then I found Feedbin. I very quickly knew this is what I had been looking for. First off, it&#x27;s not free. Feedbin is $5 per month. But on that note I don&#x27;t think any RSS readers with any unlimited email newsletter capability are free.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2020/10/copyright-paulstamatiou_com-feedbin-newsletter-address.jpg" alt="Feedbin Newsletter email address" />
<small>Feedbin has a custom email address to use for newsletters.</small>
<p>Newsletter functionality is easy to setup. In the settings you&#x27;ll find your own custom <code>@newsletters.feedbin.com</code> email address to use to subscribe to any newsletters you like.</p>
<p>There&#x27;s not much to the user interface but there&#x27;s attention to detail in a few places. I was pleasantly surprised to see that Feedbin has several Hoefler & Co typefaces to choose from. I then realized that Feedbin can even extract the full-text of any RSS post from the website directly, even when the feed only provides partial content.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2020/10/copyright-paulstamatiou_com-IMG0047.jpg" alt="Feedbin on my iPad Pro" />
<small>Feedbin theme and readability settings</small>
<p>Feedbin also has a browser bookmarklet so you can easily send any article you find anywhere on the web to Feedbin for reading later. I find myself using this quite a bit.</p>
<p>There&#x27;s also some basic "actions" functionality. Actions work very much like Gmail filters. You provide some basic search terms, specify what tags and feeds to look in and then how to act on it. Right now the set of actions is pretty limited: you can have posts marked as read or starred. There&#x27;s no way to entirely filter something out of a feed unfortunately. You can, however, setup push notifications for specific terms with <a href="https://feedbin.com/notifier">Feedbin Notifier</a>.</p>
<p>I use a few actions to star particular terms in high-volume feeds I follow. For example, I use it to search a few iOS-related subreddits for terms I care or am learning about (recently that was anything iOS 14 with Firebase) and star posts for me to browse through later.</p>
<p>That&#x27;s pretty much it. I use Feedbin every morning on my iPad Pro with my morning coffee. It&#x27;s a focused, dedicated place for me to catch up on a particular set of curated blogs, newsletters and news sources without getting distracted. And it helps unburden my inbox.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2020/10/copyright-paulstamatiou_com-IMG0050.jpg" alt="Feedbin Settings menu on my iPad Pro" />
<p>Feedbin only does a few things and I appreciate that it&#x27;s a relatively focused experience; not some overbearing tool. However, I do find myself wanting it to be a bit smarter in places.</p>
<p>I&#x27;d love to be able to tell it more generally what niche topics and phrases I&#x27;m interested in and have it more proactively prioritize these for me as well as learn as I engage with posts. I&#x27;d love to be able to apply those filters across links shared in Tweets from people I follow. And I&#x27;d like it to help me discover high-quality blogs about the topics I&#x27;m interested in.</p>
<p>I&#x27;d also like to be able to globally disable unread counts. I don&#x27;t want to have that kind of stressful inbox-like experience. I just want to be able to dip in and out as I please and not feel like I&#x27;m behind, as has always been my relationship with RSS readers in the past: an overbearing, incessantly incrementing unread counter.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2020/10/copyright-paulstamatiou_com-DSC05572-1000.jpg" alt="Feedbin on my iPad Pro" />
<small>Love my Heath mugs</small>
<p>Feedbin has an iOS app but there are lots of other RSS readers that let you log into your Feedbin account so you can maintain a synced consumption experience across devices. <a href="https://ranchero.com/netnewswire/">NetNewsWire</a>, <a href="https://reederapp.com/">Reeder</a> and <a href="https://www.goldenhillsoftware.com/unread/">Unread</a> are some of the popular ones.</p>
<p>If you follow any great blogs on the topics of iOS/SwiftUI development, design, software, startups or product development, I&#x27;d love to find more sites to subscribe to. Let me know on <a href="https://twitter.com/Stammy">Twitter</a> or <a href="https://paulstamatiou.com/contact">email</a>.</p>]]></description>
            <link>https://paulstamatiou.com/hello-rss</link>
            <guid isPermaLink="true">https://paulstamatiou.com/hello-rss</guid>
            <dc:creator><![CDATA[Paul Stamatiou]]></dc:creator>
            <pubDate>Sun, 18 Oct 2020 00:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Side projects]]></title>
            <description><![CDATA[<p>I have had some kind of side project for as long as I can remember. They have quenched my curiosity about new technologies and tools, kept my design and development skills fresh and often given me something to put out into the world.</p>
<p>Most of the time my side project has been this website. Redesigning it, debugging it, optimizing it, writing for it, shooting photos for it, editing photos for it, building out new functionality for it, managing servers and storage needs, et cetera.</p>
<p>For the last 6 months I have been working on a new side project (<a href="https://twitter.com/Stammy/status/1307353111896436739">thread</a>), a simple stocks-related app. It has helped me dive head-first into the world of Swift and SwiftUI, learn about Core Data, Cloudflare Workers, Sign In With Apple, TestFlight, Stripe Atlas, Firebase, Firebase Cloud Functions, Express.js, Hugo, Netlify and more. Not to mention that it has helped me sharpen my mobile, motion and visual design skills further.</p>
<p>Side projects give me a constraint-free creative outlet. I am the product manager, the researcher, the mobile designer, the web designer, the motion designer, the brand designer, the marketing designer, the mobile engineer, the backend engineer, the reliability engineer…</p>
<p>I can spend a month working on the animations of one view if I want. Everything is a blank canvas where I can try out different aesthetics, interactions, copy, motion and more. I can break as many design rules as I want. There are no gatekeepers or stakeholders.</p>
<p>I don&#x27;t set goals or deadlines for side projects—I fear they will start to feel like work then. It doesn&#x27;t matter it if takes me 4 weeks or <a href="https://twitter.com/Stammy/status/955482813825892352">4</a> <a href="https://twitter.com/Stammy/status/1186260455519600641">months</a> to write a blog post or even longer to <a href="https://twitter.com/Stammy/status/1034477412589830144">publish trip photosets</a> or ship an app. I’m just looking to make things the way I want.</p>
<p>Side projects keep me fulfilled on so many levels. I can’t imagine not having one on hand (well, ask me again when I have kids).</p>]]></description>
            <link>https://paulstamatiou.com/side-projects</link>
            <guid isPermaLink="true">https://paulstamatiou.com/side-projects</guid>
            <dc:creator><![CDATA[Paul Stamatiou]]></dc:creator>
            <pubDate>Mon, 05 Oct 2020 00:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Moving from Amazon S3 to Netlify]]></title>
            <description><![CDATA[<p>I recently began using <a href="https://www.netlify.com/">Netlify</a> for some of my side projects. Netlify is a modern web hosting provider that integrates a mix of offerings like a fast CDN and customizable build system. You specify how your website or project should be generated (ideal for static site generators like Jekyll) and all you do is run a git push when you&#x27;re ready to publish.</p>
<p>Netlify will automatically generate and deploy your site, optimize assets and images, provide access control and more. It also brings some desired functionality to static sites like <a href="https://www.netlify.com/products/forms/">built-in form handling</a> and server-side analytics.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2020/10/copyright-paulstamatiou_com-netlify-cd.png" alt="Netlify website settings" />
<small>Netlify website settings</small>
<p>While I was only using it for a basic landing page, I quickly began to admire how convenient it made the publishing process. Long story short, I moved this website to Netlify from my previous setup utilizing Amazon AWS S3 with CloudFront.</p>
<h3>My previous AWS S3 + Cloudfront setup</h3>
<p>I have been running this site for over 15 years now. The first few years I had a WordPress blog that I served on a bunch of devices ranging from a G4 Mac Mini in my dorm to a shared server and then to a VPS. Several years into that I wanted to change how I was publishing. I hated constantly updating the software due to security issues, keeping my VPS operating system and packages up to date and dealing with MySQL database backups (one of my early articles was about writing a bash script to save a <a href="https://paulstamatiou.com/how-to-bulletproof-server-backups-with-amazon-s3/">WordPress MySQL database dump to Amazon S3</a>).</p>
<p>I migrated my WordPress blog to Jekyll in late 2010 as part of my desire to simplify some of those performance and maintenance concerns. With Jekyll I had a site made up of fully static files and no database to worry about. I hosted my Jekyll site with Apache on an Ubuntu VPS for a while then landed on a Heroku setup with Rack::Static for a few years.</p>
<p>I eventually ended up <a href="https://paulstamatiou.com/hosting-on-amazon-s3-with-cloudfront/">hosting my site directly on S3 with CloudFront</a> and AWS Route53 for DNS. I favored this setup for its pure speed and lack of a real server I would have to manage in any capacity. Having everything on your site served at the edge directly from a CDN is a big deal. I remember receiving a few emails from readers outside the U.S. saying they noticed a performance boost on my site.</p>
<p>But the S3/CloudFront route felt like a hack. I relied on a Ruby gem to manually configure redirects (years ago I changed my permalink structure and have about a thousand redirects I need to keep around for old links) as well as invalidate CloudFront files each time I updated them. I also had to manage the site generation myself before deploying. Not a huge deal but it did mean I had to ensure I ran a few commands in the terminal in the correct sequence before deploying, and hanging around the terminal to ensure everything worked properly. I knew I needed to find a better solution when the gem I used for S3 deploys went into an unmaintained state.</p>
<h3>Why didn&#x27;t I migrate earlier?</h3>
<p>I first heard of Netlify several years ago. It seemed interesting but honestly I was not comfortable relying on a product from a relatively new startup for something as critical as hosting my sites.</p>
<p>Netlify the product kept getting better and Netlify the company kept growing, both in terms of employees, funding and customers. It was time to take a closer look.</p>
<p>At first glance I didn&#x27;t think Netlify was anything special. A hosting service that builds your site/app with a git hook before deploying was nothing new. And I did not even want that functionality at first. When I work on my long posts I commit to git dozens and dozens of times before publishing. I want my drafts backed up, but I also didn&#x27;t want to have to bother with a separate git branch for example.</p>
<p>Fortunately, there are several ways to manage your deploys with Netlify. Though for now I do have the default deploy-on-git-push behavior.</p>
<h3>Moving to Netlify</h3>
<p>The first step was authenticating my GitHub repository for this blog and seeing if Netlify could build it and deploy to a temporary site (Netlify issues you a subdomain of your choice on their <code>netlify.app</code> domain). This part took some trial and error with my Jekyll setup.</p>
<p>First, I needed to ensure all the Ruby gems I relied on were in my Gemfile so Netlify could install from that. I had to change a few things there. Second, I needed to find out how to get my SCSS and Coffeescript/JS generated. I figured I could just add the commands I usually run inline with the regular <code>jekyll build</code> command.</p>
<p>This part took some more trial and error. I couldn&#x27;t get it to run my Grunt (JavaScript task runner) commands. I used Grunt to compile, optimize and minify my SCSS, Coffeescript and JS files. For SCSS, I decided to move away from my Grunt setup and just use the <code>jekyll-sass-converter</code> Jekyll plugin to handle this for me easily. As for the Coffeescript, I used this as an opportunity to go back to JS files—something I had been wanting to do.</p>
<p>But that still left me with the task of how to concatenate and minify my JS files. Netlify has built-in asset optimization to do exactly this. It detects a series of <code>script</code> tags in your markup and bundles them all together to serve as one versioned file. This worked at first, then I realized that it wasn&#x27;t actually minifying the JS. I&#x27;m guessing it&#x27;s an issue on Netlify&#x27;s side after seeing someone else with the same issue, so I&#x27;ll have to revisit that later. For now I still have to compile the JS locally before deploying whenever I change it.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2020/10/copyright-paulstamatiou_com-netlify-asset-optim.png" alt="Netlify asset optimization settings" />
<small>Netlify asset optimization settings</small>
<p>The last thing I had to figure out was how Netlify handled redirects. There are two ways to configure redirects on Netlify, either with the <code>netlify.toml</code> config file or a separate plaintext <code>_redirects</code> file. I went with the latter as the format was similar to what I was using to manage URL redirects with the <a href="https://github.com/laurilehmijoki/s3_website">s3_website</a> gem. It only took a few find and replace all commands to the redirects file formatted properly.</p>
<p>I want to revisit the way I&#x27;m doing redirects (over 1,000+ for individual old articles when I changed my URL format years ago) and use a one-liner <a href="https://docs.netlify.com/routing/redirects/redirect-options/#placeholders">as described</a> in the documentation. Something like this:</p>
<pre><code class="language-plaintext"># I have lots of redirects like this for older posts
/2005/09/13/nero-7-announced    /nero-7-announced

# Will move to something like this
/:year/:month/:date/:slug  /:slug
</code></pre>
<p>At this point I had the site successfully building and deploying on Netlify. Here&#x27;s what my <code>netlify.toml</code> file looks like below. My setup is fairly basic so everything here can be controlled on the Netlify website as well.</p>
<pre><code class="language-bash">[build]
  publish = "_site/"
  command = "jekyll build"
[build.processing]
  skip_processing = false
[build.processing.css]
  bundle = true
  minify = true
[build.processing.js]
  bundle = true
  minify = true
[build.processing.html]
  pretty_urls = true
[build.processing.images]
  compress = false
</code></pre>
<p>The only thing left was updating the DNS to point to Netlify. To make this as smooth as possible I first logged into AWS and visited the Route53 dashboard to see all the DNS records attached to my domain. One by one I added the exact same DNS records to Netlify&#x27;s DNS. There there were quite a few records as I use both G Suite and Amazon SES on this domain.</p>
<p>I waited a while for Netlify&#x27;s DNS servers to add those rules and then I made the final change to update the DNS servers on the domain to point to Netlify&#x27;s DNS servers. Moments later the domain started loading my site on Netlify and then after that the SSL certificate was running.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2020/10/copyright-paulstamatiou_com-netlify-deploy-log.png" alt="Netlify dashboard showing a completed build and deploy." />
<small>Netlify dashboard showing a completed build and deploy.</small>
<h3>A note about media uploads</h3>
<p>While I migrated my blog to Netlify, I still keep my media assets hosted separately with S3 with CloudFront as I have for many years. I originally did this for a few reasons I mention on my <a href="https://paulstamatiou.com/about-this-website/#photos">About this website page</a>. The main one being that I don&#x27;t want ~30GB of media in my main git repository.</p>
<p>Netlify has a solution for this with their <a href="https://docs.netlify.com/large-media/overview/">Large Media feature</a> that uses Git LFS to store media, but I haven&#x27;t looked into that too much.</p>
<h3>Netlify first impressions</h3>
<p>I&#x27;m only a week into my new Netlify setup but I&#x27;m really loving it so far. Here are some of my initial thoughts:</p>
<ul>
<li><strong>Worry-free deploys:</strong> I&#x27;m coming around to this build system way of pushing git and knowing it will do everything it needs to build, optimize and deploy. I had something similar for my staging site back when I was writing on my iPad Pro and before I had my code-server VPS—each push would trigger AWS CodeBuild to deploy to a CloudFront distribution. Though that wasn&#x27;t a great experience for a staging server I was using for quick previews (having to wait a minute or more before the deploy is done), it&#x27;s fine for regular production deploys. I should also mention that with Netlify I can easily rollback to a previous deploy if needed.</li>
<li><strong>Built-in form handling:</strong> This was a really, really nice perk. With a static site hosted on S3 there was no backend that could accept any contact form POSTs; I had to use a hosted contact form from another service. Netlify has some magic attributes like <code>data-netlify="true"</code> you can apply to forms to get form handling and spam prevention.</li>
<li><strong>Asset optimization:</strong> I would love nothing more than to ditch all of my local asset pipeline management like concatenating CSS/JS files and minifying. Netlify handles this all for you (though as I noted I couldn&#x27;t get it to minify my JS for some reason but I&#x27;m sure that will be resolved soon).</li>
<li><strong>Server-side analytics:</strong> This is neat. Previously if I wanted server-side analytics I would have to enable S3/CloudFront logging and then use a tool (either paid or self-host) to read through the logs. While I don&#x27;t think I&#x27;ll use it forever as it&#x27;s rather pricey add-on at $9/month with far less functionality than dedicated analytics tools, it&#x27;s a great resource for seeing things like what bots are accessing or what 404s I may need to fix.</li>
</ul>
<img src="https://turbo.paulstamatiou.com/uploads/2020/10/copyright-paulstamatiou_com-netlify-analytics.png" alt="Netlify website analytics" width="2000" height="2174" /><br /><br /><img src="https://turbo.paulstamatiou.com/uploads/2020/10/copyright-paulstamatiou_com-netlify-analytics-2.png" alt="Netlify website analytics" width="2000" height="1748" />
<small>Netlify website analytics</small>
<ul>
<li><strong>Build times could be better:</strong> While it&#x27;s not a huge inconvenience, I do think build and deploy times could be faster, especially with the Pro plan that I&#x27;m on. It feels like they can vary between 1-4 minutes. Sometimes it goes by quickly and sometimes it takes more time between each file (maybe not cached?). I also think it must be running on some not-so-great hardware if it takes about 7.5 seconds to generate my jekyll site; something that takes 3.5-4 seconds on my MacBook Pro.</li>
</ul>
<h3>What&#x27;s next</h3>
<p>I&#x27;m trying to make it easier for me to write and publish articles, especially with my new focus on <a href="https://paulstamatiou.com/writing-more/">writing more</a> with these short-form posts. Netlify has been a huge help here by reducing some of the friction around deploys.</p>
<p>Other things top of mind for making it easier to publish include migrating away from Jekyll to a faster static site generator like <a href="https://twitter.com/Stammy/status/1307347164599922689">Hugo</a> and considering an admin front-end for my site generator like <a href="https://www.netlifycms.org/">Netlify CMS</a>.</p>
<p>For about a year now I have been using a <a href="https://paulstamatiou.com/about-this-website/#dev_env">Lightsail VPS running VSCode code-server</a> that I can access from any computer to write and deploy to my site. However, I&#x27;m now <a href="https://github.com/features/codespaces">trying out GitHub Codespaces</a>, which is basically the same thing.</p>
<p>I&#x27;m also exploring simplifying my local writing process by trying <a href="https://nova.app/">Nova.app from Panic</a> to have an all-in-one writing, dev and preview experience—no need to flip between 3 apps (Chrome, iTerm2, Atom). Though I wish I could figure out how to get a live browser preview with Live Reload working as mentioned on their homepage.</p>
<img src="https://turbo.paulstamatiou.com/uploads/2020/10/copyright-paulstamatiou_com-coda-app-1500.jpg" alt="Nova.app native Mac code editor" />
<small>Nova, the native Mac code editor</small>]]></description>
            <link>https://paulstamatiou.com/moving-from-amazon-s3-to-netlify</link>
            <guid isPermaLink="true">https://paulstamatiou.com/moving-from-amazon-s3-to-netlify</guid>
            <dc:creator><![CDATA[Paul Stamatiou]]></dc:creator>
            <pubDate>Sun, 04 Oct 2020 00:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[Writing more]]></title>
            <description><![CDATA[<p>I&#x27;m going to try something different and write more short-form posts here.</p>
<p>Over the years my focus has been increasing the quality of my articles. They&#x27;ve ended up becoming increasingly time-consuming to create. The same goes for my photosets, which also often require a bit of custom design and development in addition to the many hours photo culling and editing.</p>
<p>While that will not change and I thoroughly enjoy spending months of spare time sharing details about subjects and projects that interest me, there&#x27;s often a lot of stuff I would want to share here in between those ~annual, in-depth posts. These would be the types of posts that don&#x27;t really meet my quality bar to deserve my typical long-form post process and treatment.</p>
<p>I want to get back to what blogging felt like when I started in 2005. Back when posting a few sentences and publishing it within the same computing session was so easy and fun. Where expectations were low and it didn&#x27;t have to be perfect.</p>
<p>So I&#x27;m going to experiment with a section of my site for short little posts and updates. I want to share things I&#x27;m <a href="https://twitter.com/Stammy/status/1307353111896436739">learning with Swift and Swift UI</a>, how I&#x27;m thinking about certain design challenges with my side-projects, new products I&#x27;m using and more. I still plan to invest my time in long-form posts when it makes sense, but just want another outlet for different things.</p>
<p>As such, it felt like I would need to make a few layout changes for these posts to feel more casual and less refined. These short-form posts—which I don&#x27;t have a name for yet—have smaller text, a narrower layout and generally less stuff. As of now I have a little module on the homepage for these, but may change how and where I display these posts.</p>
<p>Let me know what you think via <a href="https://twitter.com/Stammy">Twitter</a> or <a href="https://paulstamatiou.com/contact">email</a> as I try this out. These new posts will be incorporated into my <a href="https://paulstamatiou.com/posts.xml">existing RSS feed</a> if you&#x27;d like to follow along there (I&#x27;ve been using <a href="https://ranchero.com/netnewswire/">NetNewsWire</a> for RSS feeds lately).</p>]]></description>
            <link>https://paulstamatiou.com/writing-more</link>
            <guid isPermaLink="true">https://paulstamatiou.com/writing-more</guid>
            <dc:creator><![CDATA[Paul Stamatiou]]></dc:creator>
            <pubDate>Sat, 03 Oct 2020 00:00:00 GMT</pubDate>
        </item>
    </channel>
</rss>