2026-07-27 14:10:00
Hey friends!
We made it to the end of July! It's been a fun summer and though we still have August to work through... I am so excited to be closer to fall time. Ha! Anyway, let's learn!
Was this forwarded to you? You can subscribe here!
Astro vs Next.js 2026
Build a HTML5 game like Geometry Dash using Phaser 4 and TypeScript, with a simple custom physics engine
RSS in 2026 — the best distribution channel nobody uses
A system prompt to get AI to stop pretending to be human
I had a very action-packed "offline" week, with a wedding of a good friend (where my daughter was a flower girl and my husband played piano!) and a gathering at a lake house and a birthday party and visits with family and friends. Phew!
Whenever I have these offline times, I admit part of me feels like I should be more productive in some way. It's hard to shake it in like... how we're trained to think in this society. But, that's why I chose the quote in the newsletter subject this week! Having a mental break and an enjoyable time matters.
...all that being said, I did enter a hackathon this week. Check out my fun lil entry and the repo!
If you’re evaluating voice APIs, SpeechifyAI is worth your eyes (and ears)!
Their Simba 3.2 TTS API is at the top of voice-quality blind-testing leaderboards, is the cheapest option in the top 10 (by far), and is fast enough for real-time voice agent use cases.
They also offer Simba Voice Agents for low-latency conversational AI, plus a free tier so you can test quickly.
Try it today at speechify.ai.
Last week, I had you return the gap between blinks! Batting my eyes at Ten, Micah, Willy, Ross, Austin, Brooks, David, Christian, Iain, Thulasi, Alex, Andrew, Trey, Amine, and the smarties in the Ruby Users Forum!
This week's question:
Given an array of ice cream orders and a freezer stock map, return how many orders can be fulfilled before the first unavailable flavor.
Example:
> fulfilledOrdersBeforeFailure(
[["chocolate"],["chocolate"],["chocolate"]],
{ chocolate: 2 })
> 2
> fulfilledOrdersBeforeFailure(
[["vanilla","vanilla"],["chocolate","mint"],["strawberry"],["strawberry","mint"]],
{ vanilla: 2, chocolate: 1, mint: 1, strawberry: 5 })
> 3
> fulfilledOrdersBeforeFailure(
[["rocky road"],["vanilla"]],
{ vanilla: 3 })
> 0
(you can submit your answers by replying to this email with a link to your solution, or share on Bluesky, Twitter, LinkedIn, or Mastodon)
How the Words We Teach English Language Learners Changed, and What That Says About Us
The gap is not glorious
I Guess I'm Playing The Long Game Now
Dimple r3 40% Cozy Keyboard Build (video)
Did you hear about the 1790s French music?
It's royalty free!
That's all for now, folks! Have a great week. Be safe, make good choices, and have a sleepover with your friends!
Special thanks to Ben, Kinetic Labs, and Marta for supporting my Patreon and this newsletter!
cassidoo
website | blog | github | bluesky | youtube | twitch | twitter | patreon | codepen | mastodon
2026-07-20 15:53:50
Hola hola amigos!
I hope you had a fun week! I enjoyed hanging out with friends and family and watching Spain win the World Cup! Let's boogie.
Was this forwarded to you? You can subscribe here!
In defense of polyfills
How to build a design system strategy you'll actually deliver
Equinox: Test light and dark mode at the same time
Microsoft Comic Chat is now open source
It was a good week! I feel like I both was wildly busy the entire time, and also like I got nothing done. We had multiple engagement celebrations, family time, friends time, work time, and some time in between to watch the show Better Late Than Single on Netflix (which is a Korean dating show that is both entertaining and infuriating). I'm also reading the book Welcome to the Hyunam-dong Bookshop now (a recommendation from a reader here!) and it's really nice so far!
Also, I noticed that the Twitter algorithm changed this week. I made a video about it, mostly in a conflicted state, because... eh, it's fun, but I'm not sure how I feel about social media platforms these days? But it also is really nice to see some online friends there again!
No sponsor this week!
SHILL TIME: Would you mind subscribing to my YouTube channel (where I do newsletter recaps every week in addition to technical videos and commentary) and letting me know the kinds of videos you'd like to see there?
Whether you respond to this issue here or in the YouTube comments, I'd really appreciate it. It's been a fun experiment getting into making longer-form videos, and I want to make sure they're valuable!
Last week, I had you spiral! With numbers! Wee Amine, Brad, Micah, Ross, David, Ten, Thulasi, Alex, Ege, Tatiana, and the devs in the Ruby Users Forum!
This week's question:
Given a string of . and _ where _ represents a blink, return the longest gap between blinks.
Examples:
countBlinks("_..__...._.")
> 4
countBlinks("...._")
> 0
(you can submit your answers by replying to this email with a link to your solution, or share on Bluesky, Twitter, LinkedIn, or Mastodon)
Spyder TKL with KAP Santa Llum
Backtrack-free cursive
Urban congestion relief experiments through routing-app interventions
The Lost Joy of Music Piracy
I startled my neighbor the other day with my new power tool.
I told them, "Don't worry, this is just a drill!"
That's all for now, folks! Have a great week. Be safe, make good choices, and decorate something to brighten your day!
Special thanks to Ben, Kinetic Labs, and Marta for supporting my Patreon and this newsletter!
cassidoo
website | blog | github | bluesky | youtube | twitch | twitter | patreon | codepen | mastodon
2026-07-13 12:17:13
Hey friends!
I hope you had a good week! Mine was a satisfying one, we spent a lot of time at home just taking care of chores and being with each other, which was really nice. Let's learn!
Was this forwarded to you? You can subscribe here!
TypeScript 7.0
Fixing full-bleed CSS
Obfuscated, self-evaluating bash script by CDN Akamai being supplied to consumers via retail stores
Write code like a human will maintain it
Getting Started with Anchor Positioning
I got a fun little e-reader called the Xteink and played with it this week! It's been really cool to mess around with.
In general, I'm trying to read more and scroll less (aren't we all), and having a very easily accessible device like this is nice for that. Plus, the hardware is really quite good for something I got for 50 bucks. It's got WiFi, there's open source firmware that you can flash to it via the browser, it takes an SD card to hold custom splash screens and books, it's got a magnet on the back, and you can fully program it to do other things, too!
Rafal sent me this article too about other use cases (I saw someone using it as a writer deck too, so cool), and Remy sent this giant hub of even more resources!
This is very much not an ad, rather I'm just happy to find more open hardware in the world for people to make their own. We need more of that!
No sponsor this week!
SHILL TIME: Would you mind subscribing to my YouTube channel (where I do newsletter recaps every week in addition to technical videos and commentary) and letting me know the kinds of videos you'd like to see there?
Whether you respond to this issue here or in the YouTube comments, I'd really appreciate it. It's been a fun experiment getting into making longer-form videos, and I want to make sure they're valuable!
Last week, I had you get the impacted coordinates of a fireworks display! Boom boom Brad, Alex, Greg, Amine, Ege, Tatiana, Paul, Sergio, Ten, and the smarties in the Ruby Users Forum!
This week's question:
Write a function that takes a non-negative integer n and prints the numbers 0 through n in a clockwise spiral, starting at the top-left of a square grid. Hint: The grid size should be ceil(sqrt(n + 1)), and any unused cells should be blank.
Example:
> spiralGrid(99)
0 1 2 3 4 5 6 7 8 9
35 36 37 38 39 40 41 42 43 10
34 63 64 65 66 67 68 69 44 11
33 62 83 84 85 86 87 70 45 12
32 61 82 95 96 97 88 71 46 13
31 60 81 94 99 98 89 72 47 14
30 59 80 93 92 91 90 73 48 15
29 58 79 78 77 76 75 74 49 16
28 57 56 55 54 53 52 51 50 17
27 26 25 24 23 22 21 20 19 18
> spiralGrid(30)
0 1 2 3 4 5
19 20 21 22 23 6
18 24 7
17 30 25 8
16 29 28 27 26 9
15 14 13 12 11 10
(you can submit your answers by replying to this email with a link to your solution, or share on Bluesky, Twitter, LinkedIn, or Mastodon)
How The World’s Longest-Running Sardine Cannery Packs 60 Million Cans A Year (video)
ScottoBigum Handwired Macropad
NOMOS Glashütte: In House Or Nothing
Teaching Pop Music Analysis for Non-Majors
Leather is great for sneaking around... because it's made of hide!
That's all for now, folks! Have a great week. Be safe, make good choices, and learn someone else's perspective on something!
Special thanks to Ben, Kinetic Labs, and Marta for supporting my Patreon and this newsletter!
cassidoo
website | blog | github | bluesky | youtube | twitch | twitter | patreon | codepen | mastodon
2026-07-06 15:10:34
Happy July!
I hope you had a good week! I had a busy one and the long weekend here in the States was a VERY welcome step away. Let's kick off the week!
Was this forwarded to you? You can subscribe here!
Your documentation is still in your Mum’s filing cabinet
You Can Detect if Code Is Being Run Inside a Terminal
The Goldilocks customizable select height
New in Chrome 150
I updated my blog template this week to Astro 7! It was really fun and I blogged about the main thing I had to update to make everything work smoothly.
I've been noodling on the tech stack for my blog lately. I really like the setup, but I have noticed that my node_modules folder gets heavy because I'm using TinaCMS. I even made a video about a tool I found to clean up that folder because it was so beefy. I like that Tina is Git and markdown-based, but I might experiment with options to see if I can trim the built repo size down. We'll see!
Ever notice your agents just...forget everything the second a session ends?
Redis Agent Memory fixes that.
It gives your agents short-term memory plus context that actually sticks around across conversations, managed for you.
Last week, I had you get the mean number of bits to represent numbers! You did a bit too well Kriszti, Andrew, Alex, Amine, Ten, Paul, Ross, David, Brad, Thulasi, Nico, Shreya, and the fine folks in the Ruby Users Forum!
This week's question:
Given an n x m grid, an odd integer size, and a coordinate (row, col) representing where a firework explodes, return all grid coordinates impacted by the blast. A firework affects every cell within Math.floor(size / 2) rows and columns of the center, clipped to the grid boundaries.
Example:
> getImpactedCoordinates(5, 5, 3, 1, 1)
> [[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[2,0],[2,1],[2,2]]
> getImpactedCoordinates(3, 3, 1, 2, 1)
> [[2,1]]
> getImpactedCoordinates(5, 5, 3, 4, 4)
> [[3,3],[3,4],[4,3],[4,4]]
(you can submit your answers by replying to this email with a link to your solution, or share on Bluesky, Twitter, LinkedIn, or Mastodon)
Bring Back Crappy Forums
If you’re a button, you have one job
The Tech Tree of Milk Is Insane (video)
I built a Game Boy Themed Keyboard (video)
What do you call corn that joins the army?
Kernel!
(...this joke also works for operating systems)
That's all for now, folks! Have a great week. Be safe, make good choices, and go appreciate some plants!
Special thanks to Ben, Kinetic Labs, and Marta for supporting my Patreon and this newsletter!
cassidoo
website | blog | github | bluesky | youtube | twitch | twitter | patreon | codepen | mastodon
2026-06-29 15:32:54
Hey friends!
We made it to the end of June! Phew. I hope you had a good week. Mine felt good, I was able to get some creative juices flowing on projects and cleaned my office, which was very necessary. Let's learn!
Was this forwarded to you? You can subscribe here!
Text stickers
Astro 7.0
Modern CSS theming with light-dark(), contrast-color(), and style queries
Wiggly/Wavy Input Range Slider
This week was fun. I recorded some videos for both work and my own channel (including this one on startup equity and this one on the GitHub Copilot CLI's new TUI), and blogged some (on almost burning out and on a cool CSS radial gradient trick)! I also updated my open source blog template, which you should use to blog if you don't have one yet!
I feel like I've been so busy lately, and this week, though still packed, felt a bit more manageable, and that's been really nice.
Get your year started with personalized career coaching from Keenesse
Keenesse offers coaching to help you gain crystal-clear career goals, pinpoint exciting advancement opportunities, and master crucial skills like resume optimization, interview mastery, and confident negotiation – all to land your dream role in a competitive market.
Our expert team of seasoned tech industry coaches provides tailored support at every career stage, from ambitious students to accomplished executives.
Ready? Schedule your free, no-obligation consultation today at keenesse.com.
Last week, I had you configure auto-replies to your inbox! This was a toughie, great work Amine, Tenzy, Nico, and the cool cats in the Ruby Users Forum!
This week's question:
Given a positive integer n, calculate the mean number of bits required to represent all integers from 0 to n-1 (where the bit count of 0 is 1). Return the result rounded to two decimal places.
Example:
> meanBits(6)
> 2.00
// Explanation
// 0: 1 bit, 1: 1 bit, 2: 2 bits, 3: 2 bits, 4: 3 bits, 5: 3 bits
// Mean = (1 + 1 + 2 + 2 + 3 + 3) / 6 = 2.00
(you can submit your answers by replying to this email with a link to your solution, or share on Bluesky, Twitter, LinkedIn, or Mastodon)
Web Browsers on Video Game Consoles
TMO V2 with GMK Shashin
The Case for Physical Media Ownership
Incredible Aerial Photography Of Salt Farms
What lies at the bottom of the ocean and twitches?
A nervous wreck!
That's all for now, folks! Have a great week. Be safe, make good choices, and make some donations!
Special thanks to Ben, Kinetic Labs, and Marta for supporting my Patreon and this newsletter!
cassidoo
website | blog | github | bluesky | youtube | twitch | twitter | patreon | codepen | mastodon
2026-06-22 16:53:30
Howdy friends!
I hope you had a good week! I had a good long weekend spending time with friends for Juneteenth, and I'm ready to rock 'n' roll into the next one. Let's learn!
Was this forwarded to you? You can subscribe here!
Creating Memorable Web Experiences: A Modern CSS Toolkit
The golden rule of Customizable Select
I Stored a Website in a Favicon
The Scope of CSS @function
At work, we launched the GitHub Copilot app this week! It was a big effort across all the teams to get the word out and experiment with it. I wrote a (somewhat related) blog post all about git worktrees since the app (and many other agentic engineering tools) use them for parallel work.
Outside of work, I had a wonderful weekend with my old team from Netlify, which was a blast. We hadn't seen each other in person in years, and it was so nice catching up, hanging out, and chasing each other's kids. We're thinking about some things we can work on together moving forward, so... watch this space? Ha.
Turn your AI demo into a product people can actually use.
Runtype gives you everything you need to build production-grade AI apps and ship them where your users already are — web, Slack, email, MCP, and more. Focus on the user experience, not the infrastructure.
Last week, I had you get distinct positive integers summing into a number! You plus code equals good brain thoughts, Sergio, Amine, Ten, Shreya, Greg, and the devs in the Ruby Users Forum!
This week's question:
Given inclusive unavailable date ranges, an array of override dates, and a message date, return true if the message should receive an auto-reply and false otherwise. A message gets an auto-reply only when it falls inside at least one unavailable range and is not an override date.
Examples:
const unavailableRanges1 = [["2026-07-01", "2026-07-10"], ["2026-08-15", "2026-08-20"]];
const overrideDates1 = ["2026-07-04"];
const messageDate1 = "2026-07-05";
const unavailableRanges2 = [["2026-07-01", "2026-07-10"]];
const overrideDates2 = ["2026-07-04"];
const messageDate2 = "2026-07-04";
const unavailableRanges3 = [["2026-07-01", "2026-07-10"]];
const overrideDates3 = [];
const messageDate3 = "2026-07-11";
shouldAutoReply(unavailableRanges1, overrideDates1, messageDate1)
> true
shouldAutoReply(unavailableRanges2, overrideDates2, messageDate2)
> false
shouldAutoReply(unavailableRanges3, overrideDates3, messageDate3)
> false
(you can submit your answers by replying to this email with a link to your solution, or share on Bluesky, Twitter, LinkedIn, or Mastodon)
Nibelungenlied40 | Book Split Keyboard Design
In search of Timbuktu
When one Pixar employee accidentally deleted Toy Story 2
Beyond Plastics Tracked Starbucks’ ‘Widely Recyclable’ Plastic Cups. None Ended Up at a Recycling Facility.
A man tried to sell me a coffin today.
I told him that's the last thing I need!
That's all for now, folks! Have a great week. Be safe, make good choices, and organize your desk!
Special thanks to Ben, Kinetic Labs, and Marta for supporting my Patreon and this newsletter!
cassidoo
website | blog | github | bluesky | youtube | twitch | twitter | patreon | codepen | mastodon