<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:base="https://shub.club">
  <title>shub.club - Blog Posts</title>
  <subtitle>Latest writings and thoughts</subtitle>
  <link href="https://shub.club/feed/posts.xml" rel="self"/>
  <link href="https://shub.club/"/>
  <updated>2026-04-19T00:00:00Z</updated>
  <id>https://shub.club/feed/posts.xml</id>
  <author>
    <name>Shubham Naik</name>
    <email>hello@shub.club</email>
  </author>
  <entry>
    <title>Why do people keep stealing the small sauce bottle?</title>
    <link href="https://shub.club/writings/2026/april/why-do-people-steal-the-small-sauce-bottle/"/>
    <updated>2026-04-19T00:00:00Z</updated>
    <id>https://shub.club/writings/2026/april/why-do-people-steal-the-small-sauce-bottle/</id>
    <content xml:lang="en" type="html">&lt;p&gt;Restaurants in San Francisco sure love exclusivity. I got a random email from OpenTable from TBD, a new restaurant taking over the old Akkikos space on Bush - still run by the Akkiko’s team, but now focusing on izakaya style food instead of sushi&lt;/p&gt;
&lt;p&gt;One of the dishes I tried was their karrage hot chicken. It came with a sauce bottle with their secret spicy sauce. Sour and sweet, it’s a great edition to this bird.&lt;/p&gt;
&lt;p&gt;As the staff came around to pick up my plates, I was a little sad as they took away the bottle. I asked them if I could keep it, but the waiter told me that people have taken them too often and they’re low on bottles.&lt;/p&gt;
&lt;p&gt;I was a bit astounded, this is an exclusive restaurant, was this sauce that good that people were down to steal it from a place where you couldn&#39;t even walk in, you had to get a reservation through OpenTable, thus knowing exactly who was sitting where and when?&lt;/p&gt;
&lt;p&gt;No; it wasn’t that amazing, it was good, but I think the bottle’s design could give us some insight on how product design can effect behavior of users.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://shub.club/writings/2026/april/why-do-people-steal-the-small-sauce-bottle/chicken.jpg&quot; alt=&quot;chicken&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Sorry for the image, it’s just on the right, but if you notice, it’s quite small, unmarked and made of just plastic.&lt;/p&gt;
&lt;p&gt;When deciding how to even package a product, one should consider how people’s existing biases affect the utility of a product itself. If you design something to look like a squeeze bottle, even if you make it out of glass; people will attempt to squeeze.&lt;/p&gt;
&lt;p&gt;The most famous example, if you pull from books like “The Design of Everyday Things” by Don Norman is the Norman Door itself: doors that look like they can be pushed or pulled, but only actually work a single way, leading most of these doors to have to be labeled.&lt;/p&gt;
&lt;p&gt;Now back to this sauce bottle; I think there’s an intersection of a few biases at play. The first is the bottle is diminutive yet reasonably sized: it doesn’t hold a lot of sauce, but it holds enough for maybe two or three chickens, giving incentive to use it again, maybe at home. It&#39;s sealable, you can just lock it up and pack it up. The bottle is very basic, it looks like a bottle that someone could easily pay in bulk a dollar or less for, plastic, they won&#39;t mind that it&#39;s gone.  Finally it’s also unmarked, which could give a negative bias to as well, usually restaurants that want you take things home, would give a label or mark to it, but it could also bring people to think it’s not meaningful if the bottle was gone either.&lt;/p&gt;
&lt;p&gt;Now for the restauranteur, what is the solution I propose? I think you should just not let the bottle be sealed. When there’s no seal, it becomes infinitely harder for someone to sneak it out, and even those with good intentions, when you see a open container or a container with an unclosable opening it signals that this product, like a plate or a cup is part of the restaurant’s ecosystem, where it will be used for every other guest; clean, reused, refilled and again and again.&lt;/p&gt;
&lt;p&gt;Will this prevent all theft? Probably not, some people have no decorum, but it would definitely drift from a common occurrence to anomaly in the restaurant’s lifespan.&lt;/p&gt;
&lt;location image=&quot;./tuna_wellington.jpeg&quot; caption=&quot;Tuna wellington at TBD&quot; name=&quot;TBD&quot; address=&quot;431 Bush St, San Francisco, CA 94108&quot;&gt;
&lt;div class=&quot;location-helper-wrapper&quot;&gt;&lt;span class=&quot;location-name&quot;&gt;TBD&lt;/span&gt;&lt;div class=&quot;location-image-wrapper&quot;&gt;&lt;img alt=&quot;Tuna wellington at TBD&quot; src=&quot;https://shub.club/writings/2026/april/why-do-people-steal-the-small-sauce-bottle/tuna_wellington.jpeg&quot; class=&quot;location-image&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;location-helper&quot;&gt;
        &lt;span&gt;431 Bush St, San Francisco, CA 94108&lt;/span&gt;&lt;span class=&quot;links&quot;&gt;
&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://www.openstreetmap.org/search?query=431%20Bush%20St,%20San%20Francisco,%20CA%2094108&quot;&gt;
    &lt;img alt=&quot;OpenStreetMap Logo&quot; src=&quot;https://shub.club/icons/openstreetmap.png&quot; class=&quot;location-icon&quot; /&gt;
&lt;/a&gt;
&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;http://maps.apple.com/?address=431%20Bush%20St,%20San%20Francisco,%20CA%2094108&amp;amp;dirflg=t&quot;&gt;
    &lt;img alt=&quot;Apple Maps Logo&quot; src=&quot;https://shub.club/icons/apple-maps.svg&quot; class=&quot;location-icon&quot; /&gt;
&lt;/a&gt;
&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://www.google.com/maps/search/?api=1&amp;amp;query=431%20Bush%20St,%20San%20Francisco,%20CA%2094108&quot;&gt;
    &lt;img alt=&quot;Google Maps Logo&quot; src=&quot;https://shub.club/icons/google-maps.png&quot; class=&quot;location-icon&quot; /&gt;
&lt;/a&gt;
&lt;/span&gt;
    &lt;/div&gt;
&lt;/div&gt;&lt;/location&gt;
</content>
  </entry>
  <entry>
    <title>A type of bike theft in San Francisco</title>
    <link href="https://shub.club/writings/2026/april/a-type-of-bike-theft/"/>
    <updated>2026-04-16T00:00:00Z</updated>
    <id>https://shub.club/writings/2026/april/a-type-of-bike-theft/</id>
    <content xml:lang="en" type="html">&lt;p&gt;On the intersection of Market and Bush lies Mechanics monument Plaza, an unassuming urban space with a table tennis court. Across the plaza sits Boichick bagel, a very yummy place to grab some schmere.&lt;/p&gt;
&lt;p&gt;On a day earlier this month I had went to pick up some bagels for work, I usually ride down and prop my bike nearby and lock up, but this time I was in a rush, so I propped my bike by the door.&lt;/p&gt;
&lt;p&gt;I placed my order and stood by; staring out into the city, I noticed a woman in a pink helment on a nice ebike ride along the plaza, eventually coming past my bike.&lt;/p&gt;
&lt;p&gt;I was in clear view of my bike indoors, but at an angle where someone from the outside of the store could not see me. I noticed she gazed upon my bike, possibly because it kinda was in the way of the line, which at this point was approaching to head out the door.&lt;/p&gt;
&lt;p&gt;She suddenly grabs for my bike, in an attempt to move it perhaps, but I stop her and tell her that I&#39;m not in line, and would move my bike if it was in her way.&lt;/p&gt;
&lt;p&gt;She stops for a second and looks at me and tells me that she wasn&#39;t joining the line, and instead wanted to play table tennis with me.&lt;/p&gt;
&lt;p&gt;I&#39;m off put, but eventually tell her that I have to go to work, so couldn&#39;t. She scoots off and I think I&#39;m done with that, my bagel isn&#39;t still ready, so I watch her as she bikes towards another man sort of out of view, near some pillars, then eventually she moves to look at other bikes.&lt;/p&gt;
&lt;p&gt;Normally I&#39;d just take this as a strange, but usual San Francisco interaction, but I have a feeling this was a scouter for a two man bike theft operation.&lt;/p&gt;
&lt;p&gt;I could be wrong though, just a thought.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://shub.club/writings/2026/april/a-type-of-bike-theft/bagel.jpeg&quot; alt=&quot;Bagels&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Boichick Bagel&lt;/h2&gt;
&lt;location address=&quot;22 Battery St, San Francisco, CA 94111&quot;&gt;
&lt;div class=&quot;location-helper-wrapper&quot;&gt;
    &lt;div class=&quot;location-helper&quot;&gt;
        &lt;span&gt;22 Battery St, San Francisco, CA 94111&lt;/span&gt;&lt;span class=&quot;links&quot;&gt;
&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://www.openstreetmap.org/search?query=22%20Battery%20St,%20San%20Francisco,%20CA%2094111&quot;&gt;
    &lt;img alt=&quot;OpenStreetMap Logo&quot; src=&quot;https://shub.club/icons/openstreetmap.png&quot; class=&quot;location-icon&quot; /&gt;
&lt;/a&gt;
&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;http://maps.apple.com/?address=22%20Battery%20St,%20San%20Francisco,%20CA%2094111&amp;amp;dirflg=t&quot;&gt;
    &lt;img alt=&quot;Apple Maps Logo&quot; src=&quot;https://shub.club/icons/apple-maps.svg&quot; class=&quot;location-icon&quot; /&gt;
&lt;/a&gt;
&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://www.google.com/maps/search/?api=1&amp;amp;query=22%20Battery%20St,%20San%20Francisco,%20CA%2094111&quot;&gt;
    &lt;img alt=&quot;Google Maps Logo&quot; src=&quot;https://shub.club/icons/google-maps.png&quot; class=&quot;location-icon&quot; /&gt;
&lt;/a&gt;
&lt;/span&gt;
    &lt;/div&gt;
&lt;/div&gt;&lt;/location&gt;
</content>
  </entry>
  <entry>
    <title>Are we building IDEs for engineers anymore?</title>
    <link href="https://shub.club/writings/2026/april/who-are-these-ides-for/"/>
    <updated>2026-04-01T00:00:00Z</updated>
    <id>https://shub.club/writings/2026/april/who-are-these-ides-for/</id>
    <content xml:lang="en" type="html">&lt;p&gt;Cursor 3 came out - it looks cool, lots of nifty agentic features - but something kinda burns in the back of my head. Who are the audience for these things?&lt;/p&gt;
&lt;p&gt;I was originally going to write about the two new visions for software development interfaces, one, like codex where it defers all agency to your agent. They let you open your code in an IDE, but really the goal is to maximize your agent to do all the work, even leaving comments on code instead of letting you edit the diffs themselves. Then there was the Cursor 2/Zed/IntelliJ paradigm where you as the developer have the option to choose if your agent will help you for tasks. Originally I thought both were sort of missing the point of agentic development, but I think they would eventually converge into something practical for an average developer.&lt;/p&gt;
&lt;p&gt;But I think this new Cursor 3 seems to have fallen for the Codex FOMO, and is starting to just mirror the paradigm of an solely-agentic powered builder. Agency as a developer will soon be secondary to your dependence on an LLM. Modes like the visual editor on the surface are really cool; but any experienced developer could probably make the same edits in the faster time, and for cheaper.&lt;/p&gt;
&lt;p&gt;This is the ultimate goal for agent based software companies, as your revenue comes from asking your agent to do things for you, not if the user is doing it themselves. Cursor 3, you can’t use without signing in anymore (or at least, it’s pretty hard to get around the login screen).&lt;/p&gt;
&lt;p&gt;That brings us to the question; who are we building these IDEs for? If it’s for someone who isn’t technical, this is great; this gives people who want to build, a new tool. But for me as an engineer adding more and more layers of abstraction from the code, especially since models aren’t perfect, seems like a strategy in making things that were once simple, expensive.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Are Minecraft&#39;s new mobs a hedge against Robolox?</title>
    <link href="https://shub.club/writings/2026/march/are-minecrafts-new-mobs-a-hedge-on-robolox/"/>
    <updated>2026-03-22T00:00:00Z</updated>
    <id>https://shub.club/writings/2026/march/are-minecrafts-new-mobs-a-hedge-on-robolox/</id>
    <content xml:lang="en" type="html">&lt;p&gt;Minecraft just has their annual Minecraft Live: their annual showcase of the &amp;quot;big update&amp;quot; of the year. I still play Minecraft occasionally when I’m feeling bored and creative, so I keep attention from time to time.&lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/lmVlB8KBtlQ?si=hJSkIro6T-QBtStu&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
&lt;p&gt;One thing I noticed from this year’s announcement was the addition of the Sulfur Cube. The sulfur cube is kinda strange, it’s a mob like the existing slime, where it bounces around, but its primary purpose unlike every other mob is to take just take a beating but not to be killed. When you hit it, it just bounces around, and it also can take in an input of any block in the game, and its physics suddenly change.&lt;/p&gt;
&lt;p&gt;This pretty cool, but it seems generally a big departure from the typical modern mobs that they make in Minecraft, which is a mob that its utility comes from the resources it generates, not the mob itself.&lt;/p&gt;
&lt;p&gt;Minecraft gave a few demos of use cases. Almost all of them were to create mini-games like cube soccer and cube bowling. Because of this, the mob sort of doesn’t fit in the game progression for a typical player of survival. There’s not much use for it beyond building it for entertainment.&lt;/p&gt;
&lt;p&gt;Roblox is also another creative-cube young-people-focused game that one could say is in a similar league to Minecraft. They both operate around a similar demographic, though Minecraft seems to skew older from just anecdotes. While numbers aren’t easy to get for Minecraft, Roblox has around &lt;a href=&quot;https://brands.roblox.com/metrics-insights&quot;&gt;150m DAU&lt;/a&gt; and this number has been growing every month for the last decade. It certainly eclipsed Minecraft in revenue generation, as its marketplace and modding is tightly controlled, which I think Microsoft would probably love to have too.&lt;/p&gt;
&lt;p&gt;Minecraft for the longest time has been playing catch-up for extracting revenue from users, even when it was clearly ahead of Roblox for much of the last decade. The Minecraft strategy team has been trying harder and harder to move people to Bedrock - which has a revenue-generating marketplace.&lt;/p&gt;
&lt;p&gt;I think though for the largest time, Roblox’s edge against Minecraft is that it’s much more open ended, you can even create Minecraft in Roblox; but Minecraft’s edge is that it’s more directed, making it easier to those who just start playing are able to get it; versus Roblox requires at least some network effect to understand its value.&lt;/p&gt;
&lt;p&gt;The thing is, with 150DAU, the network effect is strong; and every other kid (source my little cousins) has Roblox and wants to get their friends on Roblox too, and one of those big drivers is the ability to play any game in their game.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://shub.club/writings/2026/march/are-minecrafts-new-mobs-a-hedge-on-robolox/sulfur-cube.png&quot; alt=&quot;Sulfur Cube&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This new mob, which basically acts as a ball, hockey puck or whatever that the physics lets you, is as a new entry point for new players that helps create environments that mirror Roblox in a way. Minecraft while still a game primarily about building things, but it also is just an environment for people to do things in; we’ve seen it even in the early ages with people playing minecraft soley to &lt;a href=&quot;https://www.youtube.com/watch?v=6S_5dR2zPOk&quot;&gt;do parkour&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Minecraft is platform to do anything, but it&#39;s pretty restrictive in physics, you as the user could jump, swim, build and fight, but you couldn&#39;t interface with entities beyond destroying them or toggling a switch. With this cube, you can unlock so many more concepts that will bring new eyes and mindshare to the almost 20 year old game. (it&#39;s almost 2029...)&lt;/p&gt;
&lt;p&gt;This new sulfur cube is another step in its war against Roblox, Fortnite (to an extent) and other “sandbox platform games”. I know I’ll be trying to build a soccer field in my server with this.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>A reminder to check your inactive account passwords</title>
    <link href="https://shub.club/writings/2026/march/rotate-your-passwords/"/>
    <updated>2026-03-16T00:00:00Z</updated>
    <id>https://shub.club/writings/2026/march/rotate-your-passwords/</id>
    <content xml:lang="en" type="html">&lt;p&gt;I stopped using instagram a while ago, but one thing I did was keep my account around so that there would be a less likely chance that someone could impersonate me with a new account.&lt;/p&gt;
