<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Gabriel Teles</title><link>https://gabteles.wtf/</link><description>CTO and co-founder of Ella, writing about product, engineering, strategy, and the craft of building software.</description><generator>Hugo</generator><language>en-us</language><managingEditor>Gabriel Teles</managingEditor><lastBuildDate>Mon, 13 Apr 2026 01:57:50 +0200</lastBuildDate><atom:link href="https://gabteles.wtf/tags/product/index.xml" rel="self" type="application/rss+xml"/><item><title>In praise of brutal software</title><link>https://gabteles.wtf/posts/2-in-praise-of-brutal-software/</link><pubDate>Sat, 31 Jan 2026 11:00:00 -0300</pubDate><guid>https://gabteles.wtf/posts/2-in-praise-of-brutal-software/</guid><description>On usefulness, purpose, and the beauty of what lasts</description><content:encoded>&lt;p&gt;Recently I&amp;rsquo;ve been watching a lot of content about architecture. Not software architecture, but actual buildings. There&amp;rsquo;s something about the way physical structures are designed and constructed that resonates deeply with how I think about software engineering.&lt;/p&gt;
&lt;p&gt;Architecture, at its essence, is about crafting spaces where people can live, work, and connect. A building might be visually stunning or elegantly simple, but its true success lies in its livability. If it cannot be inhabited, it has missed its purpose. It might qualify as art, but it ceases to be architecture.&lt;/p&gt;
&lt;p&gt;Engineering isn’t so different It’s easy to get caught up in abstractions, patterns, and the excitement of creating. We often fall in love with the craft: the cleverness of a design, the precision of an implementation, the elegance of the code. But elegance without purpose is just ornamentation. What we build isn’t meant to be admired from afar; it’s meant to be used, trusted, and integrated into people’s lives.&lt;/p&gt;
&lt;p&gt;We create products through software, not the other way around. Our role isn’t to make technology fascinating — it’s to make it practical, reliable, and impactful. A system that’s technically impressive but disconnected from its purpose is like a museum exhibit: it might be admired, but it cannot be lived in.&lt;/p&gt;
&lt;p&gt;That’s why true ownership begins long before the first commit, or even before the first line of code is written. It starts with understanding the problem, questioning the assumptions, and ensuring that what we’re building is worth building. Code may be the most visible part of the system, but clarity and purpose form the foundation that holds everything together.&lt;/p&gt;
&lt;p&gt;And just like in architecture, we don’t build in isolation. Collaboration with design, product, and business teams is essential. Each perspective contributes to shaping a structure that is not only functional but also resilient and aligned with its purpose.&lt;/p&gt;
&lt;p&gt;Over time, this mindset brings clarity to what engineering truly entails. It’s not about invention for the sake of novelty. It’s about creating something that earns its place, something people can rely on without ever needing to understand its inner workings.&lt;/p&gt;
&lt;p&gt;Maybe that’s why I find myself drawn to architecture, especially brutalism.&lt;br&gt;
There’s an honesty in its raw concrete, unadorned surfaces, and exposed structures. Brutalism doesn’t seek approval or admiration. It exists to fulfill its purpose, which is to provide shelter, stability, and longevity. And in that steady commitment to function, it reveals a quiet, understated beauty.&lt;/p&gt;
&lt;p&gt;Brutalist buildings often evoke strong emotions, but their appeal is incidental, not intentional. Their beauty lies in their authenticity: every element has a purpose, and nothing is superfluous.&lt;/p&gt;
&lt;p&gt;Good software shares the same essence.&lt;br&gt;
It doesn’t rely on decoration or fleeting trends. Instead, it is purposeful, straightforward, and honest about its intent. If beauty emerges, it’s a byproduct of its authenticity, not a deliberate attempt to dazzle.&lt;/p&gt;
&lt;p&gt;We don’t create to impress. We create to be used.&lt;br&gt;
Code is merely the framework; the product is the structure it supports.&lt;br&gt;
The finest architecture — whether physical or digital — is the kind that quietly fulfills its purpose, enduring long after its creator has stepped away.&lt;/p&gt;</content:encoded></item><item><title>Good enough to learn from</title><link>https://gabteles.wtf/posts/1-good-enough-to-learn-from/</link><pubDate>Fri, 16 Jan 2026 11:00:00 -0300</pubDate><guid>https://gabteles.wtf/posts/1-good-enough-to-learn-from/</guid><description>Shipping something imperfect isn't lowering the bar, it's how you learn where the bar actually is.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This is a reflection on choosing momentum over perfection, not as carelessness, but as a way to learn faster, decide better, and build things that actually matter.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I&amp;rsquo;ve always been drawn to beautiful systems. Clean abstractions, careful boundaries, code that feels intentional in every line. Early on, I mistook that feeling for excellence. I believed great engineering meant getting it right from the start, and that if you thought hard enough, designed carefully enough, you could arrive at something close to perfect before anyone ever used it.&lt;/p&gt;
&lt;p&gt;That belief didn&amp;rsquo;t survive contact with reality.&lt;/p&gt;
&lt;p&gt;A few projects that lingered too long in “almost ready” were enough to teach me that perfection doesn&amp;rsquo;t fail loudly. It fails by slowing everything down. A flawless idea, still trapped in your head or on a whiteboard, has no impact. A working version, even if an awkward one, already does.&lt;/p&gt;
&lt;p&gt;The moment something real exists, the nature of the work changes. You stop arguing in hypotheticals and start dealing with evidence. Instead of debating what users might want, you can see what they actually do. An imperfect release creates a feedback loop that planning alone never will. It gives you signal, friction, direction. It reveals problems you didn&amp;rsquo;t anticipate and invalidates assumptions you didn&amp;rsquo;t realize you were making.&lt;/p&gt;
&lt;p&gt;That loop of build, release, and learn ended up mattering far more than the internal satisfaction of pristine code. It&amp;rsquo;s also relieving once you accept that progress and perfection are not the same thing, momentum becomes easier to choose.&lt;/p&gt;
&lt;p&gt;A sidenote here: There&amp;rsquo;s also a place for the opposite impulse. It&amp;rsquo;s okay to overengineer deliberately when learning is the goal and shipping isn&amp;rsquo;t. If you want to explore a design space deeply, build an overly elaborate abstraction, or follow an idea to its most complex conclusion, do it. There is real value in pushing systems further than necessary, in discovering their limits, and in understanding why certain approaches collapse under their own weight. As long as there&amp;rsquo;s no hidden pressure to release it, no illusion that this exercise must justify itself in production, that kind of work can be deeply formative. It sharpens judgment, not because the result is useful, but because the process teaches you what not to carry forward.&lt;/p&gt;
&lt;p&gt;And back to the original track, shipping before perfect is often framed as carelessness, as if you&amp;rsquo;re lowering the bar or excusing sloppy work. I think that&amp;rsquo;s a misunderstanding. The real distinction isn&amp;rsquo;t between quality and speed; it&amp;rsquo;s between intentional trade-offs and indulgence. The question isn&amp;rsquo;t “should this be better?”, everything can be better. The question is whether the extra refinement meaningfully changes the outcome, or whether it only satisfies our own sense of craftsmanship.&lt;/p&gt;
&lt;p&gt;There are moments when stopping to refactor is the responsible move. There are also moments when shipping and observing is the only way forward. Both can be acts of care, depending on timing. What matters is being deliberate about which one you&amp;rsquo;re choosing — and why.&lt;/p&gt;
&lt;p&gt;When I feel stuck between polishing and releasing, I try to ground myself with a few simple questions. Does this change something important for the user, or is it mainly for me? Will waiting actually teach me anything new? If I release now, what&amp;rsquo;s the realistic downside and what information might I gain?&lt;/p&gt;
&lt;p&gt;Those questions pull me back to impact. Because engineering, at least as I&amp;rsquo;ve come to understand it, isn&amp;rsquo;t about building elegant artifacts in isolation. It&amp;rsquo;s about creating things that matter in the real world.&lt;/p&gt;
&lt;p&gt;Over time, I stopped thinking of software as something you finish. Software is alive. It evolves as users change, as the business shifts, as constraints move. Every release is just the best version so far. That&amp;rsquo;s not a compromise; it&amp;rsquo;s the nature of the medium.&lt;/p&gt;
&lt;p&gt;Seeing it that way removed a lot of anxiety from my work. I no longer feel pressure to make something flawless before it&amp;rsquo;s allowed to exist. I focus on making it real. Once it&amp;rsquo;s real, improvement becomes continuous rather than blocked behind a perfectionist gate.&lt;/p&gt;
&lt;p&gt;When I&amp;rsquo;m tempted to delay for one last improvement, I come back to a simple thought: would I rather have something to improve, or nothing to show?&lt;/p&gt;
&lt;p&gt;The answer hasn&amp;rsquo;t changed. The best code I&amp;rsquo;ve written wasn&amp;rsquo;t the cleanest. It was the code that reached people, solved a real problem, and taught me something new. That&amp;rsquo;s what keeps me buildind one working version at a time.&lt;/p&gt;</content:encoded></item></channel></rss>