Summit Themes
Blog

Things I have to remind myself as a developer

Every developer I know has a mental list of things they already understand but have to relearn on a semi-regular basis. Not because they forgot — more because the pressure of a deadline, a new tool, or just a bad Tuesday is enough to make you abandon the thing you swore you would do differently this time.

This is my list. Some of these are technical. Some are just about how to work. All of them have burned me at least once.

Ship the thing, then make it good

The version in my head is always better than the version in the repository. That is a fact, and it is also a trap. I have sat on features for weeks because I was convinced they were not ready, only to ship them, get actual feedback, and realize I had been optimizing the wrong half entirely.

The gap between "ready" and "perfect" is where most work disappears. Shipping a working, honest version of something is not laziness — it is how you find out what the thing actually needs to be. Polish what users tell you matters. Guess less.

Read the error message first

I have a bad habit, and I suspect you do too: when something breaks, I reach for my mental model of what is probably wrong before I have actually read what the runtime said. Half the time, the error message tells me exactly what the problem is, on which line, with context.

The other half of the time, the error message is confusing — but reading it carefully still narrows the search. Stack traces are worth reading top to bottom. The first frame that mentions your own code is almost always where to start. Browser DevTools, terminal output, build logs: read them before you search.

Naming things is not a small decision

A variable named data, a function named handleStuff, a component named Card2 — these feel fine when you write them and feel like sabotage six months later. Names are the primary documentation for most code.

I try to remind myself: if I cannot name a function clearly, I probably do not have a clear idea of what it does. That is useful information. A murky name is often a sign the abstraction is wrong, not that the name is hard to find.

Git commits are not a chore

Writing a commit message that says fix or wip or asdf is technically harmless. Until you are bisecting a regression at 11pm and trying to figure out which of forty commits introduced it, and every message is a shrug.

A useful commit message has a subject line that finishes the sentence "If applied, this commit will..." and optionally a short body that explains why, not just what. Something like:

fix: prevent mobile nav from overlapping hero CTA

The nav was using position: fixed without accounting for the hero's
z-index stacking context. Increased hero z-index to 10 and capped
nav at 9 for predictable stacking order.

That takes ninety seconds to write and saves an hour later. The ratio is embarrassingly good.

Do not abstract until the duplication actually hurts

Early abstraction is the source of a lot of the complexity I have introduced into codebases. You see two things that look similar, you pull them into a shared function, and then the third case is slightly different and you start adding parameters, then flags, then the function is doing three jobs and the "abstraction" has made things harder to understand than the duplication would have.

The rule I try to follow is: copy it twice, abstract it the third time. By then you usually understand the actual pattern rather than the apparent one. And sometimes the third case reveals the two previous ones were not actually the same thing at all.

Slow down on CSS before reaching for JavaScript

This one catches me specifically with interactive UI. My instinct is to reach for JavaScript when something needs to move, toggle, or respond to state. But CSS handles a surprising amount of this natively, with better performance and less code.

Disclosure widgets, smooth height transitions, hover states, focus rings, sticky headers, scroll-driven effects — a lot of what I have written JavaScript for over the years has a CSS-native answer now. Worth checking before adding an event listener.

For example, a simple accessible disclosure pattern without any JavaScript:

<details class="disclosure">
  <summary>What does this include?</summary>
  <p>A full Astro component library, Tailwind config, and deployment guide.</p>
</details>

That is keyboard-accessible, screen-reader-friendly, and animatable with ::details-content in supporting browsers — no JavaScript required.

Performance is a feature, not a polish pass

I have shipped things that worked correctly and loaded slowly, and told myself I would come back and optimize. I almost never did. And even when I did, the structural changes that would have made the biggest difference were now wrapped in layers of code that made them much harder to make.

The decisions that determine 80% of a page's performance are made early: how much JavaScript gets shipped, whether images are sized correctly and in the right format, whether fonts block rendering, whether third-party scripts are deferred. These are architecture decisions, not micro-optimizations. Making them later is possible but expensive.

You do not need to understand everything to ship it

This one feels counterintuitive coming from me, but: deep understanding of every tool in your stack is a goal, not a prerequisite. There is a version of thoroughness that becomes paralysis — reading every RFC before using a browser API, studying every algorithm before picking a data structure.

The better model, I think, is: understand enough to use it correctly and debug it when it breaks. Deepen your understanding when you hit the edge. Most of what I know about how browsers work I learned because something broke and I had to dig.

Write for the person who reads it next

That person is usually me, eight months from now, and I will have no memory of the context I had when I wrote the original. A comment that explains why something is done a particular way — especially when the code looks like it should be done differently — is worth more than a comment that describes what the code already says clearly.

// Intentionally NOT using CSS custom properties here.
// Safari 15 had a known bug with custom property inheritance inside
// shadow DOM that caused values to be silently ignored. Hardcoding
// until we drop Safari 15 support (target: Q3).
const borderColor = "#e2e8f0";

That comment will save someone — probably me — from "fixing" the code back to the broken version.

Estimations are always optimistic

I have never once looked back at a completed project and thought "I really nailed that timeline." I always underestimate. Not by a little — usually by a factor of two or three once you count the edge cases, the back-and-forth on decisions, the random Tailwind quirk that ate an afternoon.

The advice I keep getting and keep ignoring: estimate, then double it. Or at minimum, explicitly budget time for "things I have not thought of yet," because there are always things you have not thought of yet.

Take breaks before you are stuck

I am most likely to step away from my desk when I am making steady progress. I am least likely to when I am stuck and frustrated. This is exactly backwards. The bug that has me locked in for three hours almost always dissolves within twenty minutes of stepping outside or switching to something else entirely.

The brain keeps working on problems in the background. The prerequisite is that you actually give it room to do that.

Finishing is a skill

Starting projects is easy. Most developers I know have a graveyard of interesting half-built things. Finishing — getting something to the state where another person can actually use it, where the rough edges are handled, where the documentation exists — is its own specific skill and it takes practice to develop.

I try to get to "done enough to show someone" faster than feels comfortable. That usually means resisting the urge to add one more feature before I let anyone see it. Momentum on a project is real, and it is much easier to maintain than to rebuild after a long gap.

The list goes on

There are other things — back up your work before you do anything clever, check your assumptions before blaming the library, read the documentation before reading Stack Overflow — but these are the ones I come back to most often. They are not secrets. Most developers would nod along to all of them. The hard part is not knowing them; it is keeping them close enough to actually use when the pressure is on.