&lt;p&gt;One thing I noticed, the longer I’ve had my account inactive, the more emails I get from Meta about attempted password recovery, attempted logins or general signs of someone trying to crack my account. I was chatting to a friend about this, and he made a good point: inactive but real accounts have a higher risk of compromise.&lt;/p&gt;
&lt;p&gt;An inactive user is probably not checking their account at all and maybe doesn&#39;t even remember their own password – which for most people, probably is a shared password.&lt;/p&gt;
&lt;p&gt;I can state the obvious – shared passwords are bad, but it&#39;s common, and even if it&#39;s a great password, an unrelated service could get hacked or leaked and suddenly a hacker could reuse those credentials to stuff your inactive account.  (heck - if instagram itself gets hacked, even your unique password can get compromised, though most services would force a password reset)&lt;/p&gt;
&lt;p&gt;If you do plan on keeping your inactive accounts around, make sure they have unique passwords -- or if it&#39;s not a vector for impersonation, just delete it, save yourself from more unnecessary ads 🐮&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Is Outside Lands becoming Portola?: a quantitative analysis</title>
    <link href="https://shub.club/writings/2026/march/is-outsidelands-becoming-portola/"/>
    <updated>2026-03-08T00:00:00Z</updated>
    <id>https://shub.club/writings/2026/march/is-outsidelands-becoming-portola/</id>
    <content xml:lang="en" type="html">&lt;p&gt;Outside Lands (OSL) just dropped their linup for their 2026 show, and one curious thing seems a bit present when looking at all the artists. I&#39;ll give you a second to tell me what&#39;s interesting below:&lt;/p&gt;
&lt;img alt=&quot;Charli xcx,RÜFÜS DU SOL,The Strokes,The xx,Baby Keem,Turnstile,Subtronics (GRIZTRONICS),GRiZ (GRIZTRONICS),Djo,Labrinth,Empire Of The Sun,Dijon,Disco Lines,Death Cab for Cutie,GloRilla,Ethel Cain,Geese,Mariah the Scientist,Modest Mouse,Not for Radio,Clipse,Lucy Dacus,Wet Leg,it&#39;s murph,Sierra Ferrell,Malcolm Todd,Lane 8,Snow Strippers,Boris Brejcha,Odd Mob (Odd Mob and OMNOM present HYPERBEAM),OMNOM (Odd Mob and OMNOM present HYPERBEAM),Tinashe,Audrey Hobert,Ben Böhmer,JADE,The Temper Trap,The Story So Far,kwn,¥ØU$UK€ ¥UK1MAT$U,KI/KI,DJ Trixie Mattel,Łaszewo,SIENNA SPIRO,DESTIN CONRAD,Boys Noize,Durand Bernarr,Kingfishr,ALLEYCVT,Balu Brigada,Sultan + Shepard,Frost Children,Miss Monique,Die Spitz,Carlita,MPH,Silvana Estrada,Momma,Dylan Brady,Goldie Boutilier,Haute &amp; Freddy,Tobiahs,Wunderhorse,Amble,Sports,Yard Act,Faouzia,Infinity Song,Billie Marten,Marlon Funaki,camoufly,Night Tapes,Bandalos Chinos,Jim Legxacy,X CLUB.,Luke Alessi,After,Bad Nerves,Chezile,RIO KOSTA,sosocamo,Automatic,Sawyer Hill,1-800 GIRLS,NEZZA,Red Leather,Racing Mount Pleasant,Day We Ran,Britton,Cruz Beckham,RYMAN,Vertigo&quot; class=&quot;full-screen&quot; src=&quot;https://shub.club/writings/2026/march/is-outsidelands-becoming-portola/poster.png&quot; /&gt;
&lt;p&gt;Ok, it&#39;s a bit hard, but most of the people listed are electronic artists. Now, there&#39;s nothing wrong with electronic; I like electronic music; the bay loves electronic music, they made a whole specialized music festival that&#39;s like a month after Outside Lands that just does mostly electronic music (Portola).&lt;/p&gt;
&lt;p&gt;My question though is when did Outside Lands end up being Portola light? I decided to do some quantitative analysis to see if we&#39;re going to see OSL 2028 have the exact same artists at Portola 2028.&lt;/p&gt;
&lt;h2&gt;Getting the Data&lt;/h2&gt;
&lt;p&gt;The first thing we need is to grab some data; we already have who&#39;s playing at event, but we need to know what genre of music each artist does, which TBH could be very painstaking work, seeing how there&#39;s like 100 artists a year. Fortunatly, Outside Lands has a very passionate reddit community, and one guy  &lt;a href=&quot;https://www.reddit.com/user/undeadsinatra/&quot;&gt;/u/undeadsinatra&lt;/a&gt; has been making genre+artist lists every year, so I had to thank them for making it &lt;a href=&quot;https://www.reddit.com/r/OutsideLands/comments/1rk9mzk/outside_lands_2026_by_genre/&quot;&gt;easy&lt;/a&gt; for me to do this!!&lt;/p&gt;
&lt;img style=&quot;width: 325px;&quot; alt=&quot;A picture of the reddit link above&quot; class=&quot;float-left&quot; src=&quot;https://shub.club/writings/2026/march/is-outsidelands-becoming-portola/sources.webp&quot; /&gt; 
&lt;p&gt;undeadsinatra had been posting for a long time, but let&#39;s just focus from 2021-2026. I think to get a real trend, we could go further, but I think even this 5 year window we can get some good numbers. The early 2020&#39;s could be seen as the tail end of the hip-hop era of the last twoish decades, so I think we could probably see a rapid change here.&lt;/p&gt;
&lt;p&gt;One thing to note is the data is a bit specific, undeadsinatra went very hard into giving very specific genres for each artist. I think for our analysis we only needed to worry about super-genres: Rock, Hip Hop and R&amp;amp;B, Electronic, Folk, Jazz and Country. So what do we do now? It&#39;s around 610 artists we&#39;d need to classify; fortunately, we live in a post LLM world, so I just threw these unstructured lists data into Letta Code and told it to make me a &lt;a href=&quot;https://shub.club/writings/2026/march/is-outsidelands-becoming-portola/osl_artists.csv&quot;&gt;spreadsheet&lt;/a&gt; with all the artists and genres.&lt;/p&gt;
&lt;p&gt;I also added a column called &lt;code&gt;is_soma_tent&lt;/code&gt;, because Outside Lands does have a EDM specific dancefloor, but I did not want to count that in our final totals since those DJs operate in their own little cultural bubble.&lt;/p&gt;
&lt;h2&gt;The Analysis&lt;/h2&gt;
&lt;img alt=&quot;100% stacked bar chart showing the percentage distribution of artist genres at Outside Lands from 2021 to 2026. Each bar totals 100%, with segments representing each genre&#39;s share. Electronic (purple) and Rock (red) consistently make up the largest portions, typically comprising 25-35% each. Hip-Hop / R&amp;B + Soul (green) represents approximately 15-20% across years. Pop (yellow) shows modest representation at 8-12%. Folk, Country, Other, and Jazz make up smaller segments. The distribution remains relatively stable across years, with Hip-Hop / R&amp;B + Soul dominating in 2021 and Electronic leading in 2026. Chart excludes SOMA Tent artists.&quot; class=&quot;full-screen&quot; src=&quot;https://shub.club/writings/2026/march/is-outsidelands-becoming-portola/genre_percentages.png&quot; /&gt; 
&lt;p&gt;So what do we get when we visualize this data? We do start seeing a tend, in 2021 we see electronic only making up 17% of total artists at Outside Lands slowly growing until 2023, where they made up almost 40% of artists. 2025 and 2026, slightly less, 35% and 37% respective, but given that we have  5 other genres, it&#39;s definitely overrepresented.&lt;/p&gt;
&lt;p&gt;Jazz and country have always been lacking at OSL, but if we compare it to their big contemporaries of Hip Hop, R&amp;amp;B and Rock, and Pop, we can see a trend that Hip-Hop is on the way out, Rock and Pop are somewhere always in the middle, and Electronic is dominating.&lt;/p&gt;
&lt;p&gt;I think Outside Lands is being strategic in following the zeitgeist here. Portola started because there was a enough of lack of electronic music at OSL to create a market for a completely seperate music festival, now that OSL is chasing electronic fans, it may require Portola to adapt to the headwinds. Music festivals are expensive, especially Portola and OSL, college students and young adults make up the majority of the clientel of these events and they&#39;re famously broke.&lt;/p&gt;
&lt;p&gt;One thing to note is that many of the big electronic artists at OSL, especially this year already played at Portola. Does this dilute the brand? Does it make them seem like they&#39;re followers, or do people even care, they get to see their fav artists every year in a new venue (most likely)&lt;/p&gt;
&lt;p&gt;I&#39;ll have to see what Portola does to challenge OSL, will they stick to their guns and be the premier electronic music festival, or will they try to bite back and add more non-electronic artists to their roster.&lt;/p&gt;
&lt;h2&gt;Is Folk the next big thing?&lt;/h2&gt;
&lt;p&gt;If we look at the trendlines, one other genre is slowly trickling up, and that&#39;s Folk. I don&#39;t really know why that is, or if that means anything. Will Folk replace electronic? Not sure, but if you told me in 2010 hip hop would be replaced by electronic I&#39;d tell you that &amp;quot;&lt;a href=&quot;https://youtu.be/YVkUvmDQ3HY?si=YBTVnFLUoQY9-SRE&amp;amp;t=190&quot;&gt;It&#39;s over, nobody listens to techno&lt;/a&gt;&amp;quot;&lt;/p&gt;
&lt;p&gt;Thank you again &lt;a href=&quot;https://www.reddit.com/user/undeadsinatra/&quot;&gt;/u/undeadsinatra&lt;/a&gt; for the data! Feel free to use my cleaned up &lt;a href=&quot;https://shub.club/writings/2026/march/is-outsidelands-becoming-portola/osl_artists.csv&quot;&gt;spreadsheet&lt;/a&gt; for your own analysis.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>The death of the case study</title>
    <link href="https://shub.club/writings/2026/january/death-of-the-case-study/"/>
    <updated>2026-01-21T00:00:00Z</updated>
    <id>https://shub.club/writings/2026/january/death-of-the-case-study/</id>
    <content xml:lang="en" type="html">&lt;p&gt;When I was early in my career, I often looked at case studies with uninterest. If I wanted to test software, I&#39;d just do it. There&#39;s a limited time cost to me, I could install it, see if it works, and if it doesn&#39;t, just move on.&lt;/p&gt;
&lt;p&gt;Now, 10 years later, it&#39;s a bit different, priorities have shifted and I do look at case studies for software with some weight. I do want to know how our peers are using the software and what benefit they got out of it, a 15 minute read is faster than installing or setting up an account.&lt;/p&gt;
&lt;p&gt;Now case studies aren&#39;t really what you typically consider &amp;quot;technical content&amp;quot;, but I can assure you, a good case study is a mix of marketing and a mix of explaining how a problem was solved with software.&lt;/p&gt;
&lt;p&gt;The problem now though is that case studies are now the cannon fodder of AEO (Answer Engine Optimization; the AI version of SEO), and sure; case studies are also SEO bait, but in the era before AI summaries, people did read them.&lt;/p&gt;
&lt;p&gt;Most case studies I come across now have become unreadable. There are a few funded startups that sell you essay autogenerators to boost SEO and because of it, you get the exact same AI generated drivel that you;d see in a Google result summary but overindulgent and spread over multiple paragraphs and partitions.&lt;/p&gt;
&lt;p&gt;Of course this is intentional, this is what the Google summaries base their content on, one could say technical content in general is being watered down to become AI bait, similar to how cooking recipies have a long essay before the actual recipe to get SEO points.&lt;/p&gt;
&lt;p&gt;With so much non-content to trick AI scrapers into indexing your content, the stuff is barely proofread, the sales team just hope people would see the brand names using the product as enough of a case to use it. One such case was so bad I experienced, the essay kept referencing my employer&#39;s CEO as an regular engineering employee.&lt;/p&gt;
&lt;p&gt;Now look - I wish I had AI when I was a student for sure, I&#39;d love to not write essays -- but now that I have to read them for a living (and sure, I can get an AI summary), it really seems that I lucked out to live in an era before this.&lt;/p&gt;
&lt;p&gt;Of course there was plenty of badly written work in the past, most engineers don&#39;t know how to write beyond a engineering doc, but in an era where even the marketing staff is forced for &amp;quot;efficiency&amp;quot; sake to push our AEO content, I feel like it can be a superpower if you know how to properly condense, summarize and write technical content in your own words.&lt;/p&gt;
&lt;h2&gt;Side comment; AI summaries&lt;/h2&gt;
&lt;p&gt;A summary is used to get a taste of the content, not a replacement of it. If you rely on AI summaries and not look deeper, it probably means that content wasn&#39;t worth in longform to you regardless.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Don’t half ass “personalized” sales outbound</title>
    <link href="https://shub.club/writings/2026/january/dont-half-ass/"/>
    <updated>2026-01-06T00:00:00Z</updated>
    <id>https://shub.club/writings/2026/january/dont-half-ass/</id>
    <content xml:lang="en" type="html">&lt;p&gt;I got a very nice email from one of our software vendors congratulating us on a new launch of a product.&lt;/p&gt;
&lt;p&gt;I thought that this was a good email-opener and attention grabber, it means that a human definitely looked at our stuff, I should take a peep at theirs.&lt;/p&gt;
&lt;p&gt;The big problem though was that in their email they were talking about how we could use their tools to monitor our usage of one of our competitors’s products.&lt;/p&gt;
&lt;p&gt;Think, if someone emailed OpenAI for LLM monitoring solutions for Claude….pretty funny&lt;/p&gt;
&lt;p&gt;Always proofread your sales outbound!&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>AB316: No AI scapegoating allowed!</title>
    <link href="https://shub.club/writings/2026/january/ab316/"/>
    <updated>2026-01-01T00:00:00Z</updated>
    <id>https://shub.club/writings/2026/january/ab316/</id>
    <content xml:lang="en" type="html">&lt;p&gt;(I am not a lawyer)&lt;/p&gt;
