stuff tagged with "programming"

Needy Programs


šŸ”— a linked post to tonsky.me » — originally shared here on

ls is a good program. ls is a tool. It does what I need it to do and stays quiet otherwise. I use it; it doesn’t use me. That’s a good, healthy relationship.

At the other end of the spectrum, we have services. Programs that constantly update. Programs that have news, that ā€œkeep you informedā€. Programs that need something from you all the time. Programs that update Terms of Service just to remind you of themselves.

Programs that have their own agenda and that are trying to make it yours, too. Programs that want you to think about them. Programs that think they are entitled to a part of your attention. ā€œPick meā€ programs.

And you know what? Fuck these programs. Give me back my computer.

I wanted to treat my son last night to some new Minecraft content.1 So I grabbed his switch to charge up whatever the in-app currency is. Mine coins?

Before I could do that, though, I had to create a Microsoft account for him.

Why?!

I’ll spare you the details, but it took a total of 16 emails just to authenticate and establish accounts for him, my daughter, and myself.

I had to abandon the idea of buying credits through the official Microsoft store because it blocked my credit card after the first purchase.2 I ended up buying digital Minecraft gift cards through Best Buy, but couldn’t redeem them in the switch app because they only worked on xbox.com?

What the hell guys, I just want my kid to be able to play SpongeBob on his switch! It was, literally not joking, a 2.5 hour cavalcade of the worst UX interactions I’ve encountered in years.

Remember when it used to take substantially less than two and a half hours to bike to Best Buy, buy a disk, and start jamming?

I agree with Niki here. I’m gonna start purging my 1Password accounts and deleting everything I can everywhere I can. I’m done signing up for stuff and being tracked and getting almost nothing in return while companies get to hold onto my info in perpetuity and use it basically however they see fit.

And thanks to vibe coding, I can build my own software that does exactly what I want without needing an account.3


  1. Anything to keep him off Roblox. Good lord, is there a needier program than that one? 

  2. lmao at my bank being like ā€œyou’re not a Microsoft boi, denied.ā€ Good bank. 

  3. as soon as I buy a dedicated machine to run LLMs locally, then I won’t need an OpenAI account either. 

Find Wikipedia Entries Near You That Are Missing An Image

originally shared here on

The very first app I ever built for iOS was an app where you could push a button and it would generate a random celebrity for you.

I used only images in Wikipedia, and at the time, the vast majority of quality images of celebrities were from people who went to a convention or premiere, snapped a bunch of photos of as many famous people as possible, and then uploaded them to the public domain.

These are unsung heroes, as far as I'm concerned.

I always admired these people and thought maybe one day I would contribute to Wikipedia in this way.

So I used ChatGPT 4o to whip up a script that allows a user to provide a set of geo-coordinates and it'll return a list of the closest Wikipedia entries which are missing photos.

Here's a link to the HTML that got spit out. Feel free to take the source code and modify it. Or feel free to look up your own geo-coordinates and give it a spin.

The next time you are out on a walk in your neighborhood and you come across a park that you recall is missing an image, you can pull out your phone, snap a photo of it, and take ten minutes to release it into the public domain so other dorks in the future can see what your neighborhood looks like.

And by the way: I know that if I didn't have a large language model, there's no chance I'd be sitting here at 11pm looking up API documentation to try and figure out how I would put this dumb idea to use. This is the power of LLMs, people. This blog post took roughly three times as long to write than the code that was written.

I did have to refine the output once, and there's clearly no great error handling, and some of the entries it returns do have a photo yadda yadda. I get it.

This isn't a tool that one uses to produce artisanal, well-crafted software that will stand the test of time.

This is a tool that, in roughly 5 minutes, empowered me with information that I can now use to make my community a tiny bit better.

That's what I love about technology.

Seven things I know after 25 years of development


šŸ”— a linked post to zverok.space » — originally shared here on

This post deeply resonates with me.

Never give up seeking truth, however uncomfortable it is. Search for knowledge. Adjust your worldview. Ask. Rewrite outdated code. Drop faulty hypotheses and unreliable foundations.

Software author is, first of all, a writer. They are a person who stands upright and says: ā€œthat’s what I know for now, and that’s my best attempt to explain it.ā€ Having this stance, preferring it to everything else, and hiding behind terms, concepts, and authority are invaluable qualities for long-term project success.

Or, basically, for any long-term human activity success.

Withered Technology


šŸ”— a linked post to lmnt.me » — originally shared here on

Though Nintendo employs more-modern technologies now, they are still criticized for not having the most-modern technologies that their rivals are all-too-happy to include, often at the cost of compatibility, affordability, and energy efficiency.

This is not a condemnation of using cutting-edge technology. But if given the choice, I prefer ā€œlateral thinking with withered technology.ā€ I think that’s a great philosophy to consider when making anything.

ā€œLateral thinking with withered technologyā€ is how I approach building websites. Use battle-tested, slow moving frameworks that don’t depend on a cornucopia of vulnerable third party plugins. :cough cough wordpress react cough sneeze:

HTML and CSS are going nowhere, and vanilla JS can do virtually anything you need these days. Render your stuff server side and keep the client side lightweight.

Write code with your Alphabet Radio on


šŸ”— a linked post to vickiboykis.com » — originally shared here on

Nothing is black and white. Code is not precious, nor the be-all end-all. The end goal is a functioning product. All code is eventually thrown away. LLMs help with some tasks, if you already know what you want to do and give you shortcuts. But they can’t help with this part. They can’t turn on the radio. We have to build our own context window and make our own playlist.

When LLMs can stream advice as clearly and well as my Alphabet Radio, then, I’ll worry. Until then, I build with my radio on.

A significant contributor to my depression last year was a conviction that LLMs could do what I could do but better.

I’m glad I’ve experimented with them heavily over the past couple years, because exposure to these tools is the only real way to understand their capabilities.

I use LLMs heavily in my job, but they are not (yet) able to replace my human teammates.

Reckoning


šŸ”— a linked post to infrequently.org » — originally shared here on

Canadian engineers graduating college are all given an iron ring. It's a symbol of professional responsibility to society. It also recognises that every discipline must earn its social license to operate. Lastly, it serves as a reminder of the consequences of shoddy work and corner-cutting.

I want to be a part of a frontend culture that accepts and promotes our responsibilities to others, rather than wallowing in self-centred "DX" puffery. In the hierarchy of priorities, users must come first.

What we do in the world matters, particularly our vocations, not because of how it affects us, but because our actions improve or degrade life for others. It's hard to imagine that culture while the JavaScript-industrial-complex has seized the commanding heights, but we should try.

And then we should act, one project at a time, to make that culture a reality.

Algorithms we develop software by


šŸ”— a linked post to grantslatton.com » — originally shared here on

I started a new job as a software engineer last month.

It’s the first job I’ve ever had where all I need to do is write code. I don’t need to worry about finding customers, protecting the company from lawsuits, ensuring the product is the correct product to build, or making payroll.

All I need to do is write code.

This is the first time in my career where I can actually focus on the art of writing good code.

I came across this article from Simon Willison’s blog, and boy, there are a lot of great pieces of advice for folks in my position here.

As a junior engineer, there's simply no substitute for getting the first 100K lines of code under your belt. The "start over each day" method will help get you to those 100K lines faster.

You might think covering the same ground multiple times isn't as valuable as getting 100K diverse lines of code. I disagree. Solving the same problem repeatedly is actually really beneficial for retaining knowledge of patterns you figure out.

You only need 5K perfect lines to see all the major patterns once. The other 95K lines are repetition to rewire your neurons.

Writing Javascript without a build system


šŸ”— a linked post to jvns.ca » — originally shared here on

I make a lot of small simple websites, I have approximately 0 maintenance energy for any of them, and I change them very infrequently.

My goal is that if I have a site that I made 3 or 5 years ago, I’d like to be able to, in 20 minutes:

  • get the source from github on a new computer
  • make some changes
  • put it on the internet

But my experience with build systems (not just Javascript build systems!), is that if you have a 5-year-old site, often it’s a huge pain to get the site built again.

I have websites that I made in middle school that I’m able to get up and running in roughly as much time as it takes to find the old folders.

I also have websites that I am unable to run on my new laptop because the dependencies are too out of date and now supported on my new architecture.

What Is React.js?


šŸ”— a linked post to briefs.video » — originally shared here on

In summary:

  • Facebook is a [redacted] company with a terrible web interface.
  • React is a technology created at Facebook to administer its interface.
  • React enables you to build web applications and their interfaces the way Facebook does.
  • I am not calling Facebook "Meta"
  • JavaScript-first interfaces built on ecosystems like React’s are cumbersome and under-performing.
  • React prevails because its evangelical proponents and apologists have convinced developers that Facebook’s success can be attributed to technological quality and not aggressive capitalism.

Over the past fifteen years, I feel like I’ve had a pretty good track record of knowing which technologies to pay attention to and which technologies to confidently let pass by me.

When React first dropped, I thought the setup process seemed so onerous and filled with so many dependencies that I slowly backed away and haven't really needed to look back.

It would be irresponsible of me to have zero experience in React, so of course I've inherited projects that others have started on top of it. But every time I jump into a React project, I feel like I’m Homer jumping into his unchlorinated pool.1


  1. I mean, this is how I feel every time I jump into a Facebook-owned property these days. 

Five Behaviours to Become an Effective Staff-Plus Engineer


šŸ”— a linked post to infoq.com » — originally shared here on

This talk helped me articulate a few key arguments that I can use to counter myself when in the throes of impostor syndrome-related attacks from my inner monologue.

Basically, a ā€œstaff-plus engineerā€ is anyone in a technical role that is higher than a senior engineer. These are sometimes referred to as principal engineers, staff engineers, etc.