&lt;p&gt;An interesting law is now in effect in California - AB316. The law is as follows:&lt;/p&gt;
&lt;legal href=&quot;https://calmatters.digitaldemocracy.org/bills/ca_202520260ab316&quot;&gt;
&lt;div class=&quot;legal&quot;&gt;
&lt;p&gt;&lt;strong&gt;The people of the State of California do enact as follows:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SECTION 1.&lt;/strong&gt; Section 1714.46 is added to the Civil Code, to read:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1714.46.&lt;/strong&gt; (a) “Artificial intelligence” means an engineered or machine-based system that varies in its level of autonomy and that can, for explicit or implicit objectives, infer from the input it receives how to generate outputs that can influence physical or virtual environments.&lt;/p&gt;
&lt;p&gt;(b) In an action against a defendant that developed or used artificial intelligence that is alleged to have caused a harm to the plaintiff, it shall not be a defense, and the defendant may not assert, that the artificial intelligence autonomously caused the harm to the plaintiff.&lt;a target=&quot;_blank&quot; rel=&quot;noopener nofollow&quot; href=&quot;https://calmatters.digitaldemocracy.org/bills/ca_202520260ab316&quot; class=&quot;legal__source&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;
&lt;/legal&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;In practice, this means that you as a developer cannot be free from liability if the AI you used causes harm to a user due to the unpredictable nature of LLMs.&lt;/p&gt;
&lt;p&gt;If your chatbot decide to tell your customer to kill themselves, it&#39;s your problem.&lt;/p&gt;
&lt;p&gt;I think this is a reasonable law but feels a bit vague. Good software needs guardrails against failures, LLMs in the end can be muzzled, we do control the spigot of the text or operations that get returned.&lt;/p&gt;
&lt;p&gt;The vagueness comes from who the &amp;quot;developer&amp;quot; is when the LLM goes awry. Is it OpenAI&#39;s fault if a third-party app has a slip up, or is the third party? If a research lab puts out a new LLM that another company decides to put in their airplane that crashes, can the original lab be liable or are they only liable if they claim it to be an OSS airplane LLM?&lt;/p&gt;
&lt;p&gt;As for AI safety and guardrail companies, we will probably see greater adoption as companies will want greater ways to shift liability. AI insurance for the research labs? Probably already gearing up for YC Spring-26.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>What death felt like</title>
    <link href="https://shub.club/writings/2025/december/what-death-felt-like/"/>
    <updated>2025-12-28T00:00:00Z</updated>
    <id>https://shub.club/writings/2025/december/what-death-felt-like/</id>
    <content xml:lang="en" type="html">&lt;p&gt;A little bit after my 28th birthday I went to get a regular blood draw. I always had issues around my blood draws, usually just fainting after the procedure was over, nothing too crazy.&lt;/p&gt;
&lt;p&gt;I went in as usual and prepared my arm, the draw went a little longer than usual, I needed more blood than usual for some reason, and I began to fall asleep.&lt;/p&gt;
&lt;p&gt;The sleep was not like normal sleep, it felt so warm, I immediately started to dream of my childhood and warm colors and sights, I could hear my mother (who was very much alive and healthy at the time of writing) call to me.&lt;/p&gt;
&lt;p&gt;It felt like many bedside death descriptions of those who felt like it was actually their time. I think my brain tricked itself into running the death scripts protocol.&lt;/p&gt;
&lt;p&gt;When I was awoken by the nurse, it had literally been one second, but it felt like 8 hours had passed in my head.&lt;/p&gt;
&lt;p&gt;I got my apple juice and sat a bit for monitoring, I didn’t even get all my blood drawn.&lt;/p&gt;
&lt;p&gt;it felt unreal, it felt scary, but it was also reassuring that you won’t notice when you die.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>The haufbraus of San Francisco</title>
    <link href="https://shub.club/writings/2025/december/the-haufbraus-of-san-francisco/"/>
    <updated>2025-12-25T00:00:00Z</updated>
    <id>https://shub.club/writings/2025/december/the-haufbraus-of-san-francisco/</id>
    <content xml:lang="en" type="html">&lt;p&gt;&lt;em&gt;This is not the typical story of haufbraus that many a &lt;a href=&quot;https://sfist.com/2017/01/20/history_bay_area_california_hofbrau/&quot;&gt;local&lt;/a&gt; &lt;a href=&quot;https://sf.eater.com/2018/9/11/17846674/hofbrau-historycalifornia-brennans-berkeley-tommys-joynt-sf&quot;&gt;newspaper&lt;/a&gt; &lt;a href=&quot;https://blog.resy.com/2021/09/blessed-be-tommys-joynt-the-last-san-francisco-hof-brau/&quot;&gt;have&lt;/a&gt; covered, this is a bit deeper!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;If you take the 38 down Geary on the corner of Van Ness you would be hard-pressed to not notice a strange blue building placard with mid-century signage: Tommy’s Joynt.&lt;/p&gt;
&lt;p&gt;A favorite hangout spot of Metallica and purveyor of meats and breads aplenty, one could be mystified by its unique atmosphere and election surrounded by modern glass facades and Ikea laced interiors of neighboring buildings and restaurants. What makes this restaurant also unique, is that it&#39;s primary descriptor is not &amp;quot;beerhaul&amp;quot; or &amp;quot;meat palace&amp;quot;, but &amp;quot;haufbrau&amp;quot; or &amp;quot;hauf-brau&amp;quot;.&lt;/p&gt;
&lt;p&gt;The word itself &amp;quot;haufbrau&amp;quot; is German, but the concept of a &amp;quot;haufbrau&amp;quot; appears to be endemic to California, particularly the Bay Area, where at an era from the 1960s to 80s one could go up to someone and ask them if they ate at a haufbrau and you wouldn’t get a confused look.&lt;/p&gt;
&lt;p&gt;A haufbrau was a place where you could dine in, pick some meats cut up at a counter cafeteria-stye and grab some beers with buds. A beerhall with meat is not unique, but it being a cafeteria and having such a specific german name tied to it brings me the question:&lt;/p&gt;
&lt;p&gt;Why call it a haufbrau? why did this concept take off in the Bay Area specifically?&lt;/p&gt;
&lt;img class=&quot;full-screen&quot; src=&quot;https://shub.club/writings/2025/december/the-haufbraus-of-san-francisco/main.webp&quot; alt=&quot;Photo of Tommy&#39;s Joynt&quot; /&gt;
&lt;div class=&quot;caption&quot;&gt;Tommy&#39;s Joynt on Geary and Van Ness (SW)&lt;/div&gt;
&lt;h2&gt;Yes, it&#39;s german&lt;/h2&gt;
&lt;p&gt;Long ago, 300 years before America was even founded, the kingdom of Bavaria had established the Hofbräuhaus, a state run brewery. The brewery itself had gained prestige and notoriety for its beers, Bavaria itself was known at least Europe-wide for its brews.&lt;/p&gt;
&lt;p&gt;Notable buildings, like the Haufbrauhaus or the Taj Mahal end up becoming placenames for their culture association in foreign land. We do see a lot of Taj Mahal restaurants everywhere you go, no? And it does have to do with food, meat on a plate, with beers; simple enough right?&lt;/p&gt;
&lt;h2&gt;Coming to America&lt;/h2&gt;
&lt;p&gt;In 1867, a John Iffland had imagined bringing his own Hofbräuhaus to America, and opened it over in &lt;a href=&quot;https://restaurant-ingthroughhistory.com/2016/07/17/find-of-the-day-ifflands-hofbrau-haus/&quot;&gt;Newark, NJ&lt;/a&gt;. Unlike the 1950s “hofbrau”, it was very much a standard restaurant, serving German food like beef and beer catering to the German businessmen visiting the region.&lt;/p&gt;
&lt;p&gt;The german diaspora up to this point in America in the 1850s were often religious refugees of protestant origin that settled in the hinterland; generally out of the eye of the &lt;a href=&quot;https://shareok.org/server/api/core/bitstreams/03783981-1729-47ef-aa0b-3e3b87a25fad/content&quot;&gt;american zeitgeist&lt;/a&gt;, but ensuing instability in Europe and rapid industrialization and commerce of Germany had brought a new urban breed into American cities; some ending up even on the west coast.&lt;/p&gt;
&lt;p&gt;One of those immigrants was Heinrich “Henry” Hirsch, an entrepreneur from Hanover who opened the Heidelberg Inn, one of the first new restaurants that emerged from the ashes of the 1906 San Francisco earthquake. The restaurant quickly became very popular, allowing Hirsch to open his magnum opus restaurant, the Hofbrau, in late 1912.&lt;/p&gt;
&lt;img class=&quot;full-screen&quot; src=&quot;https://shub.club/writings/2025/december/the-haufbraus-of-san-francisco/call.jpeg&quot; alt=&quot;IN the opening the new Hofbrau at Fourth and Market streets. San Francisco has added to Its already notable list of eating places probably the most unique restaurant on the Pacifc coast. The old home of the Bismark cafe has been completely renovated and elaborate decorations and electrical displays have changed the old effects to a pretty picture. Arangements, with a keynote of cleanli-ness, the new dining place presented an appetising appearance. Besides Its spacious main dining floor, the walls are completely lined with private dining rooms, bearing the names of the different states of the union. A fisher:men&#39;s home: a college room, complete with all effects, hunters&#39; lodge bungalow a large banquet hall, auxii-tary to the main room. Possibly most Interesting of all is the atypical barn effect with rafters, heavy bern door, Individual and all, entitled Bauern-Stauble, or barn stable. This room is sometimes referred to as the &#39;beefsteak&#39; room, One finds other cosy and comfortably arranged rooms, rep-resentiog and named after the principal cities of Germany, The Hotbrau is a reproduction of the world famous Hofbrau-Hous of Munich, and is under the mahagement of it. Hirsch, who is also the manager of the Heldelberg in Ellia street. People enjoying real German cook-ing. In true German style, and In the most picturesque German restaurent in the eity, will not be disappolnted in visiting this splendid resort, where the cuisine is perfect and a fine musical program adde to the pleasure of ones visit. Prof.&quot; /&gt;
&lt;div class=&quot;caption&quot;&gt;San Francisco Call, Volume 112, Number 163, 10 November 1912&lt;/div&gt;
&lt;p&gt;The Hofbrau, was similar to the Heidelberg Inn and the Hofbräuhaus’ before it; selling German food and beer to much fanfare. Unfortunately its fame for selling German fare would come to be it’s undo it in the coming years; as for the onset of World War 1 and subsequent American involvement against the German people had put a crosshair on the Hofbrau’s back.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;The Hofbrau wasn’t the only Hofbrau in the Bay Area, there was another hofbrau located in Oakland that had a cabaret, the two were confused so much that advertisements for the San Francisco Hofbrau always included that they didn’t have cabarets.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Anti-german sentiment quickly rose in America after the onslaught of the Great War, the Hofbrau was not shielded by its popularity. The restaurant and many other German establishments  had become targets of violence by mobs who had grown to hate all things German.&lt;/p&gt;
&lt;p&gt;For Heinrich and many others like him, they had to essentially force themselves into assimilation, to give up their history and culture into the mostly Angolcentric American world at the time. Heinrich became Henry, and the Hofbrau became the States restaurant [1]. A Native American themed restaurant that served essentially the same food, though now framed to be American; so American it was Native American!&lt;/p&gt;
&lt;newspaper-clipping source=&quot;Visalia Times Delta, Volume 24, Number 8, 9 March 1940&quot; ref=&quot;1&quot; title=&quot;Uncensored&quot; author=&quot;Leona Baxter&quot; image=&quot;./states.png&quot; content=&quot;&quot;&gt;
&lt;div class=&quot;newspaper-clipping&quot;&gt;
        &lt;div class=&quot;newspaper-clipping__main&quot;&gt;
            &lt;div class=&quot;newspaper-clipping__ref-wrapper&quot;&gt;
                &lt;span class=&quot;newspaper-clipping_ref&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;newspaper-clipping_ref__content&quot;&gt;Visalia Times Delta, Volume 24, Number 8, 9 March 1940&lt;/span&gt;
            &lt;/div&gt;
            &lt;div class=&quot;newspaper-clipping__main__title&quot;&gt;Uncensored&lt;/div&gt;&lt;div class=&quot;newspaper-clipping__main__author&quot;&gt;Leona Baxter&lt;/div&gt;
            &lt;div class=&quot;newspaper-clipping__main__content&quot;&gt; 
&lt;p&gt;Garbed in ceremonial robes, in the presence of their awe-struck but approving tribesmen, chiefs of the Navajo, Papago, Apache and Hopi Indians last week formally renounced forever the symbol that has adorned their baskets, pottery and temples for centuries—the swastika. This they did on the reasoning that Nazi Germany has desecrated the symbol by acts of aggression and persecution.&lt;/p&gt;
&lt;p&gt;To many, familiar with the history of the swastika, its abandonment by the tribes may seem pointless and a little absurd. It is one of the most ancient of decorative and symbolic emblems, found embedded in the mosaics and temples of the Greeks and Egyptians—and amazed white men discovered it, a mystic, hallowed symbol, among sun-worshipping Incas and other American Indian people.&lt;/p&gt;
&lt;p&gt;Yet the white man shouldn&#39;t smile too broadly at those serious Indians. All save youngsters remember, with an inward blush, that in the World War we Americans abolished the German language from public schools, band leaders ceased playing the glorious music of German composers—many of whom were long dead and had never heard of the Kaiser and militarism. American restaurants didn&#39;t serve &#39;hamburger&#39;—although it was all right to eat the identical dish under the label of &#39;liberty steak.&#39; One famous San Francisco restaurant, the Hofbrau, was saved from mob wreckage only by the presence of mind of the orchestra leader, who swung into the Star-Spangled Banner and so obliged the mob to stand at attention until the cops arrived. The restaurant continued to operate in safety by the simple device of changing its name from the Hofbrau to The States restaurant.&lt;/p&gt;
&lt;p&gt;That type of reasonless emotion may easily become as dangerous as it is ridiculous. Most of Europe is on such an emotional jag of murderous malice today. Jews—not individual Jews who might be guilty of offenses—but all Jews, are despoiled, insulted, killed, simply because they are Jews. The mere racial label &#39;Jew&#39; is a special symbol of unreasoning loathing, to Hitler and his immediate followers.&lt;/p&gt;
&lt;p&gt;More than ever, in these times, when blind hate is engulfing reason and understanding and tolerance on every continent but this one, Americans must hold resolutely to the common sense and sanity that are the hallmarks of civilization itself.&lt;/p&gt;
&lt;p&gt;No, we have little room to laugh at the Indians turning thumbs down on their own ancient symbol, seemingly defiled. We, in our generation, have been almost equally foolish and bitter. It probably would surprise the Navajo and Apache people to know that another nation, in spite of the regime of hate and oppression which the swastika seems to symbolize today, retains the emblem yet. This is peaceful, inoffensive little Latvia who paints the swastika plainly, bravely, on the wings of its own airplanes.&lt;/p&gt;
 &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;newspaper-clipping__image-reference&quot;&gt;
            &lt;img alt=&quot;Original photo of newspaper article&quot; src=&quot;https://shub.club/writings/2025/december/the-haufbraus-of-san-francisco/states.png&quot; class=&quot;newspaper-clipping__image-reference__inner&quot; /&gt;
        &lt;/div&gt;
&lt;/div&gt;
&lt;/newspaper-clipping&gt;
&lt;p&gt;So became the story of many restaurants like the Hofbrau, hiding away and assimilating over the next few years. Losing interest from the public as German food itself had become more synonymous with standard American faire, hotdogs and hamburgers, saurkraut, etc.&lt;/p&gt;
&lt;p&gt;The Hofbrau of San Francisco though had one last go; after an ownership change, the new owners during the interbellum period had put the name Hofbrau back onto the States restaurant to cash in on the name, though eventually the restaurant had also faded away by the second world war, probably due to again, anti-german sentiment.&lt;/p&gt;
&lt;h2&gt;The cafeteria part&lt;/h2&gt;
&lt;p&gt;We&#39;ve gotten a taste of german-american history here, enough to tell us why they sell meat and beer at a place like Haufbrau, but what about the cafeteria part?&lt;/p&gt;
&lt;p&gt;Cafeterias it seems were just a &lt;a href=&quot;https://www.latimes.com/archives/la-xpm-2003-nov-05-fo-cafeteria5-story.html&quot;&gt;big trend&lt;/a&gt;, starting in Los Angeles in the turn of the century, to becoming a mainstay afterwards everywhere else. Cafeterias though interestingly enough were on a decline by the mid-century, the automobile and suburbia seemed to pass it in favor of the drive in; fortunately San Francisco was plenty dense to keep this trend alive a bit longer.&lt;/p&gt;
&lt;h2&gt;Back to the story everyone knows&lt;/h2&gt;
&lt;p&gt;Now we finally get to 1947, where the first modern &amp;quot;hofbrau&amp;quot; set up shop, Tommy’s Joynt. A cafeteria styled restaurant that served vaguely German food. But if you noticed, they weren’t calling themselves a hofbrau, it seemed to have been applied after the fact, after many restaurants in the following decade followed suit with selling vaguely German cuisine. Restaurants like Harry&#39;s Hof Brau in 1954, and Sam’s Hofbrau started applying the word directly into the name, indicating that now this term had a meaning to it, but even the term itself did not become popular in vernacular until the decade after.&lt;/p&gt;
&lt;p&gt;It seemed like it was just a perfect alignment of assimilated cuisine with a twist, cafeterias and the desire for something new brought the new name to hofbrau.&lt;/p&gt;
&lt;p&gt;So what happened to hofbrau after the 1950s? It kept on chugging along time, switching ownership and losing more and more of its vaguely German roots to an amalgamation of American culture.&lt;/p&gt;
&lt;p&gt;One of the more popular hofbrau’s of the time, Lefty O&#39;Doul’s had no semblance of relation to Germany outside of the concept of the meat itself. And as time went on, hofbraus continued to become an amalgamation of America diasporic import, some hofbraus started offering &lt;a href=&quot;https://www.yelp.com/biz/noahs-hof-brau-modesto&quot;&gt;Chinese food&lt;/a&gt;, some stopped even being cafeterias.&lt;/p&gt;
&lt;location image=&quot;./noah.jpeg&quot; caption=&quot;noah&#39;s haufbrau in modesto serves chinese food&quot; name=&quot;Noah&#39;s Hof Brau&quot; address=&quot;1311 J St, Modesto, California 95354&quot;&gt;
&lt;div class=&quot;location-helper-wrapper&quot;&gt;&lt;span class=&quot;location-name&quot;&gt;Noah&#39;s Hof Brau&lt;/span&gt;&lt;div class=&quot;location-image-wrapper&quot;&gt;&lt;img alt=&quot;noah&#39;s haufbrau in modesto serves chinese food&quot; src=&quot;https://shub.club/writings/2025/december/the-haufbraus-of-san-francisco/noah.jpeg&quot; class=&quot;location-image&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;location-helper&quot;&gt;
        &lt;span&gt;1311 J St, Modesto, California 95354&lt;/span&gt;&lt;span class=&quot;links&quot;&gt;
&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://www.openstreetmap.org/search?query=1311%20J%20St,%20Modesto,%20California%2095354&quot;&gt;
    &lt;img alt=&quot;OpenStreetMap Logo&quot; src=&quot;https://shub.club/icons/openstreetmap.png&quot; class=&quot;location-icon&quot; /&gt;
&lt;/a&gt;
&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;http://maps.apple.com/?address=1311%20J%20St,%20Modesto,%20California%2095354&amp;amp;dirflg=t&quot;&gt;
    &lt;img alt=&quot;Apple Maps Logo&quot; src=&quot;https://shub.club/icons/apple-maps.svg&quot; class=&quot;location-icon&quot; /&gt;
&lt;/a&gt;
&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://www.google.com/maps/search/?api=1&amp;amp;query=1311%20J%20St,%20Modesto,%20California%2095354&quot;&gt;
    &lt;img alt=&quot;Google Maps Logo&quot; src=&quot;https://shub.club/icons/google-maps.png&quot; class=&quot;location-icon&quot; /&gt;
&lt;/a&gt;
&lt;/span&gt;
    &lt;/div&gt;
&lt;/div&gt;&lt;/location&gt;
&lt;p&gt;Today there stands very few restaurants claiming to be hofbraus, the style of dining blended into American culture. Anytime you see a buffet that serves carved meats or a restaurant that have vaguely German vibes, you can see that the Hofbrau is still around.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Thoughts on Startup Internships</title>
    <link href="https://shub.club/writings/2025/december/thoughts-on-startup-internships/"/>
    <updated>2025-12-22T00:00:00Z</updated>
    <id>https://shub.club/writings/2025/december/thoughts-on-startup-internships/</id>
    <content xml:lang="en" type="html">&lt;p&gt;&lt;em&gt;(This article is severely delayed because I forgot it in drafts)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Over the summer I had the opportunity to work with two bright young minds at Letta~here&#39;s what happened:&lt;/p&gt;
&lt;p&gt;We decided to setup a internship program this year because we felt it could be an interesting and low-risk experiment in the effectiveness of interns in early stage startups, as well as give back to those early into their career by showing them how startups are.&lt;/p&gt;
&lt;p&gt;I had some time to reflect now that they’ve left on what it means to have an intern at a startup, both for them and you.&lt;/p&gt;
&lt;p&gt;Having interns was not a light decision to make, especially for startup. An intern is someone who is new and ready to learn, they have some knowledge from previous experiences but are in no way masters or even intermediates. There are some students that apply for internships that work as good as junior or even mid-level engineers, but those are exceptions to the rule. Most interns are there to learn how to execute not be hired for their execution skills.&lt;/p&gt;
&lt;p&gt;With that in mind, you as a startup need to understand  that you’ll be spending time to ramp up and guide interns to be successful. The interview process is a filter on your end to figure out  who is the best at learning and the best fit for your guidance style.&lt;/p&gt;
&lt;p&gt;My intern I picked because they were quick on their feet and adaptable, they had taste and opinions, and I felt like I could lead them to success. I think though I was a bit overwhelmed for a bit of it, we ended up with two interns; which was a lot to deal with, especially  when you’re coding, designing and refining product. You need to make the time to make it work for both of you.&lt;/p&gt;
&lt;p&gt;What I did was I let them shadow my work, as well as put them in a situation where they’re essentially  full members of the team. They had to understand specs, they had to come up with a plan and they had to execute from there. I think when you’re in school you really only focus on learning fundamentals not necessarily executing them, so I felt like for my interns, most of my work had to be translating fundamentals to execution.&lt;/p&gt;
&lt;p&gt;Those three months were an exciting time at my company, our team learned so much gen-z lingo and culture that I feel like our vocabulary had changed for the better (or worse). We also gained perspective on usage patterns of younger users, and got some fresh opinions on how we could execute certain products. We also got a bunch of work done.&lt;/p&gt;
&lt;p&gt;There’s a big downside to interns, and I knew this coming into it: interns are a hindrance on your productivity, you’ll spend less time executing and more time guiding and reviewing. You can of course shirk those responsibilities, but you’re going to do a disservice to them and yourself as they don’t really learn as fast or effective and you get a pile of tech debt you will spend months refactoring after. For a really early stage startup, this could be very damaging unless you really know what you’re in for, otherwise you’re in a world of hurt.&lt;/p&gt;
&lt;p&gt;Now, are engineering interns worth it if you run a startup? The answer is it depends, if your very UX product heavy or consumer facing, I think the pros of fresh ideas and perspective outweigh the downsides of productivity. Anything else, I&#39;d lean no, unless you really want to devote the time to do it. Not saying it will be a mistake, but if you&#39;re an early career founder, I would recommend instead grabbing those would-be interns as cofounders and risk it all together.&lt;/p&gt;
&lt;p&gt;Was it worth it for us? I think yes, we found some capable students who loved to build, and we had a fun time too. I think our team had enough experience to manage them and it did not detract from our mission. Would I do it again? Yes! But only because I wanted to put the extra time in. If I didn&#39;t want to help others grow and just wanted cheap workers, I&#39;d just not do it. It doesn&#39;t make sense.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Word of the Day - Postequital</title>
    <link href="https://shub.club/writings/2025/december/word-of-the-day-post-equitable/"/>
    <updated>2025-12-13T00:00:00Z</updated>
    <id>https://shub.club/writings/2025/december/word-of-the-day-post-equitable/</id>
    <content xml:lang="en" type="html">&lt;p&gt;Word of the Day - Postequital&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Postequital&lt;/strong&gt; (adj) - Describes a person or actions of a person whose startup equity actually became valuable. Can be described as behavior similar to a mid life crisis but with greater purchasing power; common examples include opening a store or business that only loses money, working in the government to “fix it” or becoming an artist. It signifies that someone’s inner desires finally have an outlet to exist instead of in theory.&lt;/p&gt;
&lt;p&gt;Does not describe someone starting a new startup, going back to work or becoming a venture capitalist, as that is essentially continuing to do the same work as before.&lt;/p&gt;
&lt;p&gt;In a sentence:&lt;/p&gt;
&lt;p&gt;Joe’s luxury cookie store seems definitely postequitable, there’s no way he could have afforded the rent before his employer IPO’d.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Why are my food delivery apps AI generating photos of food?</title>
    <link href="https://shub.club/writings/2025/november/why-are-my-food-delivery-apps-ai-generating-photos-of-my-food/"/>
    <updated>2025-11-15T00:00:00Z</updated>
    <id>https://shub.club/writings/2025/november/why-are-my-food-delivery-apps-ai-generating-photos-of-my-food/</id>
    <content xml:lang="en" type="html">&lt;img alt=&quot;plastic ai generated food&quot; src=&quot;https://shub.club/writings/2025/november/why-are-my-food-delivery-apps-ai-generating-photos-of-my-food/cover.png&quot; style=&quot;max-width: 0%; height: 0&quot; class=&quot;full&quot; /&gt;
&lt;p&gt;The common Friday morning schedule for most startup employees with reasonable leadership is to pick out the food they want to consume for the next week. Group-buy food delivery apps have hit it big with startups, and the one I work for is no different. Most weeks it&#39;s pretty standard, visit &lt;a href=&quot;http://forkable.com/&quot;&gt;forkable.com&lt;/a&gt;, pick what meals I want to eat usually by how appetizing it looks or the description, and submit away, ezpz. But this week was a little different, instead of gazing at the photos of my potential eats, I got this:&lt;/p&gt;
&lt;img alt=&quot;plastic ai generated food&quot; src=&quot;https://shub.club/writings/2025/november/why-are-my-food-delivery-apps-ai-generating-photos-of-my-food/mexican.jpeg&quot; style=&quot;max-width: 100%&quot; class=&quot;full&quot; /&gt;
&lt;p&gt;At first, I thought, wow they really got some interesting looking lighting and plating - it really shows off a very plastic looking food.&lt;/p&gt;
&lt;p&gt;But then I saw this monstrosity:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://shub.club/writings/2025/november/why-are-my-food-delivery-apps-ai-generating-photos-of-my-food/pizza.jpeg&quot; alt=&quot;pizza.jpeg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This pizza, from JoyRide pizza in SF (delicious BTW), does not look like this at all. First off, it&#39;s a half pie, so it should ideally look like half a pizza, not a whole pizza. It&#39;s also a detroit style pizza, which means the crusts should look like it was cooked in a autoshop-pan not baked like a grandma style or whatever this is. It doesn&#39;t look accurate not does it even look appetizing, look at what it actually looks like and tell me what you&#39;d rather have:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://shub.club/writings/2025/november/why-are-my-food-delivery-apps-ai-generating-photos-of-my-food/real.jpeg&quot; alt=&quot;real.jpeg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I really don&#39;t understand the logic here, Forkable already has a very limited option of restaurants you can pick from, why not just spend the money to take actual photos of the food. It looks much better and actually looks like the food you&#39;re getting.&lt;/p&gt;
&lt;p&gt;I get that in this case the customer is not the user, but the company ordering this catering, so there&#39;s no major incentive to make food that accurate, but this plastic vision of food is not appetizing. Maybe that&#39;s the goal, to have people eat less so the company saves money? Not sure.&lt;/p&gt;
&lt;p&gt;However, if you want to build a good CX, Forkable, I would recommend instead of AI generating your food photos, make your AI auto-order mechanism engine better, I&#39;ve had coworkers get side dishes as their auto-selected entrées because your system needs a bit of fine-tuning.&lt;/p&gt;
&lt;p&gt;Bonus: Neon Blue sushi roll&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://shub.club/writings/2025/november/why-are-my-food-delivery-apps-ai-generating-photos-of-my-food/neon.png&quot; alt=&quot;neon.png&quot; /&gt;&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Coding with agents is really good but I feel so empty</title>
    <link href="https://shub.club/writings/2025/november/ai-agents-are-good-i-m-bored-now/"/>
    <updated>2025-11-03T00:00:00Z</updated>
    <id>https://shub.club/writings/2025/november/ai-agents-are-good-i-m-bored-now/</id>
    <content xml:lang="en" type="html">&lt;p&gt;&lt;em&gt;You ever beat a game and then unlock gun/sword/magic power that makes everything super easy to destroy and then you get bored of the game?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I’ve been adopting using AI agents at work to help ship features.&lt;/p&gt;
&lt;p&gt;We have a pretty established codebase with very strict linting, formatting testing and e2e tests, so building apps with [the company I work for’s open source coding agent] has become a breeze and pretty safe to do.&lt;/p&gt;
&lt;p&gt;It feels almost unreal how much I can deliver with these things. I just lay out an architecture plan, roll out segment by segment, code review every step of the way, I never try to let it write so much code it becomes a slog to review either. It’s way faster than if I started to type the code, and even when there’s architecture, system or just logical errors, it’s still faster to tell the cli to fix it.&lt;/p&gt;
&lt;p&gt;Efficient? yes.&lt;/p&gt;
&lt;p&gt;Shipping way more than before? Yes.&lt;/p&gt;
&lt;p&gt;But it really doesn’t feel like coding. It&#39;s a bit boring...not that fun.&lt;/p&gt;
&lt;p&gt;I mean, it isn’t coding.  It’s spec definition writing and then code reviewing.&lt;/p&gt;
&lt;p&gt;Two things, that are sometimes fun (spec defs, code reviews no) but they’re not coding.&lt;/p&gt;
&lt;p&gt;I feel when AI autocomplete came out, a la github, coding became faster, exciting, and it still felt like my code; coding agents on the other hand feels like I’ve become a PM who’s really good at code review. It’s really a weird experience, I worry that new engineers will never gain the skills of actually knowing how these things lace together because they’re no longer doing, they’re just observing and referring (or just not reviewing at all). I’m sure I’ll also lose my touch if I do this too much.&lt;/p&gt;
&lt;p&gt;I do feel like I’m still doing work though, there’s lots of code review, prompting and organizing still done, which for some people could be fun; but for me, I think I rather just start typing a for loop by hand sometimes again.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>My website&#39;s stats only gets updated when I make a new blog post</title>
    <link href="https://shub.club/writings/2025/september/viewcounts/"/>
    <updated>2025-09-30T00:00:00Z</updated>
    <id>https://shub.club/writings/2025/september/viewcounts/</id>
    <content xml:lang="en" type="html">&lt;p&gt;I think I have a kinda overkill analytics stack for my website.&lt;/p&gt;