The big difference between staff-plus and individual contributor path is that an IC role is one you go down when you truly want to contribute as an individual, often acquiring such an expertise in a specific domain that you just do your thing alone.

A staff-plus role requires collaboration, often leading teams, but always being the lynchpin which helps be the voice of technical leadership across multiple teams.

The responsibilities of a staff-plus role include (probably) writing and (definitely) reviewing code, providing technical direction, mentoring and sponsoring other engineers, providing engineering context to non-technical people, and being involved in strategic projects which aren’t shiny but are critical to the success of an organization.

I think I came across this talk at a timely point in my career. I have been tasked with doing staff-plus engineering work ever since starting my first company, and it’s honestly the stuff I love the most.

I’m not a developer who loves to write code. I love writing code because it results in a tool that makes someone’s life easier. What brings me joy is in doing the discovery work needed to clearly articulate the problem and charting a course that’ll lead us to a solution.

Everybody's Free (To Write Websites)


šŸ”— a linked post to sarajoy.dev » — originally shared here on

Enbies and gentlefolk of the class of ā€˜24:

Write websites.

If I could offer you only one tip for the future, coding would be it. The long term benefits of coding websites remains unproved by scientists, however the rest of my advice has a basis in the joy of the indie web community’s experiences.

I love the reference to Wear Sunscreen, one of the great commencement speeches.

There is amazing advice and inspiration for building websites in here. It also reminded me of POSSE, meaning ā€œPublish (on your) Own Site, Syndicate Elsewhere.ā€

Comfortable with the struggle


šŸ”— a linked post to rachsmith.com » — originally shared here on

I’ve known developers who’ve put up with the struggle with the expectation that one day it will go away: one day they’ll be an expert and never have to struggle again. This day never arrives, and so they bail out of the field.

Unfortunately, I don’t think the struggle ever goes away. I’ve been doing this professionally for 14 years now and I still have to deal with the struggle almost every work day.

If you can be comfortable with the struggle and build up your tolerance for it. If you’re able to sit in that moment and be okay without drama or a total crisis of confidence, I’m fairly sure you’re going to do just great.

The Struggle comes in multiple shapes and sizes too. Here is a short list of my experiences with The Struggle from this week alone:

  • Impostor syndrome
  • Anxiety about breaking a physical connector
  • Frustration with unclear objectives
  • Being overwhelmed by unfamiliar technologies
  • Debugging something and being unable to find an answer

After 12 years of professionally dealing with The Struggle, I’m still able to handle many aspects of it, but my tolerance is quickly diminishing.

Dealing with The Struggle is much easier when you feel like there’s a reward for you at the end of it. Right now, I’m trying to restore my old iPod fifth gen with an SD card, and no matter what I do, I cannot get it to work right.

I’ve been all over forums, digging into the sixth and seventh pages of search results, desperately looking for clues as to why I’m not getting it to restore.

But I can picture myself playing that brick breaking game soon, and that first game is gonna be so much fun after all of this work.

Choose Boring Technology


šŸ”— a linked post to mcfunley.com » — originally shared here on

I saw this article referenced while reading Bill Mill’s recap of relaunching a website, which in and of itself is a delightful read for those of us who nerd out on large-scale system architectures.

I am almost certain I’ve read Dan’s piece on boring code before, but I wanted to share it here because it serves as a great reference for those of us who are sick of making bad tech stack decisions for bad reasons.

In particular, the ending here sums up my experience consulting with many different tech teams:

Polyglot programming is sold with the promise that letting developers choose their own tools with complete freedom will make them more effective at solving problems. This is a naive definition of the problems at best, and motivated reasoning at worst. The weight of day-to-day operational toil this creates crushes you to death.

Mindful choice of technology gives engineering minds real freedom: the freedom to contemplate bigger questions. Technology for its own sake is snake oil.

The teams which move the fastest are the ones who are aligned on a vision for what is being built.

Often, these teams hold a ā€œstrong opinions, loosely heldā€ mentality where they decide what tools they’ll use, and they’ll use them until they no longer solve the problem at hand.

Put another way: in a business context, experimenting with your tooling is a huge organizational expense that rarely yields a worthwhile return on investment.

Your focus should be on what you are building rather than how you’re building it.

Security at Startup


šŸ”— a linked post to vadimkravcenko.com » — originally shared here on

In my opinion, security is one of the most forgotten aspects of software engineering. It rarely gets focused on until it’s too late. Even though at least one incident lands on HackerNews every week where some data gets leaked or someone gets hacked — people still think, ā€œNobody cares about my little startup.ā€ You might think you're too small to be noticed by the big, evil hackers. Wrong. Size doesn't matter. You're always a target; there’s always data to leak and ways to exploit your business.

This is a great primer for the security-related items you need to consider when you’re building software.

Some takeaways:

First, any human-built product is going to be insecure. Nothing is 100% secure, ever. The best you can do is make the bad guys earn it by making it difficult to break into.

Second, your biggest vulnerabilities are almost always human. You can build Fort Knox, but if I’m able to trick your guard into opening the door for me, then what’s the point?

Third, I’m grateful for frameworks like Ruby on Rails which handle a good chunk of the author’s ā€œstep 0ā€ items out of the box. Picking the right tool (and keeping that tool sharpened) is the best first step.

Fourth, there’s never a moment with software when you can dust your hands and say, ā€œope, we’re done!ā€

Security is especially an area in which you can’t sit still. If you build an app and let it sit for a decade without any updates, I can almost guarantee you that there’ll be a vulnerability in one of your dependencies which I could exploit to take over your system.

Finally, if you reach a certain size of organization, you need someone thinking about this stuff full time and orchestrating all the pieces needed to keep a secure system.

Home-Cooked Software and Barefoot Developers


šŸ”— a linked post to maggieappleton.com » — originally shared here on

I have this dream for barefoot developers that is like the barefoot doctor.

These people are deeply embedded in their communities, so they understand the needs and problems of the people around them.

So they are perfectly placed to solve local problems.

If given access to the right training and tools, they could provide the equivalent of basic healthcare, but instead, it’s basic software care.

And they could become an unofficial, distributed, emergent public service.

They could build software solutions that no industrial software company would build—because there’s not enough market value in doing it, and they don’t understand the problem space well enough.

And these people are the ones for whom our new language model capabilities get very interesting.

Do yourself a favor and read this entire talk. Maggie articulated the general feeling I have felt around the promise of LLMs within the confines of a concise, inspiring talk.

A friend approached me a few months back and asked me to help him build an app to facilitate a game he likes to play with his friends in real life.

I told him that a good first step would be to experiment first with facilitating the game using good ol’ fashioned paper, and use the lessons learned from that experience to eventually build an app.

A few weeks later, he came to me with a fully baked version of the app in a prototyping tool called AppSheet.

I was stunned at how much he was able to get done without any professional development support.

He’s a prime example of a barefoot developer. I don’t think he has any interest in crossing the ā€œcommand line wall,ā€ but as these tools get more capable, it’ll enable him and scores of others to build software that’ll solve their problems for them.

Helping more ā€œnormal peopleā€ to become barefoot developers is a cause I’d love to be part of.

ChatGPT is really bad at generating code to interact with GPT-4

originally shared here on

Lately, I've been working on several projects which interface with the OpenAI APIs.

Since this is 2024 and I'm far too lazy to open the official API documentation and write code myself, my first step in generating code is to ask the 4o model of ChatGPT something like this:

Write a Python script which uses the latest OpenAI APIs. I'd like the function to accept a custom prompt and a custom top-k value. It should return the prompt's response.

It returns something like this:

import openai

def generate_text(prompt, top_k=5):
    # Define your OpenAI API key here
    openai.api_key = 'your-api-key'

    # Define parameters for the completion
    completion = openai.Completion.create(
        engine="text-davinci-003",
        prompt=prompt,
        max_tokens=100,
        top_k=top_k,
        n=1,
        stop=None
    )

    # Return the generated text
    return completion.choices[0].text.strip()

# Example usage
prompt = "Once upon a time"
top_k = 10
generated_text = generate_text(prompt, top_k)
print("Generated Text:", generated_text)

Which looks super great, right?

Except when you go to run it in a terminal, you get this:

openai.lib._old_api.APIRemovedInV1: 

You tried to access openai.Completion, but this is no longer supported in openai>=1.0.0 - see the README at https://github.com/openai/openai-python for the API.

You can run `openai migrate` to automatically upgrade your codebase to use the 1.0.0 interface. 

Alternatively, you can pin your installation to the old version, e.g. `pip install openai==0.28`

A detailed migration guide is available here: https://github.com/openai/openai-python/discussions/742

If you paste that error into the chat, it'll respond with this:

It seems like there has been a major update in the OpenAI Python library since I last checked. Let me update the script to use the latest version of the library:

And then it spits this out:

import openai

def generate_text(prompt, top_k=5):
    # Define your OpenAI API key here
    openai.api_key = 'your-api-key'

    # Define parameters for the completion
    response = openai.Completion.create(
        engine="davinci-codex",
        prompt=prompt,
        max_tokens=100,
        top_k=top_k,
        n=1
    )

    # Return the generated text
    return response.choices[0].text.strip()

# Example usage
prompt = "Once upon a time"
top_k = 10
generated_text = generate_text(prompt, top_k)
print("Generated Text:", generated_text)

Notice how it still uses the openai.Completion method!

I've tried prompting it with something like:

You're still using the openai.Completion method. Reference the official up to date API documentation to get the latest call that replaces the openai.Completion method.

And it responds with:

Apologies for that oversight. Let me update the script to use the latest API method based on the official documentation:

And here's the code it generates:

import openai