&lt;p&gt;I host an &lt;a href=&quot;https://umami.is/&quot;&gt;Umami Analytics&lt;/a&gt; instance on Vercel (0$/m), and host the data on a database on a vps that I spend 15$/mo on (I use it for other things too, dw).&lt;/p&gt;
&lt;p&gt;I say it&#39;s overkill because realistically, I just want a view counter, I don&#39;t really need anything else, knowing what country my readers come from, cool but not changing my life. The bare view metric is all I need to know to see what people find the most interest on my website. I could swap to something simpler, but my system works, and it&#39;s free (for now), so why not.&lt;/p&gt;
&lt;p&gt;All this data though brings me an idea - let&#39;s show my website visitors the viewcounts for pages on this site.&lt;/p&gt;
&lt;p&gt;Since I&#39;m storing all this analytics data in a DB anyway, might as well do something with it. I already feel embarrassed paying 15$ a month to have data on a VPS, so I don&#39;t want to spend even more, so we have to make sure I don&#39;t add any new services to this feature.&lt;/p&gt;
&lt;p&gt;Then it came to me - it&#39;s not super critical that you see live viewcounts, so why not inject those views in our build system that I get for free, with my free static site hosting from &lt;a href=&quot;https://www.digitalocean.com/products/app-platform&quot;&gt;DigitalOcean&lt;/a&gt;. (I&#39;m not sponsored by anyone, I swear)&lt;/p&gt;
&lt;h2&gt;The code part...&lt;/h2&gt;
&lt;p&gt;Since I already use 11ty as my build system, this is pretty easy, I can just hook my DB url and then calculate views on the build step:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt;  pg &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;pg&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getViewCounts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; query &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;SELECT count(url_path), url_path FROM website_event WHERE event_type = 1 GROUP BY url_path;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; client &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;pg&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Client&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;connectionString&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;POSTGRES_URL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;ssl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;rejectUnauthorized&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;query&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; totalViews &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; counts &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;rows&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; out &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;parseInt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;row&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;count&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    counts&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;row&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url_path&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; out&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    totalViews &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; out&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  counts&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;total&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; totalViews&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; counts&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then I just set it as some global data in my 11ty config:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; lastUpdatedAt &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toISOString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

eleventyConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addGlobalData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;viewCounts&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getViewCounts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then I render it to you:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;@raw&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;JSON.parse(viewCounts).total&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see on the homepage, and in the page header (as of Oct 2025), we got views!!!&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I think as devs we think always about making data as realtime as possible, but sometimes it&#39;s interesting to think of not doing that to save on other constraints, like making things free!&lt;/p&gt;
&lt;p&gt;The viewcount system seems to be working, and I think the only big downside is that viewcounts only update when I make more blog posts, which maybe is a good thing :)&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Some flying things?</title>
    <link href="https://shub.club/writings/2025/september/airplane-tricks/"/>
    <updated>2025-09-16T00:00:00Z</updated>
    <id>https://shub.club/writings/2025/september/airplane-tricks/</id>
    <content xml:lang="en" type="html">&lt;p&gt;I just took a 12 hour flight, and on my 6 hours of being awake, I realized there’s a few things that people miss out on that makes their flight a bit nicer.&lt;/p&gt;
&lt;h2&gt;Foot pedals in the restroom&lt;/h2&gt;
&lt;p&gt;Don’t you hate it when you try to push your trash into the airplane restroom bin, it feels so nasty, but if you ever pay attention to the image on the trash lid, it hints there’s another way. Most modern planes have a foot pedal near the sink to open the trash bin.&lt;/p&gt;
&lt;h2&gt;Aisle seat switch&lt;/h2&gt;
&lt;p&gt;All the aisle seats have an “immovable” hand rest, but this is not true, it’s just locked. To unlock it, fish around the bottom side for a button and press down while raising the arm rest. It should work and flight attendants do not care if you do it.&lt;/p&gt;
&lt;h2&gt;Self serve snacks&lt;/h2&gt;
&lt;p&gt;Most long haul flights will provide an area usually in the back or between bulkheads where you can pick up your own snacks and water. Be sure to drink lots of water!!&lt;/p&gt;
&lt;h2&gt;Multilevel tray tables&lt;/h2&gt;
&lt;p&gt;Some modern long-haul aircraft will have multilevel tray tables, you can pull out the bottom as a normal tray as you&#39;re used to, but some do have a secondary tray that&#39;s right above it, there&#39;s usually a switch that you can press to open it. The secondary tray usually is smaller and higher up, so you can use it as a mini drink and phone stand!&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>The best sandwiches in San Francisco</title>
    <link href="https://shub.club/writings/2025/august/best-sandwhiches-in-san-francisco/"/>
    <updated>2025-08-31T00:00:00Z</updated>
    <id>https://shub.club/writings/2025/august/best-sandwhiches-in-san-francisco/</id>
    <content xml:lang="en" type="html">&lt;p&gt;My coworker &lt;a href=&quot;https://cameron.pfiffer.org/&quot;&gt;Cameron&lt;/a&gt; told me lately that I was a sandwich hater, but I actually do love sandwiches, below is a running list of my favorite sandwich spots in the city.&lt;/p&gt;
&lt;p&gt;I just like good sandwiches. This list is not every sandwhich place I&#39;ve been to, just the ones I think are great, no particular order. (No breakfast sandwich places, that&#39;s a different list)&lt;/p&gt;
&lt;h2&gt;Sandy&#39;s Muffuletta&lt;/h2&gt;
&lt;location address=&quot;1457 Haight St, San Francisco, CA 94117&quot;&gt;
&lt;div class=&quot;location-helper-wrapper&quot;&gt;
    &lt;div class=&quot;location-helper&quot;&gt;
        &lt;span&gt;1457 Haight St, San Francisco, CA 94117&lt;/span&gt;&lt;span class=&quot;links&quot;&gt;
&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://www.openstreetmap.org/search?query=1457%20Haight%20St,%20San%20Francisco,%20CA%2094117&quot;&gt;
    &lt;img alt=&quot;OpenStreetMap Logo&quot; src=&quot;https://shub.club/icons/openstreetmap.png&quot; class=&quot;location-icon&quot; /&gt;
&lt;/a&gt;
&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;http://maps.apple.com/?address=1457%20Haight%20St,%20San%20Francisco,%20CA%2094117&amp;amp;dirflg=t&quot;&gt;
    &lt;img alt=&quot;Apple Maps Logo&quot; src=&quot;https://shub.club/icons/apple-maps.svg&quot; class=&quot;location-icon&quot; /&gt;
&lt;/a&gt;
&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://www.google.com/maps/search/?api=1&amp;amp;query=1457%20Haight%20St,%20San%20Francisco,%20CA%2094117&quot;&gt;
    &lt;img alt=&quot;Google Maps Logo&quot; src=&quot;https://shub.club/icons/google-maps.png&quot; class=&quot;location-icon&quot; /&gt;
&lt;/a&gt;
&lt;/span&gt;
    &lt;/div&gt;
&lt;/div&gt;&lt;/location&gt;
&lt;p&gt;&lt;img src=&quot;https://shub.club/writings/2025/august/best-sandwhiches-in-san-francisco/sandys.jpeg&quot; alt=&quot;a muffaletta (multiple meats layered with olive topinade) with a cookie and another milk bread sandwich with cheese&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I first had Sandy&#39;s at Outside Lands when they were just a popup, and I was hooked instantly. I devoured that thing, obliterated it, it was gone, and I went and bought another immediately after and destroyed it.&lt;/p&gt;
&lt;p&gt;They only sell Muffuletta, a NOLA classic, the first time I had it was at the historic Central Market, but honestly, Sandy does it better than most of NOLA; I think it&#39;s because the food scene here isn&#39;t as olbiged with traditions (watch me yap about pizza in a future post), so you get a tinge of the classic, but also the ability to use new techniques and flavors. The tapinade is insane and the meats are top notch.&lt;/p&gt;
&lt;p&gt;To this day, when someone is visiting San Francisco, I take them here; it&#39;s truly reflective of the city, a cultural melting pot full of people who want to refine things to the very best.&lt;/p&gt;
&lt;p&gt;My rec is the classic, with a cookie on the side.&lt;/p&gt;
&lt;h2&gt;Palm City&lt;/h2&gt;
&lt;location address=&quot;4055 Irving St, San Francisco, CA 94122&quot;&gt;
&lt;div class=&quot;location-helper-wrapper&quot;&gt;
    &lt;div class=&quot;location-helper&quot;&gt;
        &lt;span&gt;4055 Irving St, San Francisco, CA 94122&lt;/span&gt;&lt;span class=&quot;links&quot;&gt;
&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://www.openstreetmap.org/search?query=4055%20Irving%20St,%20San%20Francisco,%20CA%2094122&quot;&gt;
    &lt;img alt=&quot;OpenStreetMap Logo&quot; src=&quot;https://shub.club/icons/openstreetmap.png&quot; class=&quot;location-icon&quot; /&gt;
&lt;/a&gt;
&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;http://maps.apple.com/?address=4055%20Irving%20St,%20San%20Francisco,%20CA%2094122&amp;amp;dirflg=t&quot;&gt;
    &lt;img alt=&quot;Apple Maps Logo&quot; src=&quot;https://shub.club/icons/apple-maps.svg&quot; class=&quot;location-icon&quot; /&gt;
&lt;/a&gt;
&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://www.google.com/maps/search/?api=1&amp;amp;query=4055%20Irving%20St,%20San%20Francisco,%20CA%2094122&quot;&gt;
    &lt;img alt=&quot;Google Maps Logo&quot; src=&quot;https://shub.club/icons/google-maps.png&quot; class=&quot;location-icon&quot; /&gt;
&lt;/a&gt;
&lt;/span&gt;
    &lt;/div&gt;
&lt;/div&gt;&lt;/location&gt;
&lt;p&gt;&lt;img src=&quot;https://shub.club/writings/2025/august/best-sandwhiches-in-san-francisco/palmcity.jpeg&quot; alt=&quot;A sandwich with a lot of ham and veggies on a french bread&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The thiccest hoagies around come from Palm City, legendary sandwiches here perfect after a long bike ride or hike through the golden gate park. Palm city is a bit artsy fartsy, their sandwiches reflect that, braised pork, alfalfa, the good mortadella. The chefs here are definitely bringing the upscale to this one.&lt;/p&gt;
&lt;p&gt;My rec is the Italian American, get some olives and a coke too.&lt;/p&gt;
&lt;h2&gt;Deli Board&lt;/h2&gt;
&lt;location address=&quot;1058 Folsom St, San Francisco, CA 94103&quot;&gt;
&lt;div class=&quot;location-helper-wrapper&quot;&gt;
    &lt;div class=&quot;location-helper&quot;&gt;
        &lt;span&gt;1058 Folsom St, San Francisco, CA 94103&lt;/span&gt;&lt;span class=&quot;links&quot;&gt;
&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://www.openstreetmap.org/search?query=1058%20Folsom%20St,%20San%20Francisco,%20CA%2094103&quot;&gt;
    &lt;img alt=&quot;OpenStreetMap Logo&quot; src=&quot;https://shub.club/icons/openstreetmap.png&quot; class=&quot;location-icon&quot; /&gt;
&lt;/a&gt;
&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;http://maps.apple.com/?address=1058%20Folsom%20St,%20San%20Francisco,%20CA%2094103&amp;amp;dirflg=t&quot;&gt;
    &lt;img alt=&quot;Apple Maps Logo&quot; src=&quot;https://shub.club/icons/apple-maps.svg&quot; class=&quot;location-icon&quot; /&gt;
&lt;/a&gt;
&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://www.google.com/maps/search/?api=1&amp;amp;query=1058%20Folsom%20St,%20San%20Francisco,%20CA%2094103&quot;&gt;
    &lt;img alt=&quot;Google Maps Logo&quot; src=&quot;https://shub.club/icons/google-maps.png&quot; class=&quot;location-icon&quot; /&gt;
&lt;/a&gt;
&lt;/span&gt;
    &lt;/div&gt;
&lt;/div&gt;&lt;/location&gt;
&lt;p&gt;&lt;img src=&quot;https://shub.club/writings/2025/august/best-sandwhiches-in-san-francisco/deliboard.jpeg&quot; alt=&quot;A sandwich with pastrami cheese and pickles on dutch crunch&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Deli Board was my first introduction to good store-bought deli sandwiches. When I moved to SF long long ago, I only knew of jimmy johns and subway, perfectly mediocre, but got the job done. I loved crafting sandwhiches myself, always using the good stuff and roasting my own veggies with the good cheese. Then I had Deli Board and I got woke. The sandwiches did not have to go this hard. They have a lot of pastrami here, I dont know if they make them here, but it slaps hard.&lt;/p&gt;
&lt;p&gt;My rec, 49er with waffle fries&lt;/p&gt;
&lt;h2&gt;Lou&#39;s Lounge&lt;/h2&gt;
&lt;location address=&quot;275 Battery St, San Francisco, CA 94111&quot;&gt;
&lt;div class=&quot;location-helper-wrapper&quot;&gt;
    &lt;div class=&quot;location-helper&quot;&gt;
        &lt;span&gt;275 Battery St, San Francisco, CA 94111&lt;/span&gt;&lt;span class=&quot;links&quot;&gt;
&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://www.openstreetmap.org/search?query=275%20Battery%20St,%20San%20Francisco,%20CA%2094111&quot;&gt;
    &lt;img alt=&quot;OpenStreetMap Logo&quot; src=&quot;https://shub.club/icons/openstreetmap.png&quot; class=&quot;location-icon&quot; /&gt;
&lt;/a&gt;
&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;http://maps.apple.com/?address=275%20Battery%20St,%20San%20Francisco,%20CA%2094111&amp;amp;dirflg=t&quot;&gt;
    &lt;img alt=&quot;Apple Maps Logo&quot; src=&quot;https://shub.club/icons/apple-maps.svg&quot; class=&quot;location-icon&quot; /&gt;
&lt;/a&gt;
&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://www.google.com/maps/search/?api=1&amp;amp;query=275%20Battery%20St,%20San%20Francisco,%20CA%2094111&quot;&gt;
    &lt;img alt=&quot;Google Maps Logo&quot; src=&quot;https://shub.club/icons/google-maps.png&quot; class=&quot;location-icon&quot; /&gt;
&lt;/a&gt;
&lt;/span&gt;
    &lt;/div&gt;
&lt;/div&gt;&lt;/location&gt;
&lt;p&gt;Lou&#39;s is definitly a sandwhich maximalist brand, they have such breadth of options for a fidi sandwhich stop, from the  Risky Bizness with pastrami, crab, bacon or the Kick&#39;N R. B. Sandwich with roast beef and horseradish, or just the Roma Club, which is just a club.  My goal in life is to try every item on the menu; unfortunately, their menu is like 50 sandwiches, so it&#39;ll take some time at my pace.&lt;/p&gt;
&lt;p&gt;My rec, Risky Bizness, no sides, get some tap water.&lt;/p&gt;
&lt;h2&gt;Arsicault&lt;/h2&gt;
&lt;location address=&quot;1070 Bridgeview Way, San Francisco, CA 94158&quot;&gt;
&lt;div class=&quot;location-helper-wrapper&quot;&gt;
    &lt;div class=&quot;location-helper&quot;&gt;
        &lt;span&gt;1070 Bridgeview Way, San Francisco, CA 94158&lt;/span&gt;&lt;span class=&quot;links&quot;&gt;
&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://www.openstreetmap.org/search?query=1070%20Bridgeview%20Way,%20San%20Francisco,%20CA%2094158&quot;&gt;
    &lt;img alt=&quot;OpenStreetMap Logo&quot; src=&quot;https://shub.club/icons/openstreetmap.png&quot; class=&quot;location-icon&quot; /&gt;
&lt;/a&gt;
&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;http://maps.apple.com/?address=1070%20Bridgeview%20Way,%20San%20Francisco,%20CA%2094158&amp;amp;dirflg=t&quot;&gt;
    &lt;img alt=&quot;Apple Maps Logo&quot; src=&quot;https://shub.club/icons/apple-maps.svg&quot; class=&quot;location-icon&quot; /&gt;
&lt;/a&gt;
&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://www.google.com/maps/search/?api=1&amp;amp;query=1070%20Bridgeview%20Way,%20San%20Francisco,%20CA%2094158&quot;&gt;
    &lt;img alt=&quot;Google Maps Logo&quot; src=&quot;https://shub.club/icons/google-maps.png&quot; class=&quot;location-icon&quot; /&gt;
&lt;/a&gt;
&lt;/span&gt;
    &lt;/div&gt;
&lt;/div&gt;&lt;/location&gt;
&lt;p&gt;WTH is Arsicault doing here?? Well, their new Mission Bay location has sandwiches. Parisian sandwiches that are highly opinionated and very well executed, just like their crossaints. The sandos are very simple, just very crispy and delicate baguette with some ham and butter, a complete opposite to Lou&#39;s maximialism, Arsicault serves minimalism here and does it well.&lt;/p&gt;
&lt;p&gt;My rec is ham and butter sandwich, get a chocolate crossaint too while you wait, cuz why not.&lt;/p&gt;
&lt;h2&gt;Cheese Plus&lt;/h2&gt;
&lt;location address=&quot;2001 Polk St, San Francisco, CA 94109&quot;&gt;
&lt;div class=&quot;location-helper-wrapper&quot;&gt;
    &lt;div class=&quot;location-helper&quot;&gt;
        &lt;span&gt;2001 Polk St, San Francisco, CA 94109&lt;/span&gt;&lt;span class=&quot;links&quot;&gt;
&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://www.openstreetmap.org/search?query=2001%20Polk%20St,%20San%20Francisco,%20CA%2094109&quot;&gt;
    &lt;img alt=&quot;OpenStreetMap Logo&quot; src=&quot;https://shub.club/icons/openstreetmap.png&quot; class=&quot;location-icon&quot; /&gt;
&lt;/a&gt;
&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;http://maps.apple.com/?address=2001%20Polk%20St,%20San%20Francisco,%20CA%2094109&amp;amp;dirflg=t&quot;&gt;
    &lt;img alt=&quot;Apple Maps Logo&quot; src=&quot;https://shub.club/icons/apple-maps.svg&quot; class=&quot;location-icon&quot; /&gt;
&lt;/a&gt;
&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://www.google.com/maps/search/?api=1&amp;amp;query=2001%20Polk%20St,%20San%20Francisco,%20CA%2094109&quot;&gt;
    &lt;img alt=&quot;Google Maps Logo&quot; src=&quot;https://shub.club/icons/google-maps.png&quot; class=&quot;location-icon&quot; /&gt;
&lt;/a&gt;
&lt;/span&gt;
    &lt;/div&gt;
&lt;/div&gt;&lt;/location&gt;
&lt;p&gt;Who would have thought purveyors of cheese would also make great sandwiches. Cheese plus is a real sourcer of the cheese devine, and their sandwiches really highlight that. I would say the cheesier the better here for what you order. I think american sandwich shops are generally afraid of stinky gooey cheeses in their sandwiches, which is fair as the american pallete is not well adjusted to it, especially since it usually means less meat as its too conflicting. The opportunity, though, as a cheese shop to provide us with those stinky sandwiches was realized here, and it&#39;s well worth.&lt;/p&gt;
&lt;p&gt;My rec is the Cole Valley, and of course a mini charcuterie board&lt;/p&gt;
&lt;h2&gt;The Boys Deli&lt;/h2&gt;
&lt;location address=&quot;2222 Polk St, San Francisco, CA 94109&quot;&gt;
&lt;div class=&quot;location-helper-wrapper&quot;&gt;
    &lt;div class=&quot;location-helper&quot;&gt;
        &lt;span&gt;2222 Polk St, San Francisco, CA 94109&lt;/span&gt;&lt;span class=&quot;links&quot;&gt;
&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://www.openstreetmap.org/search?query=2222%20Polk%20St,%20San%20Francisco,%20CA%2094109&quot;&gt;
    &lt;img alt=&quot;OpenStreetMap Logo&quot; src=&quot;https://shub.club/icons/openstreetmap.png&quot; class=&quot;location-icon&quot; /&gt;
&lt;/a&gt;
&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;http://maps.apple.com/?address=2222%20Polk%20St,%20San%20Francisco,%20CA%2094109&amp;amp;dirflg=t&quot;&gt;
    &lt;img alt=&quot;Apple Maps Logo&quot; src=&quot;https://shub.club/icons/apple-maps.svg&quot; class=&quot;location-icon&quot; /&gt;
&lt;/a&gt;
&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://www.google.com/maps/search/?api=1&amp;amp;query=2222%20Polk%20St,%20San%20Francisco,%20CA%2094109&quot;&gt;
    &lt;img alt=&quot;Google Maps Logo&quot; src=&quot;https://shub.club/icons/google-maps.png&quot; class=&quot;location-icon&quot; /&gt;
&lt;/a&gt;
&lt;/span&gt;
    &lt;/div&gt;
&lt;/div&gt;&lt;/location&gt;
&lt;p&gt;This is a real classic spot, tucked in the back of a grocery store you know this is gonna be a true deli experience. The sandwiches are toasted and roasted, with the classic boars head variety, special sauce and all those fresh sysco veggies you could dream of, but wait, the special sauce actually is special and they&#39;re putting some spice in their sandwiches too?? Yup its a deli+ meal here.&lt;/p&gt;
&lt;p&gt;My rec is a San Franpsycho on Dutch Crunch with chips and lemonade soda. Eat nearby because hot sandwiches can go bad fast&lt;/p&gt;
&lt;h2&gt;Also good, honorable mentions of sorts&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Molinari - great sandwiches if you can bare the line, preorder on doordash and it&#39;ll still be late (Get anything with foccacia)&lt;/li&gt;
&lt;li&gt;Golden Gate Market and Liquor - The best place to get a pretty decent sandwich near the presidio (Get the San Franpsycho)&lt;/li&gt;
&lt;li&gt;Grasso - If you want the same souricng as Molinari but dont want to wait (and its a weekday and you want to be in FiDi), come here&lt;/li&gt;
&lt;li&gt;Banh Mi Viet - I think visiting OC too many times has made me a prude in Banh Mis but this is pretty good stuff&lt;/li&gt;
&lt;li&gt;Sanguchon Eatery - Their adobo sandwich is good stuff&lt;/li&gt;
&lt;/ul&gt;
&lt;style&gt;
    picture {

width: 100%;
}



    p img {
aspect-ratio: 1/1 !important;
      width: 60%;
min-width: 350px;
      margin: 0 !important;
      max-width: 785px !important;
      padding: 1rem;
      border: 1px solid var(--border-color);
    }
&lt;/style&gt;</content>
  </entry>
  <entry>
    <title>I added a comments section!</title>
    <link href="https://shub.club/writings/2025/august/i-added-a-comments-section/"/>
    <updated>2025-08-18T00:00:00Z</updated>
    <id>https://shub.club/writings/2025/august/i-added-a-comments-section/</id>
    <content xml:lang="en" type="html">&lt;p&gt;I just added comments section to the blog part of this site. It&#39;s powered by &lt;a href=&quot;https://utteranc.es/&quot;&gt;utterances&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;This literally took me 1 minute to set up. It&#39;s really fast, and as you noticed, you don&#39;t actually need to use your exact github repo to host the comments, the comments are all stored on this &lt;a href=&quot;https://github.com/4shub/shubdotclub-comments&quot;&gt;repo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Very nice, post your thoughts below!&lt;/p&gt;
&lt;p class=&quot;tyler-inline&quot;&gt;
 Soon, I&#39;ll think of adding bluesky and &lt;input id=&quot;tyler-button&quot; class=&quot;tyler-button&quot; type=&quot;checkbox&quot; /&gt; &lt;label for=&quot;tyler-button&quot; class=&quot;tyler-active&quot;&gt;anon comments&lt;/label&gt;
&lt;video class=&quot;tyler&quot; autoplay=&quot;&quot;&gt;
  &lt;source src=&quot;https://shub.club/writings/2025/august/i-added-a-comments-section/sike.mp4&quot; type=&quot;video/mp4&quot; /&gt;
  Your browser does not support the video tag. (www.youtube.com/watch?v=RnbSom_zwfY) this the video I used.
&lt;/video&gt;
&lt;/p&gt;
&lt;style&gt;

.tyler-inline {
    display: inline;
}
    .tyler {
        display: none;
        margin: 1rem auto;
        width: 100%;
        max-width: 600px;
        border-radius: 1rem;
overflow: hidden;
     
    }

.tyler-active {
    text-decoration: underline;
cursor: pointer;
}
.tyler-button {
    position: absolute;
    top: 0;
    left: 0;
    width: 0%;
    height: 0%;
    opacity: 0;
    cursor: pointer;
}

.tyler-button:checked ~ .tyler {
    display: block;
    width: 100%;
}
&lt;/style&gt;
</content>
  </entry>
  <entry>
    <title>Soon we won&#39;t have a 2nd degree ”connection” to the 18th century</title>
    <link href="https://shub.club/writings/2025/august/end-of-an-era/"/>
    <updated>2025-08-17T00:00:00Z</updated>
    <id>https://shub.club/writings/2025/august/end-of-an-era/</id>
    <content xml:lang="en" type="html">&lt;p&gt;As we approach the 2030’s, we’re reaching a point where there won’t be someone alive today who had been around at the same time as someone who was alive in the 18th century (1701-1800).&lt;/p&gt;
&lt;p&gt;The oldest person around now was born in 1909 &lt;a href=&quot;https://en.wikipedia.org/wiki/Ethel_Caterham&quot;&gt;[1]&lt;/a&gt;, and it seems like there have been verifiable amounts of people who had been born in in the 1700s who made it to 110 &lt;a href=&quot;https://en.wikipedia.org/wiki/Margaret_Ann_Neve&quot;&gt;[2]&lt;/a&gt;. Given that the absolute longevity of a human seems to be 120 at most, (even with modern medicine) this probably will be the last decade we’ll have a 2nd degree “connection” to the century of the American revolution.&lt;/p&gt;
&lt;p&gt;It&#39;s interesting how long humans do live over so much history. Here&#39;s a video of a guy who witnessed the Lincoln assassination on TV in 1956.&lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/1RPoymt3Jx4?si=QgZ50TRnVcXl8wyt&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
&lt;p&gt;If someone aged 3-4 remembered this show, and lived to the human maximum expectancy, the second degree connection to the Lincoln assassination would be around well into the 2070&#39;s.&lt;/p&gt;
&lt;p&gt;But hey, we may invent functional immortality by then, and maybe we&#39;ll always have someone around who watched on TV live a guy who saw the Lincoln assassination.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Small Startups should go to Small Collegiate Hackathons</title>
    <link href="https://shub.club/writings/2025/may/small-startups-should-go-to-small-hackathons/"/>
    <updated>2025-05-12T00:00:00Z</updated>
    <id>https://shub.club/writings/2025/may/small-startups-should-go-to-small-hackathons/</id>
    <content xml:lang="en" type="html">&lt;p&gt;Between March and April of 2025, I went to three hackathons as a representative of the startup I currently work for. As someone who grew up around hackathons and fell in love with computer science through it, I&#39;ve been big advocate of those events. The startup I am currently at is pretty small, at the time only 5 employees including the founders. But we had a product and a platform, and we were gaining traction too, so I felt like it was a good time to spend some of their funding round on going to a hackathon.&lt;/p&gt;
&lt;p&gt;What hackathon though? What was our goal from even going to these events? My pitch to my team was the following, our platform is in a refinement phase, and we need to test out our APIs in how effectively can developers  understand our documentation and build their end productions from it. Hackathons then became the best place to people watch a group of developers who have a wide range of skill levels interface with your application.&lt;/p&gt;
&lt;p&gt;What we wanted to do at each event was to be able to present our product, both pitching at our table and giving a workshop on more in-depth usage; get feedback from developers and get a little bit of marketing material and potential interns from students who successfully build something on-top of our APIs. That means we had to go to events that let us host a prize, give a workshop and table at the event.&lt;/p&gt;
&lt;p&gt;Our budget? $6000.&lt;/p&gt;
&lt;p&gt;$6000 at an event at [big name school]  would maybe get you a table among the 100 other companies that show up. It didn’t seem like a good deal to us. When I was in college, I ran my own event, HackMerced and knew plenty of other schools that threw their own events that had around 250-500 students but had sponsorship packages between 1-3,000$ that could give us everything we needed.&lt;/p&gt;
&lt;p&gt;I found three event  that could give us what we wanted with our budget, HackDavis, DiamondHacks and HackMerced. HackMerced, of course was a little bias, but you gotta make deals where you can. The other two events were both relatively affordable and let us meet with hundreds of students and have a very successful  hackathon run.&lt;/p&gt;
&lt;p&gt;Success for us of course meant:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Battle testing out software; hundreds of students hitting your APIs at once in ways you may have never even thought of&lt;/li&gt;
&lt;li&gt;Understanding the best way to pitch our product to developers with no background in our specific domain&lt;/li&gt;
&lt;li&gt;Debugging foot guns and bad documentation&lt;/li&gt;
&lt;li&gt;Building rapport with developers early, becoming the go to tool for those starting off&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I think these three events really got us that, I posted on LinkedIn about all of them here if &lt;a href=&quot;https://www.linkedin.com/posts/shubhamnaik_insights-for-letta-hackmerced-why-activity-7305282238508609536-pSBM?utm_source=share&amp;amp;utm_medium=member_desktop&amp;amp;rcm=ACoAABGBmisBZq6ce70GPfcgLq9oR-aatnFb5P8&quot;&gt;you&lt;/a&gt; &lt;a href=&quot;https://www.linkedin.com/posts/shubhamnaik_i-had-the-pleasure-this-weekend-to-visit-activity-7315114422564204544-eVDG?utm_source=share&amp;amp;utm_medium=member_desktop&amp;amp;rcm=ACoAABGBmisBZq6ce70GPfcgLq9oR-aatnFb5P8&quot;&gt;want&lt;/a&gt; to &lt;a href=&quot;https://www.linkedin.com/posts/shubhamnaik_last-weekend-we-were-honored-to-sponsor-hackdavis-activity-7320130976712470528-Wp_D?utm_source=share&amp;amp;utm_medium=member_desktop&amp;amp;rcm=ACoAABGBmisBZq6ce70GPfcgLq9oR-aatnFb5P8&quot;&gt;know&lt;/a&gt; specifics.&lt;/p&gt;
&lt;p&gt;For you, fellow startup founder, I would say you should go to these events if you’re thinking about launching an API. You don’t know how much ROI you get out of events like these until you try.&lt;/p&gt;
&lt;p&gt;Beyond budget, I’d still advise going small. It may seem appealing to go to the biggest events, but you’ll have more time and energy on impressions on students when you’re in a group of 5 sponsors versus 50, plus the top hackathon participants generally go to other hackathons beyond their home school, you won’t be missing out on coverage there.&lt;/p&gt;
&lt;p&gt;Some other tips:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Come with your co-founder, these events will have students coming at all times to your booth, be sure you have someone and maximize your time here.&lt;/li&gt;
&lt;li&gt;Get a hotel close-by, best walking distance&lt;/li&gt;
&lt;li&gt;Actually sleep, students might be braindead by the end of the event, you shouldn’t&lt;/li&gt;
&lt;li&gt;The last 5 hours of the event will have the most questions about your API&lt;/li&gt;
&lt;li&gt;Bring extra snacks for students&lt;/li&gt;
&lt;li&gt;While cash prizes are an incentive, your submission rate won’t change much by offering something like a prize item instead. Also lots of events discourage cash prizes due to higher rates of cheating.&lt;/li&gt;
&lt;li&gt;Want to find a hackathon to sponsor, just make your way down &lt;a href=&quot;https://mlh.io/seasons/2025/events&quot;&gt;this list&lt;/a&gt; by MLH (Major League Hacking)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;More hackathon blog posts soon, thanks for reading.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Don&#39;t overcomplicate posting</title>
    <link href="https://shub.club/writings/2025/april/dont-overcomplicate-posting/"/>
    <updated>2025-04-02T00:00:00Z</updated>
    <id>https://shub.club/writings/2025/april/dont-overcomplicate-posting/</id>
    <content xml:lang="en" type="html">&lt;p&gt;I was checking out this software called &lt;a href=&quot;https://utteranc.es/&quot;&gt;utteranc.es&lt;/a&gt;, thinking about how I can add a comment section to this blog. Not sure if I&#39;ll stick with it or implement it. But one thing I noticed is that the copy representing &amp;quot;sites using utterances&amp;quot; are two dead* sites.&lt;/p&gt;