def generate_text(prompt, top_k=5):
    # Define your OpenAI API key here
    openai.api_key = 'your-api-key'

    # Define parameters for the completion
    response = openai.Completion.create(
        engine="davinci-codex",
        prompt=prompt,
        max_tokens=100,
        top_k=top_k,
        n=1,
        temperature=0.7,
        stop=None
    )

    # Return the generated text
    return response.choices[0].text.strip()

# Example usage
prompt = "Once upon a time"
top_k = 10
generated_text = generate_text(prompt, top_k)
print("Generated Text:", generated_text)

Which, again, still uses the openai.Completion method!

I've noticed this sort of "oops, I screwed up, here's the exact same thing I just outputted" behavior appear more frequently when I use the new GPT-4o model.

If I use GPT-4 and I'm using my ChatGPT Plus subscription, I will still run into the issue where its first response references the deprecated method, but if I inform it of its mistake and provide a link to the official documentation, it'll access the web and try to offer something different. (It still generates unusable code lol but it's at least trying to do something different!)

When it comes to Python and Rails code, I'm seeing that the GPT-4o model is not as good at code generation as the previous GPT-4 model.

It feels like the model is always in a rush to generate something rather than taking its time and getting it correct.

It also seems to be biased toward relying on its training for supplying an answer rather than taking a peek at the internet for a better answer, even when you specifically tell it not to do that.

In many cases, this speed/accuracy tradeoff makes sense. But when it comes to code generation (and specifically when it tries to generate code to use their own APIs), I wish it took its time to reason why the code it wrote doesn't work.

Rapid skill acquisition and adapting to new career opportunities


šŸ”— a linked post to justin.searls.co » — originally shared here on

Joel’s original post is an excellent read, but I really enjoyed Justin’s statement at the end of his linked post:

One last note: showing up to a client following a weekend-long crash course in a particular technology doesn't make you a fraud. Nearly twenty years in consulting has taught me that the people most worried about misrepresenting themselves and their abilities are the people who have the least reason to worry. The fact they care so much almost always means they'll put in the work when they need to. The real frauds, meanwhile, don't worry at all. And while Joel was holed up in a Starbucks for 72 hours, I'm sure they were having a delightful and relaxing weekend. And Joel's much richer for it, as he's gotten four careers' worth of experience by repeatedly diving into new industries, organizations, and technologies, whereas the real imposters only learned how to talk a good game as they skated through life without ever stretching themselves.

I’ve seen first hand the nerve some developers bring to a first meeting, only to dim gradually over time.

I continue to struggle sometimes with confidence in what I do, but my entire career so far has been non-stop learning.

Every project is an opportunity to learn a new framework, a new project management style, a new business problem.

It’s a hard characteristic to put on a resume, but the ability to pick up new systems quickly is definitely one of my core strengths.

Why Can't Programmers Agree on Anything?


šŸ”— a linked post to jesseduffield.com » — originally shared here on

Programmers disagree on various topics, for various reasons. Personally, I wouldn’t have it any other way. I wouldn’t want to live in a world where all of these software topics are settled and boring. Debates about programming are interesting and intellectually stimulating, and unlike debates about, say, politics, you’re unlikely to lose any friends when you express your functional-programming hesitancy.

Maybe, at the end of the day, that’s the real reason there’s so much disagreement among devs: because it’s so fun.

I should print this out and give it to my wife. This is exactly why I enjoy arguing about dumb stuff.

It’s rarely about winning. Being correct is fun. Arguing over semantics and picking nits over asinine details lets you sharpen your beliefs by pitting them against someone else’s.

It also signals that you truly care about the thing. It’s probably the most common way I show I love something.1


  1. I recognize this makes me insufferable to consume most forms of media with. When I notice the little details in a show where they took shortcuts and were lazy, I can’t help but call them out. Sorry, Shanny. 

A pair of worn-out shoes at the edge of a path leading into a misty forest.

The Job Hunt Chronicles: Month 2: Beyond the Fog

originally shared here on

(This is the second in a series of posts going through my journal entries from the last month and talking about what it's like to go through a period of unemployment, self doubt, and finding your spark. You can read the first one here.)

Alright, we've made it through February!

I'm still on the job hunt. I'm still dealing with some crippling anxiety and depression.

But I'm making progress! I'm having interviews, I'm figuring out how to feel my feelings and articulate my values, and I'm finding opportunities to enjoy the moment and be optimistic about finding my next job.

I journaled every single day last month. I fed all 28,000+ words into ChatGPT and asked it to summarize the entries into two sentences using the style of the journal entries themselves. Here's what it said:

Another month down, filled with musings, mild misadventures, and moments of clarity amidst the mundane. Balancing personal passions, family love, and the hunt for professional fulfillment, the journey meanders through the highs and lows, always circling back to the comforting, complex tapestry of daily life.

Man, do I actually sound that pretentious in my own journal? ?

Anyway, if you're wondering what was on my mind in January, strap yourself in and let's go!

"What are you looking for?"

Gonna put this up front again like I did last month.

I'm looking for a position where I can blend strategic tech leadership with hands-on coding, preferably in a small, mission-driven company focused on healthcare or climate solutions. The ideal environment is a funded startup with fewer than 50 employees, leveraging generative AI, and based in or flexible with the Twin Cities area.

Ideal extras include a flexible 32-hour work week, a hybrid work arrangement, and opportunities for travel and professional development

In short: If you know a mission-oriented startup seeking a tech-savvy strategist passionate about making a significant impact, send them my way!

Activities I've done

I put this section in my last post because it felt like a badge of honor to brag about how many meetings I had in a month. To me, it felt like I was doing something.

All of that pride went down the drain after talking with a new friend who basically said that I'm continuing to burn myself out by grinding through hundreds of meetings instead of doing the actual hard work of sitting down and figuring out what my values are.

Once you know what your values are, you are so much more likely to know what path to walk down.

So in that spirit, I won't mention how many meetings I've had. Instead, I basically spent this month continuing to figure out who I am and what I want.

I'm aware that's not a very satisfying or flashy statement to make in a blog post that purports to explain life in the eyes of someone who got laid off.

But truly, most of what I've done in the last month is learn about my feelings and how to deal with them productively.

I've gone to some of the darkest places I've ever gone in my life this past month. The shame, the fear, the depression, the embarrassment, the anger... all of those feelings are easy to deal with when you ignore them like I had been for my entire adult life.

But your body can only handle ignoring them for so long. Eventually, you find yourself leaving work early and rushing to the hospital because your heartbeat is noticeably irregular, and your heart feels like an orange being crushed in the hands of a strongman, adrenaline secreting between their fingers.

One thousand and six hundred dollars later, you're told that there's nothing physically wrong with you. Go see a therapist.

Your body remembers each and every time you ignore those feelings, those warning signs. Those "gut checks" that you decide to push aside because it doesn't align with what you think you should be doing.

Eventually, it all boils over.

So that's what I've been up to this month: looking back at the past twenty years of my life and beating myself up for years of beating myself up.

It hasn't all been atonement, though. I've also started to hope again. I've had moments where I'm excited again for what's next.

Even if that's something as simple as waiting for a hug from my kids when they get home from school, or watching an episode of Drag Race with my wife every Friday.

Those little things are the things that keep me going, and they're giving me the energy to start looking forward to how I can get back out in the world and be helpful.

Things I've learned

Here are all the random things I've been contemplating over the past month:

?ā€? Personal growth insights

My 7 year old daughter told us she thinks she's getting too old for Barbie.

This was crushing for me and my wife to hear, but for different reasons.

For my wife, it was the prototypical "my kid is growing up" response that all parents feel when they see their kid age. I don't wanna minimize that feeling, because I certainly feel it myself: it's bittersweet to see your kids grow up.

But for me, it was a good reminder that the grass is always greener on the other side.

I can't remember the last time I dreamed about what I wanted. I feel like I've been coasting for at least the last several years.

Besides hanging with my family/friends and the occasional fun project at work, there hasn't been much driving me forward to grow.

And that's probably where a good chunk of my depression is coming from.

I could either sit and analyze the "why" (and trust me when I say that I have), but the more important thing is to be grateful for coming to this realization and making strides towards dreaming again.

My problem is that I, uh, kind of forgot how to do that.

Part of it stems from my engineering brain continually looking for edge cases that cause me to reject a dream wholesale.

Another big part of it might be this fear of losing what I've already got. I worked hard to build a reputation, I've got a great family that needs to be provided for, I've got a house that needs maintenance and improvements, the list goes on and on.

But whatever the reason, I find that dreaming is a muscle that can atrophy. I have a similar theory about being extroverted: after the pandemic, I found being around people to be exhausting in a way that I never felt before. My extroversion tendencies returned as I continually subjected myself to new groups of people.

Dreaming feels the same way: continually practicing and refining the act of dreaming is the only way to get good at it.

That's what makes me jealous of my daughter and son.

I watch them play with Barbies together, and their ability to play baffles me.

How can you just start playing?

How can you come up with new scenarios and then go for it?

I ended up talking to my daughter about this. It felt great to share with her how I'm jealous of her ability to be young and idealistic and have a vision for how her life can be, and I'm jealous of how she's able to express that vision through her play.

She ended up deciding to keep her Barbies, and I'm extremely grateful for that. It means there's still more time for me to learn first hand from the master of dreaming.

She'lo yada, yada.

I was speaking with someone about struggling to make a decision that needed to be made, and he told me about this expression that he heard his family say a lot growing up.

It's a Hebrew expression that means "He who doesn't know, knows."

This pairs nicely with the Derek Sivers axiom of "Hell Yes, or No," where something is either impossible to say no to, or you simply say no to it.

Both of these, of course, are "easier said than done" aphorisms to adopt, but it's good to document them nonetheless.

It's awesome to end things.

I spoke with a friend who ran a very popular blog about his adventures traveling to various breweries, and we were both talking about how we were considering winding down our various beer-related projects.

Throughout my entrepreneurial journey, I keep coming across articles expressing the importance to consider the ending to whatever you start.

At one networking event, I heard a speaker ask "what is the percentage likelihood that you will exit your business?"

The answer: 100%.

Because at some point, you will die.

That is the ultimate finality, of course, but the longer I'm around here on earth, the more I have to start embracing the good side of things ending.

I built mncraft.beer a decade ago because my wife and I were extremely passionate about supporting craft breweries, and we had a goal to get to every single brewery in the state.

Fast forward ten years, our ambitions have changed. It's difficult to convince two young kids to sit in a car for several hours on a weekend, let alone motivate myself to spend all that time traveling to visit a brewery that, in all likelihood, only produces mediocre beer.

I've gotten all that I can get out of that project. My biggest takeaway is that a brewery often is a boon for a small town. Even if the beer isn't going to win any awards, we all collectively need more third spaces, and breweries act as a fantastic gathering place for a community.

According to my Untappd account, I've had 7,445 beers since joining the app in August of 2012. Of that, 4,346 of them were unique. I've had 200 different styles of beers, and I've learned that I like Pilsners, Belgians (anywhere from Dubbels to Quads), Extra Special Bitters, Kƶlsch beers, and straight up, old school IPAs.

I know what good beer tastes like, and I know what breweries make good beers in our state.

So what's the benefit to continuing that app?

I shared a video from Hank Green last year about letting go of the dreams of your past in order to free yourself up for new ones, and that's the mindset I gotta adopt here.

It's always sad to end things. I remember every closing circle after a show would end in theatre was a mess of emotions and tears. I remember losing our final football game in high school, looking around the field, seeing tears and frustrations mount on the faces of my teammates. You never wanna say goodbye to something that gave you so much joy.

It kind of reminds me of this exchange from Hook (one of my favorite movies of all time):1

Hook: Are you ready to die, boy?

Peter: To die would be a great adventure.

Killing off parts of our former self on which we linger is a privilege which allows us to fully move on to the next adventure.

Al Snow on Success

I felt under the weather this month for a couple days, and on one of those days, I decided to watch the Wrestlers documentary on Netflix.

Two things I want to mention about that:

First, the whole thing felt like a work-shoot to me. I love the way professional wrestling blurs the line between what's real and what's made up.

It felt like the documentarians were very intentional about painting Al as the babyface (the good guy) and Matt Jones as the heel (the bad guy).

I hope OVW gets a good boost in viewership as a result of the documentary. They did a great job of showing how the sauce gets made, and I'm sure they know it's the exact sort of thing that hooks in smart marks like me.

Second, since I assume all of those wrestling terms are not meaningful to most of you, here's a great quote that comes at the end of the documentary:

If you equate success in a destination (that destination being WWE), you’re probably not gonna get it. But if you equate success in doing something you’re passionate about and that you love, and that gives you purpose and drive, then you’re successful.

I keep asking myself what success means to me, and while I don't have a solid answer yet, maybe it's because I'm still working on giving myself permission to dream without restrictions.

I'll get there soon, though. I can feel it.

Tracy Chapman's "Fast Car".

After Tracy performed with Luke Combs at the Grammy's this year, I saw a post that talked about her performance of Fast Car in front of an extremely frustrated crowd at Wembley Stadium in 1988.

You can find recaps of the story online, but the long and short of it is that Stevie Wonder was refusing to go on stage at this birthday celebration for Nelson Mandela, so Tracy came back out on stage and performed Fast Car.

When you watch the video, you hear the crowd go from rowdy to genuinely moved.

It's hauntingly beautiful. That song has always been a staple in my rotation, and after hearing it performed in this way, it makes it even more special.

We should use all of our senses to find our way.

I feel like the best metaphor I can give for how depression feels to me is a fog that completely obstructs my vision.

No matter which direction I look, all I see is a dense fog of nothingness.

But what I keep reminding myself is that even when you can't see, you still have at least four other senses you can use.

I'm not sure how to use those other senses yet, but I'm starting to use my ears to listen for opportunities, my nose to sniff out which direction to walk in, and my gut to validate which direction feels right.

The Dan Patch Club serves as a template for who I wanna be when I get old.

My dad invited me to speak to The Dan Patch Club, which is a subgroup of residents and friends of the Masonic Home in Bloomington dedicated to learning and exploring various topics together.

I'm ashamed to admit that I'm not immune from playing the generational blame game. But placing each other into broad, faceless groups like "boomers" or "millennials" only makes it harder for us to pool our collective wisdom and work together to solve real problems that our society faces.

Short of vague jokes about mysticism and ritualistic masonic secrets, I honestly had no idea what to expect when my dad asked me to come speak to these Masons.

I figured the hour would be spent giving a broad introduction to generative AI tools like ChatGPT and Midjourney, but what surprised me was how many hands were raised when I asked "how many of you have used ChatGPT?"

I should've known better because I did know that this room contained two PhDs and a retired attorney. All of these guys had extremely poignant and informed questions about the use of AI in our society.

We talked about the legal implications of deep fakes, the ability to spread election propaganda at unfathomable speed, how these models "reason" and come up with "truth", and the most important question which continues to plague us information workers: "how do you turn off predictive autocomplete in Microsoft Word?"

As we were wrapping up, I actually didn’t want it to end in the same way I haven’t wanted many of my conversations to end lately.

Sparking that curiosity in people is one of the key values I've been aspiring towards as I craft my vision for the next ten years.

I hope when I’m their age, I’m still kickin’ it with my homies, whomever they may be, nerding it up about complex topics, continuing to challenge myself and grow as much as possible.

Is anxiety only reducible when you are focused on your basal instincts and needs?

It seems like the only known treatments and mitigations for anxiety center around mindfulness and getting your brain to live in the present.

Is that really it? Living in the now is the only way to make anxiety go away?

It seems like there should be more we can do to harness our ability to look into the future while keeping the major doom scenarios from spiraling in our heads.

Meditation?

Anyone have any good suggestions for developing a consistant medication practice?

I have tried apps in the past but haven't found them to be sticky or altogether helpful.

Daniel Tiger isn't only for kids.

Toward the end of February, I had a major backslide with my mental health, and it kind of came to a head one day while I was dropping my son off at daycare.

I usually let him pick out what we listen to, and he chose the Daniel Tiger's Big Feelings album.

One of the first songs on that album is called "Close Your Eyes and Think of Something Happy."

I ended up at a red light and, as I found myself descending into some negative thoughts, I decided to do exactly that.

And you know what I saw?

Absolutely nothing.

It crushed me.

I'm a grown ass man, and I couldn't even come up with a single thing in that moment to think of in order to make me happy.

Suddenly, from the back seat, I hear my boy giggling and singing along.

Man.

That moment highlighted to me how badly I needed help through this stuff. That there is a ton to be happy about.

I'm glad my son was able to help me get out of my head.

And I'm glad I'm no longer dismissing those songs as "simple kid songs." We can all use a reminder for how to process sad and angry feelings in a healthy manner.

It's easier to venture out when you know you can return home.

I heard Dr. Becky mention it in that Farnam Street podcast, but she was talking about the relationship between teenagers and parents.

I've been considering the sentiment in regards to music.

For the past five years, I've been very curious about genres of music from which I've typically shied away.

I decided to listen through my entire local library of music, which is currently sitting at 83 days of non-stop new tunes.

That library is filled with music of every type of genre imaginable. Country. Experimental free jazz. 70s East African jams. Norwegian death metal. A mashup of Metallica and The Beatles. All kinds of EDM mixes.

It took more than 4 years to get through all of it, but I finished it with an appreciation of the core albums that have been there for me my whole life.

The other day, I decided to shuffle my "key albums", which is any album I've given a star rating of 4.5 or higher.

I was instantly transported back to several happy moments in my life. Building Ralph Wiggum images in front of my computer in my childhood bedroom. Walking home to my (eventually) condemned house in college. Going for a run around the pond in Bloomington. Riding the light rail home.

Solitary moments where I didn't need to worry about what other people would think of what I was listening to.

A place where I can be myself.

That concept applies to much of our soul searching. We are only able to be truly adventurous when we know there's a safe place for us to come home to when we're weary from exploration.

I find myself drawn to people who are able to speak passionately about their cause much in the same way my kids talk about Santa Claus or the Easter Bunny.

There's something magical about believing in something.

There's something special about having solid, firm convictions on which you stand.

It's this palpable energy you can feel emanating from someone sharing their passions.

I felt it at a couple of job interviews I had last month.

I felt it while speaking with friends about AI.

I felt it playing crazy rummy with my wife and talking about what we want to do for our ten year anniversary.

Maybe that's the feeling I should be chasing. Is that feeling "joy"?

I'm not sure where I started getting so disillusioned about that feeling in a professional context.

But I'm eager to find a job where I can surround myself with that energy once again.

Kids simply do not care about success like grown ups do.

When my daughter was 4, I'd watch her play a game where she'd have to pick the right word and she would purposefully pick the wrong one.

Like, I knew she knew the right word, but she intentionally picked the wrong one.

It sent me up a wall.

But one day, I asked her why she was picking the wrong one on purpose.

She said, "I like the noise it makes when I get it wrong."

My kids are way better at learning and dealing with uncertainty than I am.

And success is whatever you define it to be.

I can't thank you all enough.

A lot of my journaling over the past month is just, like, truly dismal.

But there are moments of light, and they're all thanks to you all.

I am forever indebted to the literal hundreds of people who have reached out to ask me how I'm doing. I'm so fortunate that I've got so many people who care about me.

I feel like I'm not able to be my own best friend right now. I find myself continually returning to a place where I can't stop beating myself up.

You know how people used to take their old cars that they don't want anymore and drive them deep into the woods and leave them there? That's how I feel right now. I feel like a beat up old car that's completely rusted through, nature slowly consuming and reclaiming it.

But it's conversations with many of you that are helping me see that's not an accurate picture of reality.

So thanks for checking in on me. It's definitely helping me get through the fog.

?ā€? Professional growth insights

If someone calls themselves an "expert", it's because they're trying to sell you something.

This insight came from a talk by the incredible Jim Wilt that technically came from January, but I didn't include it in last month's post and want to make sure I include it now.

My inbox is a prime source of stress.

It's a roulette wheel where sometimes you win big (a job offer, a congratulatory email, a rave review), but you also sometimes lose big (a threat of a lawsuit, a late bill notice).

I'm still learning how to separate work from my personal life, but a good place to start is to go to your settings on your phone and turn the inbox off for your work email.

You don't need to remove it altogether.

But when I was at Bionic Giant, I turned it off, and it helped my stress levels immensely at night.

It allowed me to turn it on if I needed access to a message on my phone during the day, but then I could easily turn it off at night so I didn't get distracted when I went to my inbox to read a newsletter.

It's awfully hard to say "no."

I wrote a lot in my journal this month about how a lot of my anxiety stems from saying "yes" to everyone and everything.

One reason I can't say "no" is because I'm not sure what I actually want. Saying "yes" at least gives me the chance to figure out if it's something I want.

But when I say "yes" to too many things, I never get a chance to sit back and reflect on whether it was something I wanted.

Which basically describes the first decade+ of my professional career. I say "yes" to the point where I have no room in my schedule to reflect.

I need a better analogy for how generative AI arrives at its solutions when compared to a search engine.

If anyone has any ideas, let me know.

I don't get why I feel so guilty for feeling sick.

I find it next to impossible to rest as it is.

But when I'm sick, it's like my anxiety works in overdrive to try and let me know that I'm falling behind on stuff.

I said this earlier, but I felt a little under the weather one day this past month, and I ended up calling folks and cancelling my meetings with them. The guilt I felt was incredible.

I appreciate having anxiety to keep me thinking through possible problems and pushing myself to move forward to fix them, but the combination of the "fight or flight" and "freeze" responses makes it tough to get anything done.

Learning new things becomes a lot harder as you age.

I was turned down from a job I was rather hopeful to get because I don't have the experience in the Javascript framework that they were looking for.

So I decided I was gonna sit down this past week and learn it.

I tell you, I watched three different tutorials, and I could not bring myself to finishing any of them.

The problem here is that I already know how to build web apps. I've been doing it since I was eight years old.

I've learned how to build web apps by hand, by using PHP, by using Laravel (a framework built using PHP), by using Wordpress, and by using Ruby on Rails.

And you know what I've realized after all that learning? They're all slightly different ways of achieving the same thing.

And guess what? There are roughly a dozen different additional popular ways to build and deploy web apps. There's all kinds of containerization techniques to deploy scalable platforms. There are cloud providers that allow you to spin up all sorts of architectures to scale your platform. There are a bajillion different Javascript frameworks to write your code in, along with a quadrillion CSS frameworks to style your apps in.

I may have hit my Morgan Freeman in Shawshank moment where I simply don't care what technology we use anymore.

You feel compelled to use Rails to build a monolith? Great!

You think you're gonna hit a scale that requires a complex microservice infrastructure built on hundreds of lambdas? Fine, sure, let's do it.

The thing is, I don't want to learn a new framework for the sake of learning a new framework.

If I needed to figure out a specific architecture for a job, I am 100% confident that I could do it, even if it requires using a framework that I've never used. That's what nearly 30 years of building on the internet does for me.

[...]

Can I be real with you all for a minute?

Of all the sections I've written in this blog post, this one is the one I am having the hardest time releasing to the world.

I have a feeling I'm coming off as a bit of a crybaby.

I recognize that any craftsperson needs to hone their craft and stay up to date with the latest tooling in order to be marketable.

My problem may be that I'm conflating burnout symptoms with my general interest in learning new things.

In every development project I've ever worked on, I've had to learn new things.

There's always a new API, a new SDK, a new framework to pick up.

It's been part of my agency life for my entire career.

Maybe my problem isn't with learning new things. Maybe it's that I'm exhausted from having to whip around from tech to tech without ever taking an opportunity to go deep on any one of them in particular.

Even as a seasoned Ruby on Rails developer with more than a decade of use, I feel like I'm falling behind with all the fancy new Rails 7 functionalities like serving HTML over the wire.

There are a million different ways to build websites, and I'm struck with the realizing that I'll never learn all of them.

Maybe I have to decide whether I want to sharpen the tools I do know intimately, or whether now is a time to adopt new tools and put in the work to become an expert with those ones.

They say learning new things becomes harder as you get older.

What's next for me

Last month, I committed to coming back with a more clear vision of what I want my life to be. I don't think I'm at a point where I'm ready to articulate my vision, so I am going to continue spending time honing that through journaling, meditation, and conversation. I hope to be in a place to share a rough draft with y'all next month.

I also want to keep up my recent blitz of sharing links here on my blog. I'm going to add in a "tagging" feature to my posts so I can start keeping better track of things I talk about on here and find them more easily.

I also want to start podcasting again. I will commit that by next month, I'll be able to tell you what my new podcast will be about. My friend Dana and I are going to start meeting once a week to hold each other accountable on our various endeavors, and that's what I'll be spending that time plotting.

If you're reading this and want to know how you can help me, here's how:

  1. If you know of a full time (32-40 hr/week) job opportunity where I can help architect a complex software system for a meaningful organization and lead a team of people to get it built, please send it my way.
  2. If you come across any thought leaders who are speaking about AI from a perspective of what it will mean for our humanity (in how we work, how we organize, how we think, etc.), please connect them with me!

Thanks again for reading all the way to the end! If you did, I would love to hear if anything resonated with you. Shoot me an email or a note on LinkedIn.


  1. The next line in this exchange is, ironically, "Death is the only adventure you have left," which I don't feel fits neatly into my narrative here, but it's still a great movie. I can't wait for my kids to be old enough to enjoy it like I still do. 

JavaScript Bloat in 2024


šŸ”— a linked post to tonsky.me » — originally shared here on

It’s not just about download sizes. I welcome high-speed internet as much as the next guy. But code — JavaScript — is something that your browser has to parse, keep in memory, execute. It’s not free. And these people talk about performance and battery life...

Call me old-fashioned, but I firmly believe content should outweigh code size. If you are writing a blog post for 10K characters, you don’t need 1000Ɨ more JavaScript to render it.

I’ll be honest: I’m a bad modern front end dev.

I only have a limited amount of experience with frameworks like Vue and React.

But this blog post gets to the reason why: massive JavaScript framework bloat is often not necessary.

As you can see in this post, many of these incredibly basic sites that display text (like Medium and Substack) still require 4mb of JS code! That’s insane!

It’s like the old axiom goes: use the right tool for the job.

And maybe think twice before slapping a thousand marketing pixels on your landing page. ?

DOOM Turned Thirty


šŸ”— a linked post to brainbaking.com » — originally shared here on

I can understand how a VGA signal works when you give me a schematic and I’ll probably be able to program something for it. I can understand single-threaded CPU architectures and can probably write assembly or an emulator for it. But I have a lot of trouble understanding the internals of the digital 4K HDMI/USB-C output port, and even if you give me three months, I will never grasp even the basics of what’s under the hood of modern CPU chips. That’s a shame.

In that sense, I’m a bit worried that we’re over-engineering everything just because we can. Something that a single person could understand in 1993 now requires a dedicated team with ten years of experience.

On the one hand, I bet the DOOM team felt the same way thirty years ago about the confusing and complex systems of the mid-1990s.

But on the other, I definitely sympathize with the author. I feel spoiled that I was able to mostly learn how to program websites by right-clicking and viewing source.

Have you ever tried doing that on a modern website? It’s complete gibberish. Everything is obfuscated behind embedded, compressed Javascript libraries and CSS styling that is intentionally complex to prevent things like ad blocking tech from discovering which <div> blocks to hide.

Regardless, we should all wish a very happy birthday to DOOM.

I am currently looking at my Nalgene bottle of stickers and fondly looking at the Chex Quest one.

Also, I will never forget iddqd, idkfa, and idbehold.

Dependency rejection


šŸ”— a linked post to amontalenti.com » — originally shared here on

Dependencies seem to be all around us, both in the real world, and in programming. And they are perniciously distracting in just this way. Have you ever noticed how rare it is for you to just do something?

If so, you might have been worrying, up front, about dependencies.

Being a senior developer means you spend most of your time stressed out about the optimal way to get something shipped.

But I don’t just see that stress manifest in my professional life. Ask my wife how many side projects around the house she wants me to do that have not even been started.

It’s why I admire people who just start projects with no fear.

And it’s a trait I find myself trying to instill in my children, who will naturally jump into a task with both feet and zero regrets while I’m impatiently hovering over them, fretting about ā€œsafetyā€ and messes that’ll need to be cleaned up.

The Engineer/Manager Pendulum


šŸ”— a linked post to charity.wtf » — originally shared here on

The best frontline eng managers in the world are the ones that are never more than 2-3Ā years removed from hands-on work, full time down in the trenches. The best individual contributors are the ones who have done time in management.

And the best technical leaders in the world are oftenĀ the ones who do both. Back and forth. Ā Like a pendulum.

Solving common problems with Kubernetes


šŸ”— a linked post to blog.adamchalmers.com » — originally shared here on

I first learned Kubernetes ("k8s" for short) in 2018, when my manager sat me down and said "Cloudflare is migrating to Kubernetes, and you're handling our team's migration." This was slightly terrifying to me, because I was a good programmer and a mediocre engineer. I knew how to write code, but I didn't know how to deploy it, or monitor it in production. My computer science degree had taught me all about algorithms, data structures, type systems and operating systems. It had not taught me about containers, or ElasticSearch, or Kubernetes. I don't think I even wrote a single YAML file in my entire degree. I was scared of ops. I was terrified of Kubernetes.

Eventually I made it through and migrated all the Cloudflare Tunnel infrastructure from Marathon to Kubernetes. I didn't enjoy it, and I was way over my deadline, but I did learn a lot. Now it's 2022, and I'm leading a small team of engineers, some of whom have never used Kubernetes before. So I've found myself explaining Kubernetes to them. They seemed to find it helpful, so I thought I'd write it down and share it with the rest of you.

I immediately identified with this post after the author mentioned he was terrified of Kubernetes, because insert Chris Pratt meme here.

This post not only made the point of Kubernetes abundantly clear, it also was unveiled in such a clever and delightful way whereby each problem unveils a slightly more complex way to utilize Kubernetes.

I Accidentally Saved Half A Million Dollars


šŸ”— a linked post to ludic.mataroa.blog » — originally shared here on

I saved my company half a million dollars in about five minutes. This is more money than I've made for my employers over the course of my entire career because this industry is a sham. I clicked about five buttons.

Oof, this is a very good read that hits pretty close to home. I’ve seen stuff like this in several organizations I’ve worked with.

I wonder why it’s so prevalant?

Can't Be F*cked: Underrated Cause of Tech Debt


šŸ”— a linked post to jesseduffield.com » — originally shared here on

’But,’ you say, ā€˜premature optimisation is the root of all evil! Duplication is better than the wrong abstraction! Don’t be an architecture astronaut!’

The developers I’m thinking about already know of all those takes and have internalised them long ago. They know that sometimes ā€˜good enough’ is the right choice given the constraints of a project. They know that sometimes you need to cut scope to stay on-track. They know that sometimes it’s better to wait to learn more about a domain before rearchitecting a system. And yet in spite of those constraints their output remains golden. These are hard working motherf*ckers whose diligence and perseverance put other devs to shame.

Other devs… like me.

Sometimes, I just CBF.

You’re a Developer Now


šŸ”— a linked post to every.to » — originally shared here on

ChatGPT is not a total panacea, and it doesn’t negate the skill and intelligence required to be a great developer. There are significant benefits to reap from much of traditional programming education.

But this objection is missing the point. People who couldn’t build anything at all can now build things that work. And the tool that enables this is just getting started. In five years, what will novice developers be able to achieve?Ā 

A heck of a lot.Ā 

See, now this is the sort of insight that would’ve played well in a TEDx speech.

a road along a river with full fall foliage where many people are running a race

A Coder's Sprint: Behind The Scenes of the Twin Cities Marathon Graphics

originally shared here on

(Editor's note: That graphic is Midjourney's interpretation of what the Twin Cities Marathon looks like. Can you imagine if the Twin Cities Marathon actually looked like that? Running on top of the Mississippi River lmao)

Growing up, I took every chance I could get to be around live TV production.

The thing that keeps drawing me back to the medium is that you basically get one chance to tell a story to which there is an uncertain conclusion. The pressure to get it right is exhilarating.

Even though I haven't been part of a live production in roughly a decade, I had a unique opportunity this past weekend to be part of the live coverage of the Medtronic Twin Cities Marathon.

My role was to be the liaison between the marathon and the production crew who was filming, directing, and producing the show that was to ultimately be broadcast on KARE 11 (the local NBC station). I was to watch the race unfold and keep the crew informed of any interesting moves that we should mention on air.

I also was the liaison between the production crew and the timing crew. I would take periodic data dumps from the timing team, run them through a script I wrote, and pump out some graphics to help keep the audience up to date with the current leaders.

As you may or may not know, the race itself was unfortunately cancelled, so our collective efforts were not able to be showcased.

But even though we didn't get to try out our system live, I wanted to share some of the behind the scenes process for how I was able to get all this stuff to speak to each other. I'm mostly writing this for myself for the coming year, as I'd like to keep improving this process so the 2024 version of the race is chock full of awesome graphics that help to tell the story of the race.

The final product

Every good post should show the results first, right? Well, here's the two graphics I was able to get built in about 72 hours:

A large leaderboard graphic for television

This is a leaderboard intended to be a full-screen graphic, likely to be used with a blurred static shot under it.

A small leaderboard graphic for television

This is a leaderboard intended to be used while on top of a single shot with the leader in full frame.

The timing data

I was fortunate to spend the beginning part of my career working with the crew at Mtec Results. They are the team that helps time many of the major races around the country, most notably the Twin Cities Marathon and Grandma's Marathon, but they also are often called on to help out with other high-profile races like the marathons in Boston and New York City.

It took about 3 minutes of explaining the idea of using "real time data"[^tcm-2023-recap-1] to the team before it was met with a resounding "how can we help?"

We went back and forth around file formats and specs, and after we worked our way through uninteresting technical challenges[^tcm-2023-recap-2], we ultimately settled on a CSV format that looked something like this:

BIB,FIRST NAME,LAST NAME,GENDER,AGE,CITY,STATE,NATIONALITY,TEAM,TEAMTYPE,TIME OF DAY FINISH,GUN TIME,NET TIME,5K,10K,15K,20K,HALF,25K,30K,35K,40K,FIRST_HALF,SECOND_HALF,5 MILE
103,Rosalynne,Sidney,F,31,Burnsville,MN,USA,,,10:33:07.73,2:33:09,2:33:09,18:10,36:24,54:43,1:12:48,1:16:51,1:30:56,1:48:57,2:07:38,2:25:40,1:16:51,,

We decided given our time constraints, we would just keep that CSV in a shared Dropbox folder, and that file would get periodically updated throughout the race.

The graphics

The production team at Freestyle Productions uses an open source tool called SPX Graphics to generate and play back graphics during broadcasts.

SPX Graphics is a fascinating tool that uses HTML, JS, and CSS along with layers to help display all sorts of useful graphics like bugs, lower thirds, and crawls.

It took a little troubleshooting to understand the template structure that SPX uses, but in conjunction with ChatGPT, I was able to build out some basic HTML to create a table that I could dynamically populate:[^tcm-2023-recap-3]

<body>
  <div id="viewport">
    <div id="spxTable">
      <header>
        <div class="logo" id="marathon-logo">
          <img src="./TCM/tcm-logo.png">
        </div>
        <div class="logo" id="ten-mile-logo" style="display: none;">
          <img src="./TCM/ten-mile-logo.png">
        </div>
        <div id="title-container">
          MEN-FINISH
        </div>
      </header>

      <section class="table-body">
        <div class="table-row">
          <div>1</div>
          <div>Rosalynne SIDNEY</div>
          <div>USA</div>
          <div>??</div>
          <div>2:33:09</div>
          <div>--</div>
        </div>
        <!-- Add more table-row divs as needed -->
      </section>
    </div>
  </div>
</body>

Hooray, we now have a basic table for a full screen leaderboard! If you throw a little fancy CSS on top of it, you have a really nice looking table.

...but how do we populate it?

Translating the timing data

The CSV that I showed above contains some great data, but it's not particularly useful at the moment.

For starters, if I want to show the current leaders at 25K, do I use the values in the 25K row or do I use the values in the gun time row?

If I want to show how far back each racer is from each other (the time differential between each person), how do I generate that?

What happens if the racer's last name got entered in ALL CAPS instead of Title Case?

I figured I needed to write a tool that helped me transform this data into something a little easier to manipulate from the leaderboard template... so I did!

Behold, csvToJson.html in all its glory!

A screenshot of my rudimentary JSON generator

Because I know I'm going to forget what all these fields are for come next year, here's an explanation of what each field does:

  • CSV File: This is a basic input field to grab the CSV file from a local disk.
  • Header row: This is the name of the header row for which I want to pull the timing value (e.g. GUN TIME, which would pull 2:33:09 from the CSV example above)
  • Race: This allows me to tell the front end template which race to style it as
  • Title: This is the title in the top right corner for the full screen version or the first title on the smaller version
  • Subtitle: This is the second title on the smaller version (basically the name of the race)
  • Mile Split: In the smaller graphic, there's a little notch in the top right corner that contains the mile split for the most recently passed timing mat. This field lets me fill that in with the split.
  • Show time difference: On the full screen graphic, we may (or may not) want to show the time difference (e.g. +2:09).
  • Max number of elements: This should've probably said "max number of rows" because that's what this field controls. The full screen version of this graphic looks best with 10 entries, whereas the smaller version of the graphic looks best with 5.

Once you click "Load CSV", I fire off a Javascript method which loads the CSV and converts each row into a JSON object that looks something like this:

{
  "race": "marathon",
  "title": "Women's Leaders - 25K",
  "subtitle": "MEDTRONIC TWIN CITIES MARATHON",
  "mile_split": "25K",
  "show_time_difference": true,
  "table_data": [
    {
      "position": "1",
      "name": "Rosalynne SIDNEY",
      "time": "2:33:09",
      "difference": "--",
      "state": "MN",
      "country_name": "USA",
      "country_flag": "??"
    },
    // More entries here
  ]
}

I would then take that JSON and paste it into a file stored on a remote server.

Now that I have both a beautiful-looking template and a beautiful-looking source of data, I was able to whip up some Javascript on the template side to read that file on page load and populate the table with all the customizations included on it.

What's next?

It was truly a bummer that the race didn't get started. As someone who has gotten heat stroke at mile 21 of a marathon, I know that the organizers of the race did the right thing by cancelling it outright.

As someone who was in charge of building and displaying these graphics, though, I am a bit relieved that I get another year to iterate on this foundation.

Here are the obvious areas for improvement:

Automate the fetching of the data from Dropbox

If it wasn't clear, this process was brittle and prone to human error. I was having to load Dropbox from the web, download a CSV, manually sort it in Numbers based on the gun time, remove all but the top 10 or so rows of data, and then save a sanitized version.

There could be a tool written to automate this process so it is continually polling for updates to the file, and once it finds updates, it automatically does the sorting and converting so I don't need to touch it.

Automate the creation of the JSON from that timing data

Similar to above, I shouldn't need a csvToJson.html file. Because I'm sharing the data between the two templates, I should hard code the number of rows I want each template to read, and then I can fully automate the creation of the JSON it uses to populate the table.

Also, because of how SPX works, I need to host that JSON file somewhere remotely that the graphics system can access whenever the director calls for the graphic. That process should be similarly automated.

Improve the flag display

The Twin Cities Marathon attracts professional marathoners from all over the world, but it's not uncommon to see Minnesotans and other Americans finish in the top 10. It might be cool to use state-level flags instead of the US flag for the top athletes.

Another little annoying thing: I only had five countries hard-coded in my JSON creator because that was what I had from the representative data sample (USA, Canada, Mexico, Kenya, and New Zealand). I should probably support more flags because you should always be prepared for an unexpected performance from someone not from one of those five countries, right?

MOAR GFX PLZ KTHX

This leaderboard only scratchs the surface with what's possible.

With the timing data we're getting, I should be able to have a permanent graphic built that shows the top 10 runners at all times.

I should also have more graphics that you see in most professional marathon broadcasts:

  • An omni-present clock[^tcm-2023-recap-4]
  • Biographic slides that show a runner's photo along with some of their professional highlights
  • Slides with historical facts (course record holders and whatnot)
  • A map showing where runners are along the course

But I want more!

If we start planning now, we could attach biometric gear to some of the runners and show things like current heart rate, current pace, current stride count, and more.

Even if we aren't able to pull that off, we could still use the existing data to tell interesting stories like how the hill on Summit Avenue affects pace and how many runners are actually hitting "the wall".

Gearing up for 2024

I am so pleased with what we were able to pull together in basically a week.

Now that we have a better understanding of the technology that powers the graphic system, I am beyond excited at the possibilities ahead of us next year.

The team at Twin Cities in Motion truly care about putting on a best-in-class event for runners. Their commitment and investment in this broadcast are evidence of this, and I am honored to be part of the team responsible for telling the story of the two races that take place that day.

Mark your calendars for next October. It's gonna be an exciting race to watch live!

[^tcm-2023-recap-1]: For our purposes, we basically mean up to date within a minute or two of capturing the data. Getting updates to the leaderboard within milliseconds of a racer crossing a timing mat is not yet technically feasible. Besides, time is an arbitrary construct, right, maaan? [^tcm-2023-recap-2]: The software used to capture timing/scoring data for races is necessarily archaic. I say "necessarily" because it's both a feature and a bug; you don't want to put your trust in some fancy pants, brand new, untested Javascript framework to calculate results for an event that depends on those results for attracting big name runners, sponsors, and money. Of course, you can wrap all sorts of transforming layers on top of the data you collect from the timing systems, which is what Mtec does to power their results pages. But creating an API on top of that layer was not really feasible in the time we had. [^tcm-2023-recap-3]: You might notice in that HTML that I have two logos: one for the marathon and one for the ten mile. This allows me to reuse the same leaderboard graphic but style it orange or green to fit the relevant race. Also, stop judging my HTML! [^tcm-2023-recap-4]: Do you know how hard it is to get an accurate clock to display on screen? The homies that create professional football graphics are insanely talented. Again, time is an arbitrary construct.

The Disappearing Art Of Maintenance


šŸ”— a linked post to noemamag.com » — originally shared here on

Whatever comes next must take responsibility for that legacy, while also articulating something new and perhaps even bolder than what came before. There is a useful lesson drably concealed in the MTA’s maintenance facility in Queens: What we inherit comes with responsibility. Vintage machines are owed our best efforts, and our ingenuity in keeping them running should at least be equal to our ingenuity in forging them.Ā 

The work of maintenance is ultimately a way of parsing and knowing a thing and deciding, over and over, what it’s worth. ā€œMaintenance should be seen as a noble craft,ā€ said Rossmann, the boot-strapping repair man who learned the secrets of the iPhone’s circuits. ā€œIt should be seen as something that teaches people not just how to repair, but how to think.ā€

This article reinforced one of my core tenets of software engineering: the simpler, the better.

It also supplies an important distinction between repair and maintenance. Repair is when you fix something that’s broken. Maintenance is about making something last.

The article calls for finding a way to better incentivize acts of maintenance in our economic system, and the more I reflect on that, the more I find it reasonable.

Building new stuff is cool and often necessary, but finding a way to make our old stuff last longer is equally cool.

Not just with our bridges and train cars and iPhones, but with our elderly too.

There's still no silver bullet


šŸ”— a linked post to changelog.com » — originally shared here on

Saying ā€œuse the right tool for the jobā€ is easy, but actually selecting the right tool for the job is anything but. Good tools are hard to find, hard to evaluate, hard to learn. We have constraints, we have biases, we have shortcomings.

But that’s all part of the work.

And if you ā€œjust use Goā€ or ā€œjust use Reactā€ or ā€œjust use Postgresā€ for every problem that crosses your keyboard, you’re just not putting in the work.

I’ve only worked in agencies my entire professional career, and that work has honed two important traits of a good engineer: curiousity and agility.

Being curious gives you the ability to explore new tools and understand how they work.

Being agile (not in the project management sense, but the ā€œmoving freely and quicklyā€ sense) gives you the ability to deploy those tools to solve increasingly complex problems.

It’s not that I don’t have a standard set of tools I reach for when solving a wide swatch of problems (Rails, Postgres, etc.), but as I get older, I’m finding that I am more willing to engage with newer tech.

I come from a background of writing Javascript by hand, but I'm starting to play more with Vue and React, and I can see why people like these tools.

Same thing with CI/CD pipelines. I always thought they were more fiddle-y and brittle than they were worth, but that's because I've generally been a lone wolf. In a team context, they are extremely useful.

If you keep hearing noise about a new technology, it's probably worth taking a look over the fence to see how that tool could be used.

The blind programmers who created screen readers


šŸ”— a linked post to theverge.com » — originally shared here on

For most companies, accessibility isn’t a priority, or worse, something that they pay lip service to while doing the bare minimum to meet regulatory compliance. Ojala’s pet peeve is people thinking that accessibility is a feature, a nice-to-have addition to your product. When they tack on accessibility later, without thinking about it from the very beginning, Ojala can tell — it feels haphazard. (Imagine first creating a product with a colorless UI, then to add colors later as an afterthought, only to use the wrong color combination.)

I heard long ago that the reason developers should start testing software with accessibility in mind is that everyone, at some point in their life, will benefit from accessible technology.

At a minimum, as your eyesight gets older with age, an increase in font size will make it more comfortable to read things.

Any story that revolves around a few people banding together to solve an actual problem, and how that solution literally changed people’s lives, is so inspiring to me.

It’s what I yearn for at this point in my life. I don’t mind making money and building apps which drive business value. The stability of my job has done wonders for my mental health, and I am supremely grateful that I have it.

But boy, wouldn’t it be fun to get to work on something that has an outsized positive impact on people’s ability to live productive lives?

Programming Sucks


šŸ”— a linked post to stilldrinking.org » — originally shared here on

Here are the secret rules of the internet: five minutes after you open a web browser for the first time, a kid in Russia has your social security number. Did you sign up for something? A computer at the NSA now automatically tracks your physical location for the rest of your life. Sent an email? Your email address just went up on a billboard in Nigeria.

These things aren’t true because we don’t care and don’t try to stop them, they’re true because everything is broken because there’s no good code and everybody’s just trying to keep it running. That’s your job if you work with the internet: hoping the last thing you wrote is good enough to survive for a few hours so you can eat dinner and catch a nap.

As poignant, true, and depressing as it was back when it was 2014.

Craig Mod: Fast Software, the Best Software


šŸ”— a linked post to craigmod.com » — originally shared here on

Speed in software is probably the most valuable, least valued asset. To me, speedy software is the difference between an application smoothly integrating into your life, and one called upon with great reluctance.

I’ve tried articulating this notion to my clients, but now I’m just gonna send them this article.

If you manage a software project, or are interested in software development, Craig’s thoughts are a must read.

RailsConf 2019 - Opening Keynote by David Heinemeier Hansson


šŸ”— a linked post to youtube.com » — originally shared here on

I've never heard any of DHH's RailsConf keynote speeches before, so I guess I kind of expected it to be more about the state of Rails and where things are going.

In a way, I suppose this is that. But really, it's a personal manifesto about the intrinsic value of software, human worth, and capitalism.

This was mind bending and well worth the watch.

How to detect and replace YouTube links by extending the Redcarpet gem

originally shared here on

As I'll explain in a future post, I had an old Wordpress blog that I got sick of maintaining and updating, so I did what any red-blooded developer would do: build my own blog engine.

In doing so, however, I needed to import all my old posts from Wordpress over to my own Rails form. This worked nearly flawlessly, with the exception of my YouTube videos, which looked something like this (without the space inside the tag):

[youtube]nFZZxOHHZlo[/youtube ]

Because I am using the Redcarpet gem, I thought I'd extend its parsing capabilities to detect anything like this and wrap it in a responsive frame.

Here's how I did it (with extreme thanks to this SO post):

Step 1: Create a folder called app/services, and then create a file called custom_markdown.rb:

class CustomMarkdown < Redcarpet::Render::HTML
  def preprocess(text)
    format_youtube(text)
  end

  def format_youtube(text)
    text.gsub! /\[youtube](.*?)\[\/youtube]/ do
      "<div class='embed-container'><iframe src='https://www.youtube.com/embed/#{$1}' frameborder='0' allowfullscreen></iframe></div>"
    end
    text
  end

end

This code will perform a regular expression to find anything wrapped in [youtube] tags and replace it with a <div> that we can now style with CSS.

Step 2: Add the following SCSS somewhere in your project where it makes sense:

.embed-container { 
  position: relative; 
  padding-bottom: 56.25%; 
  height: 0; 
  overflow: hidden; 
  max-width: 100%; 
  iframe, object, embed { 
    position: absolute; 
    top: 0; 
    left: 0; 
    width: 100%; 
    height: 100%; 
  }
} 

Step 3: Use the custom parser when including Redcarpet in your project:

require './app/services/custom_markdown.rb' # This was necessary for me, might not be necessary for you
@blogs = Blog.all.order("published_at desc")
renderer = CustomMarkdown.new()
@markdown = Redcarpet::Markdown.new(renderer, extensions = {})

Now, anywhere you use those [youtube] tags, you'll get this fancy rendering instead:

Trying to put vertically-scrolling text in a UIScrollView? Don't.

originally shared here on

It took me about 3 hours of research and pulling my hair out to try and implement a UIScrollView that just scrolls a bunch of text vertically.

Turns out UIScrollView is for images, and UITextView is for text.

Talk about your ultimate face palm.

CTolleRun.com Redesign


šŸ”— a linked post to ctollerun.com » — originally shared here on

This week, we launched version 3 of CTolleRun.com. It's the result of several months of planning, organizing and development, and I thought I would take a few moments to share exactly what we've changed and the process behind it.

Our last redesign of the webpage was earlier this year. Truthfully, the site was rushed out in a hurry because we needed to have something live, so I pushed it out with the intention of upgrading it piece-by-piece down the line. Of course, we never got around to actually upgrading anything, and ultimately, we decided that time would be better spent on re-building from the ground-up.

The biggest conceptual change on the site was to give each episode its own page. This would give us a chance to better showcase our content, as well as drive our SEO. In order to implement this, however, required implementing a more robust, custom CMS1. Before this redesign, we were able to input the basic information: episode name, description, YouTube link, etc. Now, we are able to add several elements which make each page unique and more appealing for our viewers:

Links Almost every podcast I admire includes a list of links with each episode. This makes it easy to give viewers the chance to dive deeper into a specific topic, as well as share links we've mentioned in the episode. It also allows us to drive more traffic to the photo albums we've uploaded to Facebook.

Featured Guests We have the luxury of having some pretty awesome people on our show. Unfortunately, many of the guests we've had on our show aren't yet household names. Many people know who Kara Goucher is, but not a lot of people recognize Hassan Mead. If a viewer doesn't recognize who they're about to watch, it doesn't give them a lot of incentive to watch the episode.

To combat this, we included a short biography of each guest. We figured it's a simple way to boost viewership of those episodes as well as rank them higher on Google. In the future, I'm hoping to add links to these guest's social media accounts, as well as personal blogs or team pages.

Sponsors Before I became an avid podcast consumer (and creator), I loathed advertising. I ran ad-blockers on all my computers and I skipped over every sponsorship spot I possibly could.

It's really a shame, though, because a lot of the advertisers who throw money at podcasts like ours really seem to get it. They just want to put their product or race in the hands of people who maybe would've never even heard of it otherwise.

It's understandable that you don't want ads shoved down your face, though, which is why we've presented our ads in the ways we have. Each episode with a sponsor gets mentioned at the top of the show, and each sponsor gets an ad permanently embedded on the episode's page. We also have two "title sponsor" spots that are prominently displayed on the main page. That's it.

We think this is win-win-win: we are able to get you in touch with our sponsors, our sponsors are able to get permanent placements of their product and you are able to find out about some cool products, services and races without being hassled.

Social Media A huge focus for this redesign was to better integrate the site with social media. Here's what we did to optimize for our key three networks:

Facebook: If you're a developer, and you're not using Open Graph tags, you're missing out. By using Open Graph tags, we were able to turn our bland-looking links into this:

An added bonus: if you specify the OG tags for og:video and og:video-type, Facebook will embed the YouTube video in-line! Here's the code I used for that: <meta property="og:video" content="http://www.youtube.com/v/<? echo $youtubeID; ?>?version=3&autohide=1" /> <meta property="og:video:type" content="application/x-shockwave-flash" /> Twitter: If you're not simply sharing an article or some photos, Twitter's new Cards functionality is a bit more complex than simply adding OG tags. In order to make a functioning Player Card, Twitter wants you to build a page that gets embedded in an IFRAME. In a similar vein to what we're doing with Facebook, we're standing on the shoulders of giants and simply embedding YouTube's Player Card with our episode ID passed through: <meta name="twitter:card" content="player" /> <meta name="twitter:site" content="@CTolleRun" /> <meta name="twitter:player" content="https://www.youtube.com/embed/ echo $youtubeID; ?>" /> <meta name="twitter:player:width" content="640" /> <meta name="twitter:player:height" content="360" />

And out comes this:

Note that the Twitter Card API requires the use of twitter:title, twitter:description, twitter:image and so forth. Thankfully, if you're already using og:title, og:description, og:image and so forth, you don't need to re-include them.

Pinterest: Unfortunately, Pinterest doesn't have a public-facing API yet. Essentially, all we can do is include a "Pin It" button for each episode. We'd really like to get a bigger presence on Pinterest, however, because it seems like a good portion of our target audience is there. Here's hoping for that API soon!

A note about Google+, App.net, etc.: I think it's important to not get too crazy with social networks. Sure, it's easy enough to drop a +1 button on each page, as well as a hundred other buttons. However, for each service you include, you're not only adding more visual clutter to your page; you're increasing the page's load time by executing a hundred different pieces of remote Javascript code.

If we get a huge demand to add another service to our site, or if Facebook loses a million followers, we'll go there. We're not dummies, but we're also not in the business of predicting which services will be the best. Facebook, Twitter and Pinterest seem to be our best options today. We'll adapt as time goes on.

More Robust RSS Feeds Our RSS feeds (video and audio) aren't the most popular way to get our episodes2, but it's my personal favorite, so I made an effort to optimize this experience as well. Each item in the feed includes the linked list as well as the episode's sponsors. We also include the file size and run time of each episode, which means the fancy podcast clients will be able to show that information without any big-city processing on their end.

MailChimp We converted our mailing list over to the incomparable MailChimp. It's everything you could possibly want in a mailing list provider, but for free. My only gripe with them thus far is that the templates aren't 100% customizable, but it's just about the only fault I can find with them. Seriously, if you do mailing lists, you should be doing them through MailChimp.

Front Page Slide Show Whenever a client requests a rotating slide show, my go-to choice has always been Nivo Slider. For this project, however, I needed a solution that allowed me to use two <div> tags for a caption (one on top, one on bottom). With Nivo Slider, the solution I came up with was to put two smaller <div>'s into 1 giant <div>. Unfortunately, that meant the image wasn't clickable, which defeated the purpose of the slider.

I tried a few different sliders and ultimately settled on Camera by Pixedelic. This awesome slider allowed me to place as many <div>'s (or any other kind of crazy mark-up) on top of the image while maintaining its clickablilty. My only gripe is that the slideshow doesn't work as well in IE, which is, of course, no surprise to anyone.

Internet Explorer Fixes Speaking of every web developer's best friend, Internet Explorer provided the majority of trouble for this redesign. I kept getting alignment issues with IE while using Nathan Smith's excellent 960 Grid System, so instead of learning a whole new system (like the Responsive Grid System which I'm highly considering for future projects), I just added the <meta> tag which forces IE to render everything as if its IE7 (even if you're on a newer version):

<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />

Of course, this is a very inelegant solution, but I'm just sick of wasting so much time making sites look good in IE when every other browser (even Opera) gives me less guff.

Embedded Tweets in the Footer It's all about keeping your site fresh and up to date, right? I thought the best way to do this was to write a script that cached our latest Tweet server-side. I'm not sure if it fully complies with the infamous Rules of the Road, but since our use doesn't really allow for tons of Branding®©™, I think we'll be okay.

I ended up using WebcodingEasy.com's fantastic Convert twitter created_at time format to ago format script to make our time appear like Twitter's "12 minutes ago" format, as well as another open source script (which I, embarrassingly, can't find right now) to convert all tweeted links into clickable links.

The toughest part was writing the Tweet caching script. Essentially, my script reads a Tweet which was saved onto the sever from the Twitter API. When it's saved, I append a variable called cached_Tweet_Time along with the current server time. When someone loads the footer, it will read the cached Tweet and check the time. If it's less than a minute old, the script returns the Tweet from the server. If it's more than a minute old, it fetches a Tweet from Twitter. If anyone is interested in the source code, let me know and I'll post it here.

In the future, I'd like to append the script so it only returns Tweets which aren't "at-replies".

In Conclusion This has been one of the most ambitious site designs I've ever completed3, and I am quite pleased with how it has turned out. Front-end design has never been my strong suit; in fact, most of my designs end up looking the same. This time, however, I forced myself to look outside of my wheelhouse and try something new. I hope you guys like it, and if you have any questions, let me know.


  1. Before this redesign, we were running everything on a custom CMS that was integrated with our owner's race results page. The new CMS consists of multiple, custom databases which all link together. :adjusts nerd glasses: 

  2. I believe (as of a few weeks ago) we have a combined total of 120 subscribers to these feeds, which is in the ballpark to how many people reach our page through our e-mail newsletters. 

  3. The only bigger project I can think of right now was That's Unpossible, and that underwent somewhere around 9 redesigns and spanned across 6 databases.