&lt;p&gt;Blogs can die very fast, utterances was written in 2017, now it&#39;s 2025, those example sites are dead. Do I think my website will last another 8 years? Maybe, hopefully - I&#39;ll be in my mid 30&#39;s by then!!&lt;/p&gt;
&lt;p&gt;shub.club was alive in 2017, but it&#39;s been down and deleted many times due to me not wanting to pay hosting bills; now I just coast off of github pages and cloudflare.&lt;/p&gt;
&lt;p&gt;Moral of the story - don&#39;t pay for hosted software solutions, prepay your domain name for as long as you can, and host your blog for as cheap or free as possible! I love reading old blogs, keep them alive for me.&lt;/p&gt;
&lt;p&gt;*&lt;a href=&quot;http://sadsloth.net/&quot;&gt;sadsloth.net&lt;/a&gt; has become an indonesian fake slots website, I have no idea what&#39;s going on here. (Look at the image below)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://shub.club/writings/2025/april/dont-overcomplicate-posting/what.png&quot; alt=&quot;what&quot; /&gt;&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>It&#39;s actually easy to name 100 women</title>
    <link href="https://shub.club/writings/2025/march/100-women/"/>
    <updated>2025-03-31T00:00:00Z</updated>
    <id>https://shub.club/writings/2025/march/100-women/</id>
    <content xml:lang="en" type="html">&lt;p&gt;I was watching one of my favorite YouTube series&#39; called Jetlag last week when I saw the contestants Sam and Tom Scott struggling to name 100 women.&lt;/p&gt;
&lt;iframe width=&quot;100%&quot; height=&quot;400px&quot; src=&quot;https://www.youtube.com/embed/dsDy5VAw-xo?si=4BzVGeur0RIBbI17&amp;amp;controls=0&amp;amp;start=3282&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
&lt;p&gt;This is most likely not out of their specific implicit biases against women, but just the human brain unable to deal with loading 100 things at once. The best way to tackle this challenge is split it up and name 3-5 women per first letter in the alphabet, and you&#39;ll get to 100 in a faster time than random iteration:&lt;/p&gt;
&lt;p&gt;If that&#39;s still too hard, split it into categories you know well:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sports&lt;/li&gt;
&lt;li&gt;Politics&lt;/li&gt;
&lt;li&gt;Movies&lt;/li&gt;
&lt;li&gt;Music&lt;/li&gt;
&lt;li&gt;Art&lt;/li&gt;
&lt;li&gt;History&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To take on big tasks is to split them up into smaller ones!&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>I thought I&#39;d never get addicted to my phone but here I am</title>
    <link href="https://shub.club/writings/2025/march/phone-addiction/"/>
    <updated>2025-03-30T00:00:00Z</updated>
    <id>https://shub.club/writings/2025/march/phone-addiction/</id>
    <content xml:lang="en" type="html">&lt;p&gt;Knowing my way around technology was easy for me; I was born in the late 90&#39;s and grew up in the Silicon Valley. My dad was a software engineer with a hobby of collecting the latest and greatest tech, and my mom was an academic who sparked my interest in research and just lokking things up. I was using a desktop around 8-9 years old to make “websites” in Word and trawl Wikipedia for fun articles. I was into technology, and while on a computer a lot, I felt like my childhood and teenage years were full of relatively healthy technology usage. I felt most of my time on my computer was building things, games, art, programs or reading, I was challenging my mind and growing with tech. I felt knew how to handle it, harness it and make it work for me.&lt;/p&gt;
&lt;p&gt;Earlier this decade, when TikTok was becoming the zeitgeist, I decided to hop onto there, but soon deleted it after a month. Realizing how good their algorithm was to get me hooked to those reels, I thought to myself: “wow, I have a pretty good sense of these things, I won’t get addicted to short form reels, I&#39;ll delete TikTok and just just stick to Youtube and Instagram reels, their algorithms suck, I’ll just watch a few to be entertained, I won&#39;t get addicted, this is just entertainment”&lt;/p&gt;
&lt;p&gt;But here I am in my late 20’s, scrolling away.&lt;/p&gt;
&lt;p&gt;I feel my brain has created a link with my phone, if I step away for too long, I get a headache that doesn&#39;t go away until I&#39;m on my phone or doing something else stimulating (cycling, programming, etc), but I can&#39;t stay still anymore. The only relief is that if I don&#39;t entertain it for long enough, it sometimes goes away. I think I still have a way out. I just removed both apps from my phone, I&#39;m pretty good at not using mobile web versions due to poor usability. Let&#39;s see what happens now.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Long Interviews are an antipattern.</title>
    <link href="https://shub.club/writings/old/long-interviews-are-an-antipattern/"/>
    <updated>2025-02-23T00:00:00Z</updated>
    <id>https://shub.club/writings/old/long-interviews-are-an-antipattern/</id>
    <content xml:lang="en" type="html">&lt;p&gt;For the length of my career in startups, both as an interviewee and interviewer, interviews are way too long and way too uninteresting. Today I see startups attempting to do on sites that last multiple days, or take homes that only take “3-4” hours to complete, or even worse, making a founding engineer do sets of leetcode problems to get signal.&lt;/p&gt;
&lt;p&gt;But why are some startup interview processes are so long? What that leads to this and what we do as startups to actually hire great talent without spending 12+ hours of your time on seeing people write the same code over and over again.&lt;/p&gt;
&lt;h2&gt;The origins of long and boring interview processes&lt;/h2&gt;
&lt;p&gt;Hiring in a startup is much more unpredictable than hiring in a big company, while on the surface, the ultimate goal is to get a butt into a seat to start coding something. A startup, due to the size, has greater risks when  adding a single employee to the roster, as every employee brings their own biases, skills and culture to your company. When you have 1000 employees, every new employee is only contributing a fraction of a percent to your company’s growth, versus in a startup of 4, a new employee would be seen as 20%.&lt;/p&gt;
&lt;p&gt;That % can be extremely positive -- hiring someone who’s 20% of your company and is: extremely skilled, gets along with everyone, and can teach the team is going to much more greatly affect the overall output of the team. On the flip side, a bad 20% hire can completely disable a team, even if the other 80% are working the most optimally.&lt;/p&gt;
&lt;p&gt;It then seems reasonable then for startup founders to spend 12-30 hours over multiple weeks interviewing the same person just to be absolutely sure they’re going to get the person they need. It seems like a fair trade, right?&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://shub.club/writings/old/long-interviews-are-an-antipattern/signal-to-noise.svg&quot; alt=&quot;signal to noise&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Perverse incentives&lt;/h2&gt;
&lt;p&gt;The standard interview process comprises three parts, an introductory interview to validate alignment on the role, a set of technical interviews to validate ability and then a final stage, usually an onsite, full of a bunch of small interviews to check the work of the two first interviews. The phone screen and technical interview will give you 75% of the signal you really need, everything else will get you the remaining 25%. With this configuration, it is only natural that most companies traditionally only have three rounds.&lt;/p&gt;
&lt;p&gt;But startups and even some larger companies seem to think having multiple remote technical rounds or multiple days of onsite interviews can help them get a better signal, but asking someone the same questions of different flavor over and over again will ultimately reduce the amount of signal you can get from someone every time; and it leads to a great filtering. The more you ask and prod, the more time you waste for the engineer, who could go for someone else in the meantime. You may only get the most desperate of engineers.&lt;/p&gt;
&lt;p&gt;There’s nothing wrong for an engineer to be desperate inherently, we all need to pay bills and sometimes you get unlucky with interviewing, but desperate engineers are also going to the engineers who will take bigger risks to get hired, this could be as simple as cheating, or even worse not actually even wanting to work at your company since they just want to get paid by someone.&lt;/p&gt;
&lt;p&gt;For both a big and small company, someone who lies about their qualifications is bad; but for a startup, a disinterested employee can be its own level of destructive.&lt;/p&gt;
&lt;p&gt;The more steps and stages, and the more time you take between interview spots, the fewer people will be interested in working with you, not because your product Is bad or not interesting, but because either there are limitations to how much time people can take off from their current job, or another startup that is as equally as interesting has a shorter interview loop that will get them the offer instead.&lt;/p&gt;
&lt;p&gt;If you have things like multi day on-sites, even if they’re paid, your sample of people who will do this is much smaller and mostly will consist of people who aren’t working right now. Which, again isn’t a negative signal, but you lose the ability to hire people who do have a current job, so you just lose access to people who you might like more.&lt;/p&gt;
&lt;h2&gt;What’s the fix?&lt;/h2&gt;
&lt;p&gt;On the surface, the fix is just do the standard three phase interview: Phone screen, online technical, and onsite. Nothing else; but we don’t fix the boring part here, we don’t want you to waste your time as well with low signal interviews.&lt;/p&gt;
&lt;h3&gt;Identifying your values and the pre-interview&lt;/h3&gt;
&lt;p&gt;Life is a set of values that you apply into the real world; the same can be said about a startup. What are the values of your startup, are they working long hours to get to a goal, are efficiency trumps time, or is it let’s build the least harmful product possible. There’s lots of values you can have in a startup, but you can bucket them into a few categories:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How do you want engineers to spend their time?
&lt;ul&gt;
&lt;li&gt;Do you think most of their work should be research, should it be application, or should it be a mix&lt;/li&gt;
&lt;li&gt;Engineers who are dead set on goals will show off their resume based on growing existing products, those on their learning and growth may show off new projects and verticals&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;How do you determine efficiency?
&lt;ul&gt;
&lt;li&gt;Are efficient engineers who spend the most time on deliverables, or are they engineers who spend their time mostly on building solid fundamentals first&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Do you value implicit or explicit communication?
&lt;ul&gt;
&lt;li&gt;Do you need daily standups or do you want your team to update their boards where you can check them instead&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Do you value credentials?
&lt;ul&gt;
&lt;li&gt;Do you care if your engineers are all from a bootcamp or do they need to have a college brand or another big company&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Do you want to foster growth or do you want people who grow by themselves?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And many more, and most good hiring managers think of these things when looking at a resume before even talking to a candidate. You can take those values and map them to how a candidate portrays their work. If you see their project brief and see that tenure is shorter at companies where projects seem more simple, it probably means this engineer values challenge, or if you see them list mostly mentorship and leadership skills over code written, it probably means they’re not going to write as much code, and maybe a good fit to build team instead.&lt;/p&gt;
&lt;h3&gt;The Phone Screen&lt;/h3&gt;
&lt;p&gt;Once you’ve screened a resume, you should have already filtered out 90% of the talent that comes in, as long as you know your values.&lt;/p&gt;
&lt;p&gt;The phone screen then becomes  the fastest way to figure out if someone is actually going to join your team or not. Many times I’ve done phone screens, I can almost exactly tell if someone is going to pass the onsite then and there and who’s not, and I’m sure most of you feel the same.&lt;/p&gt;
&lt;p&gt;What should you be asking then?&lt;/p&gt;
&lt;p&gt;You should take the values you have, and try to figure out if your assumptions of them are true, not necessarily  literally asking them the questions above, but instead trying to figure out if their work behavior in the past aligns with the values your company has.&lt;/p&gt;
&lt;p&gt;If they align with your values, you’re good to go, if not, then maybe you shouldn’t send them off for 10 more rounds.&lt;/p&gt;
&lt;h3&gt;The Technical&lt;/h3&gt;
&lt;p&gt;The online technique is probably the worst implemented part of any interview process. Some companies believe that a generic coding challenge is good enough to qualify someone to be on your team. And for a huge company, this makes sense, you don’t necessarily  need someone who knows anything broader than how to program to work with you, as large companies have ramp up times that people can become accustomed to, even if it’s different programming languages.&lt;/p&gt;
&lt;p&gt;For you though, a startup, you want something more practical, you probably want an engineer who knows the language you coded your startup in, and probably more than you hopefully too. Many startups have begun to believe that the most equitable and simple task is giving a developer a prompt or a codebase and telling them to spend between 8-36 hours building them something to present. This sounds good, if you want to hire someone desperate or a contracting firm.&lt;/p&gt;
&lt;p&gt;Most people don’t want to waste time, even if they think your company is great at building a whole app in their free or paid time. Your scope of hires starts shrinking as soon as you make interviews longer than standard ones. The second issue is also, you don’t actually know what they’re doing at that time; the technical interview is not just about seeing if someone can code, it&#39;s a first look at how someone thinks about problems. And you lose 50% of that in a take home interview; even if you make them present it afterwards; it’s often a negative signal, as engineers, especially those in earlier career paths are not as trained in technical presentations.&lt;/p&gt;
&lt;p&gt;What I do nowadays is I build a project halfway: if it&#39;s for a full-stack dev, I’ll build a Next.JS app with a prebuilt sqlite db; for a platform engineer, a docker compose with some services and a working app; this halfway project will have challenges; different tasks from different skill sets you can identify from those types of engineers; a full stack engineer could be amazing at design and databases but are just ok at building APIs, construct enough different challenges for engineers to possibly do, and make sure all of them take around an hour to actually do. Now; give your candidate this codebase a few days before the interview, and tell them to pick a challenge. Tell them you can look and prod the codebase but don’t start working on anything or sharing the code.&lt;/p&gt;
&lt;p&gt;Doing this interview style you gain a few things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Remove engineer stress from throwing random prompts at them as they know the challenge is, engineers don&#39;t work from black boxes in the real world, why are they here&lt;/li&gt;
&lt;li&gt;Give them a look at what your company is working with; sometimes you accidentally get someone who’s more suited for a different role, and they’ll let you know from just looking at the codebase&lt;/li&gt;
&lt;li&gt;Not making your interview super long, you keep the engineers who lose you to just time constraints&lt;/li&gt;
&lt;li&gt;Doing something kind of fun and entertaining that has to do with what they probably also are good at; leetcode is a drain and a grind, and most people even if they’re good at them, don’t like doing these problems, and can just lead to negative signal unnecessarily&lt;/li&gt;
&lt;li&gt;Give you insight on how they approach a problem; are they someone who is curious and looks at problems beforehand, or are they people who wait for the time to actually interview.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;The onsite&lt;/h3&gt;
&lt;p&gt;The onsite or final stage exists for two reasons, one to check your work, and two examine culture fit. Your first two stages should have been good enough to weed out most interviewees, the onsite should only be there to validate your assumptions on their fit within your company.&lt;/p&gt;
&lt;p&gt;To me, the best way to accomplish this is for them to run through the first two interviews parts again, but in a different format:&lt;/p&gt;
&lt;p&gt;The start of your onsite day should be a meeting with the candidate and your team. Go over what was done on the technical and let them know they will be completing some more challenges from that interview.&lt;/p&gt;
&lt;p&gt;The candidate has had some hands-on experience with the codebase, and you should instruct your candidate to take some time to write up an architecture doc on how they plan on tackling this next challenge.&lt;/p&gt;
&lt;p&gt;From there; you should give them some time to write up a spec, meet with them after an hour and discuss. I never understood why system design interviews had to be drawn in front of an audience. Usually engineers are left alone when writing specs in real life. The only time they start talking to others is in the feedback phase.&lt;/p&gt;
&lt;p&gt;From there, they should spend the rest of the day working on that challenge or challenges, similar to a work day, and in the middle of the day, you all should go out for a lunch, because then you can really vibe check someone on how they hang. Of course they might be a little nervous, as it is an interview, but as an interviewer, you should try your best to break the ice.&lt;/p&gt;
&lt;p&gt;From there, they should have a check-in with you about progress, you should give feedback to the current work at hand, maybe suggesting changes or asking their opinion on why they did something, all this should be to derive a signal about ability but also to tie it again into your startup’s values.&lt;/p&gt;
&lt;p&gt;At the end of the day, you should save a good hour on a discussion of the candidates work. Let them explain to you and your team what they did and what they accomplished, it doesn’t need to be super presentationally, you should make that a point, and it should be casual; you may learn something about how they implemented a feature or did something cool, this is a massive signal.&lt;/p&gt;
&lt;p&gt;Then you send them off. And you and your team should immediately  discuss them. Any time you sit on candidates, you lose your impressions of them, and two you lose time for them possibly signing with someone else. Discuss immediately, see if the values and abilities align.&lt;/p&gt;
&lt;p&gt;Then send them the offer. That&#39;s it.&lt;/p&gt;
&lt;p&gt;Good night&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>How I eleventy</title>
    <link href="https://shub.club/writings/old/notes-on-eleventy/"/>
    <updated>2025-01-31T00:00:00Z</updated>
    <id>https://shub.club/writings/old/notes-on-eleventy/</id>
    <content xml:lang="en" type="html">&lt;p&gt;In 2025 I started using Eleventy (11ty) for building my personal website. 11ty fundamentally is a tool that takes in an input directory of files and ouputs them to a dist directory. The parsing of those files are controlled in a file called &lt;code&gt;eleventy.config.js&lt;/code&gt;. That&#39;s it! It&#39;s super extensible, and below are some cool things I do with 11ty.&lt;/p&gt;
&lt;h2&gt;How I organize my code&lt;/h2&gt;
&lt;p&gt;I structure my 11ty code as below&lt;/p&gt;
&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;filesystem
├─ dist
├─ public
├─ eleventy.config.ts
├─src
  ├─ _components
  ├─ _includes
      ├─ layouts&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I have a public folder containing any global information, I use the &lt;code&gt;addPassthroughCopy&lt;/code&gt; function to set this up&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;eleventyConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addPassthroughCopy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__dirname&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;public&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;public&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I place the rest of my code in &lt;code&gt;src&lt;/code&gt;, which is configured by the return statement in the config file&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;eleventyConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; UserConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// rest of my code&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    dir&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      input&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;src&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      output&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;dist&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;My layouts are in the &lt;code&gt;_includes&lt;/code&gt; directory, this is a default directory used file imports&lt;/p&gt;
&lt;p&gt;I have a &lt;code&gt;_components&lt;/code&gt; folder that contains reusable web-components, you can see the section &lt;a href=&quot;https://shub.club/writings/old/notes-on-eleventy/#playing-with-webc&quot;&gt;Playing with WebC&lt;/a&gt; for more details&lt;/p&gt;
&lt;h2&gt;Playing with WebC&lt;/h2&gt;
&lt;p&gt;Web components are actually really sick, and 11ty has a plugin that lets you use them in your code. First I use the package &lt;code&gt;@11ty/eleventy-plugin-webc&lt;/code&gt; then do the following in my config file.&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; pluginWebc &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;@11ty/eleventy-plugin-webc&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;eleventyConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; UserConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  eleventyConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addPlugin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pluginWebc&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Glob to find no-import global components&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// This path is relative to the project-root!&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// The default value is shown:&lt;/span&gt;
    components&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;src/_components/**/*.webc&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Web components are a little different in 11ty, they are written in a &lt;code&gt;.webc&lt;/code&gt; file which can contain your standard html tags, css, and javascript. Then 11ty will bundle and process them up, so you don&#39;t need to do any custom javascript finagling for building web components in the documented way.&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;current-time&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    [00:00:00]
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;style&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token style&quot;&gt;&lt;span class=&quot;token language-css&quot;&gt;
    &lt;span class=&quot;token selector&quot;&gt;#current-time&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;font-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1.5em&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; #333&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;style&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;span class=&quot;token language-javascript&quot;&gt;

    &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getTime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; currentTime &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;current-time&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; date &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; hours &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Intl&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;NumberFormat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;en-US&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token literal-property property&quot;&gt;minimumIntegerDigits&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getHours&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; minutes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Intl&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;NumberFormat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;en-US&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token literal-property property&quot;&gt;minimumIntegerDigits&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getMinutes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; seconds &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Intl&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;NumberFormat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;en-US&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token literal-property property&quot;&gt;minimumIntegerDigits&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getSeconds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        currentTime&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;innerHTML &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;hours&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;minutes&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;seconds&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;setInterval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;getTime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;getTime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The code above I use to display the current time on my website, I save it as &lt;code&gt;current-time-component.webc&lt;/code&gt; in my &lt;code&gt;_components&lt;/code&gt; folder. I then import by just writing &lt;code&gt;&amp;lt;current-time&amp;gt;&amp;lt;/current-time&amp;gt;&lt;/code&gt; in other webc files. In njk files I have to use the renderTemplate function to render the web component.&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;{ % renderTemplate &quot;webc&quot; %}
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;current-time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;current-time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
{ % endrenderTemplate %}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The renderTemplate function is another 11ty plugin, it allows some mixed templating languages in your code.&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; EleventyRenderPlugin &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;@11ty/eleventy&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;eleventyConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; UserConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  eleventyConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addPlugin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;EleventyRenderPlugin&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
</content>
  </entry>
  <entry>
    <title>Building with server-sent events with React and Node.js</title>
    <link href="https://shub.club/writings/old/building-with-server-sent-events/"/>
    <updated>2020-05-22T00:00:00Z</updated>
    <id>https://shub.club/writings/old/building-with-server-sent-events/</id>
    <content xml:lang="en" type="html">&lt;p&gt;Building real-time applications on the web has never been easier. In this post, I&#39;ll explain how you can use &lt;strong&gt;server-sent events&lt;/strong&gt;, or &lt;strong&gt;SSE&lt;/strong&gt; for short, to get real-time data for your web applications.&lt;/p&gt;
&lt;p&gt;At the end of this article you should know:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What a server-sent event is&lt;/li&gt;
&lt;li&gt;How to listen to server-sent events on the browser&lt;/li&gt;
&lt;li&gt;How to send server-sent events from your server&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This tutorial is for those who have some familiarity with developing on the web as well as some knowledge in either python or nodejs.&lt;/p&gt;
&lt;h2&gt;The gist&lt;/h2&gt;
&lt;p&gt;Server-sent events (SSE) are a client initiated, unidirectional, server controlled messages. When you visit a website that queries an SSE-enabled endpoint, the server can send your browser unlimited amounts of information until you leave that page. SSE urls are always accessed via an asynchronous request from your browser. You can visit a url that serves an SSE endpoint from your browser but there is no standard on what you will experience.&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; source &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EventSource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/an-endpoint&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

source&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;onmessage&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;logEvents&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
   console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this code snippet, I create a new &lt;code&gt;EventSource&lt;/code&gt; object that listens on the url  &lt;code&gt;/an-endpoint&lt;/code&gt;. &lt;code&gt;EventSource&lt;/code&gt; is a helper class that does the heavy lifting of listening to server-sent-events for us. All we need to do  now is to attach a function, in this case &lt;code&gt;logEvents&lt;/code&gt;, to the &lt;code&gt;onmessage&lt;/code&gt; handler.&lt;/p&gt;
&lt;p&gt;Any time our server sends us a message, &lt;code&gt;source.onmessage&lt;/code&gt; will be fired.&lt;/p&gt;
&lt;p&gt;Let&#39;s look at a more realistic example. The code below listens on a server at the url &lt;code&gt;https://ds.shub.dev/e/temperatures&lt;/code&gt;. Every 5 seconds, the server returns a server-sent event with the temperature of my living room.&lt;/p&gt;
&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;
&lt;span class=&quot;token comment&quot;&gt;// @codepen-link:https://codepen.io/4shub/pen/QWjorRp&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; useState&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; useEffect &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;react&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; render &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;react-dom&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;useEventSource&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; updateData&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token function&quot;&gt;useEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; source &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EventSource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
        source&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;onmessage&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;logEvents&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;      
            &lt;span class=&quot;token function&quot;&gt;updateData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;event&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;     
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useEventSource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;https://ds.shub.dev/e/temperatures&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;The current temperature in my living room is &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;temperature&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt; as of &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;updatedAt&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;App&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;root&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;What&#39;s happening behind the scenes?&lt;/h3&gt;
&lt;p&gt;Let&#39;s look at these two properties of EventSource:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;url&lt;/code&gt; - The url that we want to listen on for changes&lt;/li&gt;
&lt;li&gt;&lt;code&gt;readyState&lt;/code&gt; - The state of the connection. This can be &lt;code&gt;(0) CONNECTING&lt;/code&gt;, &lt;code&gt;(1) OPEN&lt;/code&gt; and &lt;code&gt;(2) CLOSED&lt;/code&gt;. Initially this value is &lt;code&gt;CONNECTING&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When EventSource is invoked, the browser creates a request with the header &lt;code&gt;Accept: text/event-stream&lt;/code&gt; to the &lt;code&gt;url&lt;/code&gt; that was passed through.&lt;/p&gt;
&lt;p&gt;The browser will then verify if the request returns a &lt;code&gt;200 OK&lt;/code&gt; response and a header containing &lt;code&gt;Content-Type&lt;/code&gt;: &lt;code&gt;text/event-stream&lt;/code&gt;. If successful, our &lt;code&gt;readyState&lt;/code&gt; will be set to &lt;code&gt;OPEN&lt;/code&gt; and trigger the method &lt;code&gt;onopen&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The data from that response will then be &lt;a href=&quot;https://html.spec.whatwg.org/multipage/server-sent-events.html#parsing-an-event-stream&quot;&gt;parsed&lt;/a&gt; and an event will be fired that triggers &lt;code&gt;onmessage&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Finally, the server we pinged can send us an unlimited amount of &lt;code&gt;event-stream&lt;/code&gt; content until:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We close our page&lt;/li&gt;
&lt;li&gt;We fire the &lt;code&gt;close()&lt;/code&gt; method on event source&lt;/li&gt;
&lt;li&gt;The server sends us an invalid response&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When we finally close our connection, the &lt;code&gt;EventSource&lt;/code&gt; object&#39;s &lt;code&gt;readyState&lt;/code&gt; will fire a task that sets &lt;code&gt;readyState&lt;/code&gt; to &lt;code&gt;CLOSED&lt;/code&gt; and trigger the &lt;code&gt;onclose&lt;/code&gt; event.&lt;/p&gt;
&lt;p&gt;In case of a network interruption, the browser will try to reconnect until the effort is deemed &amp;quot;futile,&amp;quot; as determined by the browser (unfortunately, there are no standards on what constitutes &amp;quot;futile&amp;quot;).&lt;/p&gt;
&lt;h2&gt;Sending events on the server&lt;/h2&gt;
&lt;p&gt;Sending server-sent events is just as easy as listening to them. Below, I&#39;ve written a few different implementations of sending server-sent events to your client.&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// @repl-it-link:https://repl.it/@4shub/server-sent-events-node&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; express &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;express&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; server &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;express&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; port &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// create helper middleware so we can reuse server-sent events&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;useServerSentEventsMiddleware&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setHeader&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;Content-Type&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;text/event-stream&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setHeader&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;Cache-Control&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;no-cache&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// only if you want anyone to access this endpoint&lt;/span&gt;
    res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setHeader&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;Access-Control-Allow-Origin&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;*&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;flushHeaders&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;sendEventStreamData&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; sseFormattedResponse &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;data: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#92;n&#92;n&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sseFormattedResponse&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// we are attaching sendEventStreamData to res, so we can use it later&lt;/span&gt;
    Object&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;assign&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;res&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        sendEventStreamData
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;streamRandomNumbers&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// We are sending anyone who connects to /stream-random-numbers&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// a random number that&#39;s encapsulated in an object&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; interval &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setInterval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;generateAndSendRandomNumber&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sendEventStreamData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// close&lt;/span&gt;
    res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;close&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;clearInterval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;interval&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

server&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/stream-random-numbers&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; useServerSentEventsMiddleware&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    streamRandomNumbers&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;


server&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;port&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Example app listening at 
    http://localhost:&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;port&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the example above, I created a server with an event-stream that sends users a random number every second.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Many companies use server-sent events to pipe data to their users in real time. LinkedIn uses server sent events for their &lt;a href=&quot;https://engineering.linkedin.com/blog/2016/10/instant-messaging-at-linkedin--scaling-to-hundreds-of-thousands-&quot;&gt;messaging service&lt;/a&gt;, Mapbox uses SSE to &lt;a href=&quot;https://www.mapbox.com/solutions/real-time-maps&quot;&gt;display live map data&lt;/a&gt;, and many analytics tools use SSE to show real-time user reports. SSE will only become more prominent as monitoring tools and real-time events become more relevant to users.&lt;/p&gt;
&lt;p&gt;Let me know if you try it out — I&#39;d love to see what you come up with!&lt;/p&gt;
</content>
  </entry>
</feed>
