Latest Posts (20 found)
Matthias Endler 2 weeks ago

On Choosing Rust

Since my professional writing on Rust has moved to the corrode blog , I can be a bit more casual on here and share some of my personal thoughts on the recent debate around using Rust in established software. The two projects in question are git ( kernel thread , Hacker News Discussion ) and the recently rewritten coreutils in Rust , which will ship with Ubuntu 25.10 Quizzical Quokka . What prompted me to write this post is a discussion on Twitter and a blog post titled “Are We Chasing Language Hype Over Solving Real Problems?” . In both cases, the authors speculate about the motivations behind choosing Rust, and as someone who helps teams use Rust in production, I find those takes… hilarious. Back when I started corrode, people always mentioned that Rust wasn’t used for anything serious. I knew about the production use cases from client work, but there was very little public information out there. As a consequence, we started the ‘Rust in Production’ podcast to show that companies indeed choose Rust for real-world applications. However, people don’t like to be proven wrong, so that conspiracy theory has now morphed into “Big Rust” trying to take over the world. 😆 Let’s look at some of the claims made in the blog post and Twitter thread and see how these could be debunked pretty easily. “GNU Core Utils has basically never had any major security vulnerabilities in its entire existence” If only that were true. A quick CVE search shows multiple security issues over the decades, including buffer overflows and path traversal vulnerabilities. Just a few months ago, a heap buffer under-read was found in , which would cause a leak of sensitive data if an attacker sends a specially crafted input stream. The GNU coreutils are one of the most widely used software packages worldwide with billions of installations and hundreds (thousands?) of developers looking at the code. Yes, vulnerabilities still happen. No, it is not easy to write correct, secure C code. No, not even if you’re extra careful and disciplined. is five thousand lines long. (Check out the source code ). That’s a lot of code for printing file names and metadata and a big attack surface! “Rust can only ever match C performance at best and is usually slower” Work by Trifecta shows that it is possible to write Rust code that is faster than C in some cases. Especially in concurrent workloads and with memory safety guarantees. If writing safe C code is too hard, try writing safe concurrent C code! That’s where Rust shines. You can achieve ridiculous levels of parallelization without worrying about security issues. And no, you don’t need to litter your code with blocks. Check out Steve Klabnik’s recent talk about Oxide where he shows that their bootloader and their preemptive multitasking OS, hubris – both pretty core systems code – only contain 5% of code each. You can write large codebases in Rust with no unsafe code at all. As a trivial example, I sat down to rewrite in Rust one day. The result was 3x faster than GNU on my machine. You can read the post here . All I did was use to copy data, which saves one memory copy. Performance is not only dependent on the language but on the algorithms and system calls you use. If you play into Rust’s strengths, you can match C’s performance. At least there is no technical limitation that would prevent this. And I personally feel more willing to aggressively optimize my code in Rust, because I don’t have to worry about introducing memory safety bugs. It feels like I’m not alone . “We reward novelty over necessity in the industry” This ignores that most successful companies (Google, Meta, etc.) primarily use battle-tested tech stacks, not bleeding-edge languages. These companies have massive codebases and cannot afford to rewrite everything in the latest trendy language. But they see the value of using Rust for new components and gradually rewriting existing ones. That’s because 70% of security vulnerabilities are memory safety issues and these issues are extremely costly to fix. If these companies could avoid switching to a new language to do so, they would. Besides, Rust is not exactly new anymore. Rust 1.0 was released 10+ years ago! The industry is moving slowly, but not that slowly. You’d be surprised to find out how many established companies use Rust without even announcing it or thinking of it as “novelty”. “100% orchestrated” Multiple people in the Twitter thread were convinced this is some coordinated master plan rather than developers choosing better tools, while the very maintainers of git and coreutils openly discussed their motivations in public forums for everyone to see. “They’re trying to replace/erase C. It’s not going to happen” They are right. C is not going away anytime soon. There is just so much C/C++ code out there in the wild, and rewriting everything in Rust is not feasible. The good news is that you can incrementally rewrite C/C++ code in Rust, one component at a time. That’s what the git maintainers are planning, by using Rust for new components. “They’re rewriting software with a GNU license into software with an MIT license” Even if you use Rust, you can still license your code under GPL or any other license you want. Git itself remains GPL, and many Rust projects use various licenses, not only MIT. The license fear is often brought up by people who don’t understand how open source licensing works or it might just be FUD. MIT code is still compatible with GPL code and you can use both of them in the same project without issues. It’s just that the end product (the thing you deliver to your users, i.e. binary executables) is now covered by GPL because of its virality. “It’s just developers being bored and wanting to work with shiny new languages” The aging maintainers of C projects are retiring, and there are fewer new developers willing to pick up C just to maintain legacy code in their free time. C developers are essentially going extinct. New developers want to work with modern languages and who can blame them? Or would you want to maintain a 40-year-old COBOL codebase or an old Perl script? We have to move on. “Why not build something completely new instead of rewriting existing tools?” It’s not that easy. The code is only part of the story. The other part is the ecosystem, the tooling, the integrations, the documentation, and the user base. All of that takes years to build. Users don’t want to change their workflows, so they want drop-in replacements. Proven interfaces and APIs, no matter how crude and old-fashioned, have a lot of value. But yes, new tools are being built in Rust as well. “They don’t know how to actually solve problems, just chase trends” Talk about dismissing the technical expertise of maintainers who’ve been working on these projects for years or decades and understand the pain points better than anyone. If they were just chasing trends, they wouldn’t be maintaining these projects in the first place! These people are some of the most experienced developers in the world, and yet people want to tell them how to do their jobs. “It’s part of the woke mind virus infecting software” Imagine thinking memory safety is a political conspiracy. Apparently preventing buffer overflows is now an ideological stance. The closest thing to this is the White House’s technical report which recommends memory-safe languages for government software and mandating memory safety for software receiving federal funding is a pretty reasonable take. Conclusion I could go on, but I think you get my point. People who give Rust an honest chance know that it offers advantages in terms of memory safety, concurrency, and maintainability. It’s not about chasing hype but about long-term investment in software quality. As more companies successfully adopt Rust every day, it increasingly becomes the default choice for many new projects. If you’re interested in learning more about using Rust in production, check out my other blog or listen to the Rust in Production podcast . Oh, and if you know someone who posts such takes, stop arguing and send them a link to this post.

0 views
Matthias Endler 2 months ago

How To Review Code

I’ve been reviewing other people’s code for a while now, more than two decades to be precise. Nowadays, I spend around 50-70% of my time reviewing code in some form or another. It’s what I get paid to do, alongside systems design. Over time, I learned a thing or two about how to review code effectively. I focus on different things now than when I started. Think About The Big Picture Bad reviews are narrow in scope. They focus on syntax, style, and minor issues instead of maintainability and extensibility. Good reviews look at not only the changes, but also what problems the changes solve, what future issues might arise, and how a change fits into the overall design of the system. I like to look at the lines that weren’t changed. They often tell the true story. For example, often people forget to update a related section of the codebase or the docs. This can lead to bugs, confusion, breaking changes, or security issues. Be thorough and look at all call-sites of the new code. Have they been correctly updated? Are the tests still testing the right thing? Are the changes in the right place? Here’s a cheat sheet of questions I ask myself when reviewing code: These questions have more to do with systems design than with the changes themselves. Don’t neglect the bigger picture because systems become brittle if you accept bad changes. Code isn’t written in isolation. The role of more experienced developers is to reduce operational friction and handle risk management for the project. The documentation, the tests, and the data types are equally as important as the code itself. Always keep an eye out for better abstractions as the code evolves. Naming Is Everything I spend a big chunk of my time thinking about good names when reviewing code. Naming things is hard, which is why it’s so important to get it right. Often, it’s the most important part of a code review. It’s also the most subjective part, which makes it tedious because it’s hard to distinguish between nitpicking and important naming decisions. Names encapsulate concepts and serve as “building blocks” in your code. Bad names are the code smell that hint at problems running deep. They increase cognitive overhead by one or more orders of magnitude. For example, say we have a struct that represents a player’s stats in a game: I often see code like this: This code is hard to read and understand. What is , , and ? The purpose is not conveyed clearly. This builds up cognitive load and make it harder to follow the logic. That’s why I always think of the most fitting names for variables, even if it feels like I’m being pedantic. Good names become even more critical in larger codebases where values are declared far away from where they’re used and where many developers have to have a shared understanding of the problem domain. Don’t Be Afraid To Say “No” I have to decline changes all the time and it’s never easy. After all someone put in a lot of effort and they want to see their work accepted. Avoid sugarcoating your decision or trying to be nice. Be objective, explain your reasoning and provide better alternatives. Don’t dwell on it, but focus on the next steps. It’s better to say no than to accept something that isn’t right and will cause problems down the road. In the future it will get even harder to deny a change once you’ve set a precedent. That’s the purpose of the review process: there is no guarantee that the code will be accepted. In open source, many people will contribute code that doesn’t meet your standards. There needs to be someone who says “no” and this is a very unpopular job (ask any open source maintainer). However, great projects need gatekeepers because the alternative is subpar code and eventually unmaintainable projects. At times, people will say “let’s just merge this and fix it later.” I think that’s a slippery slope. It can lead to tech debt and additional work later on. It’s hard to stand your ground, but it’s important to do so. If you see something that isn’t right, speak up. When it gets hard, remember that you’re not rejecting the person, you’re rejecting the code. Remind people that you appreciate their effort and that you want to help them improve. Even though you’ll develop an intuition for what to focus on in reviews, you should still back it up with facts. If you find yourself saying “no” to the same thing over and over again, consider writing a style guide or a set of guidelines for your team. Be gracious but decisive; it’s just code. Code Review Is Communication Code reviews aren’t just about code; people matter too. Building a good relationship with your coworkers is important. I make it a point to do the first couple of reviews together in a pair programming session if possible. This way, you can learn from each other’s communication style. Building trust and getting to know each other works well this way. You should repeat that process later if you notice a communication breakdown or misunderstanding. Use Multiple Iterations Of Reviews “Can you take a quick look at this PR? I want to merge it today.” There often is an expectation that code reviews are a one-time thing. That’s not how it works. Instead, code reviews are an iterative process. Multiple iterations should be expected to get the code right. In my first iteration, I focus on the big picture and the overall design. Once I’m done with that, I go into the details. The goal shouldn’t be to merge as quickly as possible, but to accept code that is of high quality. Otherwise, what’s the point of a code review in the first place? That’s a mindset shift that’s important to make. Reviews aren’t exclusively about pointing out flaws, they’re also about creating a shared understanding of the code within the team. I often learn the most about writing better code by reviewing other people’s code. I’ve also gotten excellent feedback on my own code from excellent engineers. These are invaluable “aha moments” that help you grow as a developer. Experts spent their valuable time reviewing my code, and I learned a lot from it. I think everybody should experience that once in their career. Don’t Be A Jerk From time to time, you’ll disagree with the author. Being respectful and constructive is important. Avoid personal attacks or condescending language. Don’t say “this is wrong.” Instead, say “I would do it this way.” If people are hesitant, ask a few questions to understand their reasoning. These “Socratic questions” 1 help the author think about their decisions and can lead to better designs. People should enjoy receiving your feedback. If not, revisit your review style. Only add comments that you yourself would be happy to receive. From time to time, I like to add positive comments like “I like this” or “this is a great idea.” Keeping the author motivated and showing that you appreciate their work goes a long way. If Possible, Try To Run The Code It’s easy to miss subtle details when you look at code for too long. Having a local copy of the code that I can play with helps me a lot. I try to run the code, the tests, and the linters if I can. Checking out the branch, moving things around, breaking things, and trying to understand how it works is part of my review process. User-facing changes like UI changes or error messages are often easier to spot when you run the code and try to break it. After that, I revert the changes and, if needed, write down my findings in a comment. Better understanding can come from this approach. Be Upfront About Your Availability Code reviews are often a bottleneck in the development process, because they can’t be fully automated: there’s a human in the loop who has to look at the code and provide feedback. But if you wait for your colleagues to review your code, that can lead to frustration. Avoid being that person. Sometimes you won’t have time to review code and that is okay. If you can’t review the code in a reasonable time, let the author know. I’m still working on this, but I try to be more proactive about my availability and set clear expectations. Never Stop Learning Code reviews are my favorite way to learn new things. I learn new techniques, patterns, new libraries, but most importantly, how other people approach problems. I try to learn one new thing with each review. It’s not wasted time, if it helps the team improve and grow as a whole. Don’t Be Nitpicky Formatters exist for a reason: leave whitespace and formatting to the tools. Save your energy for issues that truly matter. Focus on logic, design, maintainability, and correctness. Avoid subjective preferences that don’t impact code quality. Ask yourself: Does this affect functionality or would it confuse future developers? If not, let it go. Focus On The Why, Not The How When reviewing code, focus on the reasoning behind the changes. This has a much better chance of success than pointing out flaws without any reasoning. Consider the following two code review comments. The first one is unhelpful and dismissive. The second suggests an alternative, links to the documentation, and explains why the change could lead to problems down the road. Which one would you prefer to receive? I realize that this requires more time and effort, but it’s worth it! Most of the time, the author will appreciate it and avoid making the same mistake in the future. There is a compound effect from helpful reviews over time. Don’t Be Afraid To Ask Stupid Questions Asking is better than assuming. If you don’t understand something, ask the author to explain it. Chances are, you’re not the only one who doesn’t get it. Often, the author will be happy to explain their reasoning. Better understanding of the code and the system as a whole can result from this. It can also help the author see things from a different perspective. Perhaps they’ll learn that their assumptions were wrong or that the system isn’t self-explanatory. Perhaps there’s missing documentation? Asking great questions is a superpower. Ask For Feedback On Your Reviewing Style From time to time, ask the author for feedback on your feedback: Basically, you ask them to review your review process, heh. Learning how to review code is a skill that needs constant practice and refinement. Good luck finding your own style. Thanks for pointing out that term to me, Lucca! ↩ How does this code fit into the rest of the system? What’s its interaction with other parts of the codebase? How does it affect the overall architecture? Does it impact future planned work? “Will this break existing workflows if we do it this way?” “Which alternatives have you considered?” “What happens if you call this function with an empty array?” “If I don’t set this value, what will be the error message presented to the user?” Have you been too harsh/nitpicky/slow/sloppy? Did you point out the right things? Did your feedback help them? Do they have suggestions for improvement? Thanks for pointing out that term to me, Lucca! ↩

0 views
Matthias Endler 3 months ago

Repeat Yourself

One of the most repeated pieces of advice throughout my career in software has been “don’t repeat yourself,” also known as the DRY principle. For the longest time, I took that at face value, never questioning its validity. That was until I saw actual experts write code: they copy code all the time 1 . I realized that repeating yourself has a few great benefits. Why People Love DRY The common wisdom is that if you repeat yourself, you have to fix the same bug in multiple places, but if you have a shared abstraction, you only have to fix it once. Another reason why we avoid repetition is that it makes us feel clever. “Look, I know all of these smart ways to avoid repetition! I know how to use interfaces, generics, higher-order functions, and inheritance!” Both reasons are misguided. There are many benefits of repeating yourself that might get us closer to our goals in the long run. Keeping Up The Momentum When you’re writing code, you want to keep the momentum going to get into a flow state. If you constantly pause to design the perfect abstraction, it’s easy to lose momentum. Instead, if you allow yourself to copy-paste code, you keep your train of thought going and work on the problem at hand. You don’t introduce another problem of trying to find the right abstraction at the same time. It’s often easier to copy existing code and modify it until it becomes too much of a burden, at which point you can go and refactor it. I would argue that “writing mode” and “refactoring mode” are two different modes of programming. During writing mode, you want to focus on getting the idea down and stop your inner critic, which keeps telling you that your code sucks. During refactoring mode, you take the opposite role: that of the critic. You look for ways to improve the code by finding the right abstractions, removing duplication, and improving readability. Keep these two modes separate. Don’t try to do both at the same time. 2 Finding The Right Abstraction Is Hard When you start to write code, you don’t know the right abstraction just yet. But if you copy code, the right abstraction reveals itself; it’s too tedious to copy the same code over and over again, at which point you start to look for ways to abstract it away. For me, this typically happens after the first copy of the same code, but I try to resist the urge until the 2nd or 3rd copy. If you start too early, you might end up with a bad abstraction that doesn’t fit the problem. You know it’s wrong because it feels clunky . Some typical symptoms include: It’s Hard To Get Rid Of Wrong Abstractions We easily settle for the first abstraction that comes to mind, but most often, it’s not the right one. And removing the wrong abstraction is hard work, because now the data flow depends on it. We also tend to fall in love with our own abstractions because they took time and effort to create. This makes us reluctant to discard them even when they no longer fit the problem—it’s a sunk cost fallacy. It gets worse when other programmers start to depend on it, too. Then you have to be careful about changing it, because it might break other parts of the codebase. Once you introduce an abstraction, you have to work with it for a long time, sometimes forever. If you had a copy of the code instead, you could just change it in one place without worrying about breaking anything else. Duplication is far cheaper than the wrong abstraction —Sandi Metz, The Wrong Abstraction Better to wait until the last moment to settle on the abstraction, when you have a solid understanding of the problem space. 3 The Mental Overhead of Abstractions Abstraction reduces code duplication, but it comes at a cost. Abstractions can make code harder to read, understand, and maintain because you have to jump between multiple levels of indirection to understand what the code does. The abstraction might live in different files, modules, or libraries. The cost of traversing these layers is high. An expert programmer might be able to keep a few levels of abstraction in their head, but we all have a limited context window (which depends on familiarity with the codebase). When you copy code, you can keep all the logic in one place. You can just read the whole thing and understand what it does. Resist The Urge Of Premature Abstraction Sometimes, code looks similar but serves different purposes. For example, consider two pieces of code that calculate a sum by iterating over a collection of items. And elsewhere in the code, we have In both cases, we iterate over a collection and calculate a total. You might be tempted to introduce a helper function, but the two calculations are very different. After a few iterations, these two pieces of code might evolve in different directions: In contrast, the shipping cost calculation might look like this: Had we applied “don’t repeat yourself” too early, we would have lost the context and specific requirements of each calculation. DRY Can Introduce Complexity The DRY principle is misinterpreted as a blanket rule to avoid any duplication at all costs, which can lead to complexity. When you try to avoid repetition by introducing abstractions, you have to deal with all the edge cases in a place far away from the actual business logic. You end up adding redundant checks and conditions to the abstraction, just to make sure it works in all cases. Later on, you might forget the reasoning behind those checks, but you keep them around “just in case” because you don’t want to break any callers. The result is dead code that adds complexity to the codebase; all because you wanted to avoid repeating yourself. The common wisdom is that if you repeat yourself, you have to fix the same bug in multiple places. But the assumption is that the bug exists in all copies. In reality, each copy might have evolved in different ways, and the bug might only exist in one of them. When you create a shared abstraction, a bug in that abstraction breaks every caller, breaking multiple features at once. With duplicated code, a bug is isolated to just one specific use case. Clean Up Afterwards Knowing that you didn’t break anything in a shared abstraction is much harder than checking a single copy of the code. Of course, if you have a lot of copies, there is a risk of forgetting to fix all of them. The key to making this work is to clean up afterwards. This can happen before you commit the code or during a code review. At this stage, you can look at the code you copied and see if it makes sense to keep it as is or if you can see the right abstraction. I try to refactor code once I have a better understanding of the problem, but not earlier. A trick to undo a bad abstraction is to inline the code back into the places where it was used. For a while, you end up “repeating yourself” again in the codebase, but that’s okay. Rethink the problem based on the new information you have. Often you’ll find a better abstraction that fits the problem better. When the abstraction is wrong, the fastest way forward is back. —Sandi Metz, The Wrong Abstraction tl;dr It’s fine to look for the right abstraction, but don’t obsess over it. Don’t be afraid to copy code when it helps you keep momentum and find the right abstraction. It bears repeating: “Repeat yourself.” For some examples, see Ferris working on Rustendo64 or tokiospliff working on a C++ game engine . ↩ This is also how I write prose: I first write a draft and block my inner critic, and then I play the role of the editor/critic and “refactor” the text. This way, I get the best of both worlds: a quick feedback loop which doesn’t block my creativity, and a final product which is more polished and well-structured. Of course, I did not invent this approach. I recommend reading “Shitty first drafts” from Anne Lamott’s book Bird by Bird: Instructions on Writing and Life if you want to learn more about this technique. ↩ This is similar to the OODA loop concept, which stands for “Observe, Orient, Decide, Act.” It was developed by military strategist John Boyd. Fighter pilots use it to wait until the last responsible moment to decide on a course of action, which allows them to make the best decision based on the current situation and available information. ↩ Generic names that don’t convey intent, e.g., instead of Difficult to understand without additional context The abstraction is only used in one or two places Tight coupling to implementation details For some examples, see Ferris working on Rustendo64 or tokiospliff working on a C++ game engine . ↩ This is also how I write prose: I first write a draft and block my inner critic, and then I play the role of the editor/critic and “refactor” the text. This way, I get the best of both worlds: a quick feedback loop which doesn’t block my creativity, and a final product which is more polished and well-structured. Of course, I did not invent this approach. I recommend reading “Shitty first drafts” from Anne Lamott’s book Bird by Bird: Instructions on Writing and Life if you want to learn more about this technique. ↩ This is similar to the OODA loop concept, which stands for “Observe, Orient, Decide, Act.” It was developed by military strategist John Boyd. Fighter pilots use it to wait until the last responsible moment to decide on a course of action, which allows them to make the best decision based on the current situation and available information. ↩

0 views
Matthias Endler 4 months ago

Watching Millionaires

I watched the Champions League final the other day when it struck me: I’m basically watching millionaires all the time. The players are millionaires, the coaches are millionaires, the club owners are millionaires. It’s surreal. This week I watched John Wick Ballerina and, again, there’s Keanu Reeves, who is a millionaire, and Ana de Armas, who is as well. Yesterday I heard about Trump and Musk fighting. They are not millionaires, they are billionaires! As I’m writing this, I’m watching the Rock am Ring live stream, a music festival in Germany. Weezer is playing. These guys are all millionaires. I don’t know what to make of it. It’s a strange realization, but one that feels worth sharing. I could go down the road of how this fixation on elites distracts us from the people nearby, but that’s not quite it. What interests me more is how normalized this has become. Maybe it’s just the power law in action: a few rise to the top, and we amplify them by watching. But most people in every field aren’t millionaires. We just don’t see them. You’re on a tiny blog by a tiny man and if you made it this far, I appreciate you. It looks as if you care about the little stories as well. If you’re anything like me, you’re not only enjoying the little stories, you’re actively seeking them out – but there’s so few of it nowadays. Yes, there are still places where people share their stories, but you need to know where to look. If anything, we all should share more. Write about the little things, the everyday moments, the people you meet, the things you care about. Don’t live anybody else’s life! Rivers Cuomo, Weezer’s lead singer, once wrote: My motivation is much different now than it was then: then I was terribly discontent and dreaming of being a classical composer, a writer, or basically anything that I wasn’t ; now I just want to enjoy my life and do the responsible thing—graduate. That’s from his Letter For Readmission To Harvard (2005) . Nobody forced him to go back to Harvard after so many years. He was a freaking millionaire rock star by then. And yet, he did. He stopped pretending and started living . We don’t have to keep watching other people’s lives. Live your own.

0 views
Matthias Endler 4 months ago

Paolo the Plumber

Paolo was a plumber. People knew him as a reliable and thorough craftsman. He fixed the pipes in his small town and made a good living doing so. One day, his friend Mario told him that he’d bought a plumbing machine. Paolo was intrigued and asked how it worked. “It’s magical!” said Mario. “I show it what’s broken, and it fixes the problem in no time!” Paolo asked if he could watch the machine work. The next day, Paolo and Mario took the machine to a house with a broken pipe. Paolo watched as Mario positioned the machine by the pipe. “Beep boop,” and the machine started working, and quickly. Paolo noticed the machine turned the wrench back and forth instead of steady pressure - something he could adapt for his own work. Within minutes, the pipe was fixed. “Soon no one will need plumbers anymore,” said Mario. “I can already do the work of ten plumbers with this machine!” That night, Paolo couldn’t sleep. He thought about his job and how it might change. He loved being a plumber and helping people. But what if machines really took over? Within a few weeks, Paolo’s phone stopped ringing. People were calling Mario instead because he did quicker, cheaper work. Some of Paolo’s old customers told him he was “old-fashioned” and “out of touch.” In the past, none of his customers had ever complained about his work. He always took time to do things right. He would check every joint, seal every pipe, and make sure everything was perfect before leaving. Sometimes he noticed other problems that needed fixing and he would offer to fix those too. Then one day, he got a call from an old customer. It was an emergency. The pipes in the restaurant were leaking and they needed help fast. Paolo rushed over and found a mess. He got to work and fixed the problem. “We just got it fixed the other day!” When Paolo asked who did the work, the owner said it was Mario. From that day on, more people called Paolo. They all had problems after working with Mario and the machine. Paolo kept finding the same mistakes: pipes not properly sealed, joints not aligned correctly, leaks temporarily fixed with instant glue. Sometimes the machine would add extra parts: pipes that ended nowhere, valves that didn’t connect to anything. Paolo recognized these as signs of the machine at work. Paolo called Mario and told him what he’d found. Mario knew about the issues: “I told it to fix it, but it didn’t work right. Even when I asked multiple times and was very polite.” And worse: “One time I looked away for a moment and the machine started remodeling the bathroom! It added a new sink that wasn’t there before.” Paolo asked why he didn’t just fix it himself. “I can’t,” Mario said. “I don’t know how to do it without the machine.” Mario had been a reputable plumber before he got the machine. Now he was relying on a machine that didn’t always work. Worse, Mario didn’t own the machine but rented it from a company far away. The rent was cheap in the beginning, but now it was getting more expensive. Paolo realized that Mario wasn’t the only one. Many plumbers were using machines now, and new plumbers were learning machines instead of tools. It wasn’t just plumbers—electricians, carpenters, other tradespeople were all relying on machines. The machines caused problems, but the company promised they would fix everything and get better with time. They kept updating the machines and gave them fancy names, but the problems remained. Paolo just kept working. He fixed what the machines broke. His customers called him back for more work. Soon his phone was ringing like before. A while later, a salesperson came to town with a new machine. Paolo heard Mario talking to him at the coffee shop.

0 views
Matthias Endler 4 months ago

Reinvent the Wheel

One of the most harmful pieces of advice is to not reinvent the wheel. It usually comes from a good place, but is typically given by two groups of people: Either way, both positions lead to a climate where curiosity and exploration gets discouraged. I’m glad that some people didn’t follow that advice; we owe them many of the conveniences of modern life. Even on a surface level, the advice is bad: We have much better wheels today than 4500–3300 BCE when the first wheel was invented. It was also crucially important that wheels got reinvented throughout civilizations and cultures. Note: When I say “wheel” throughout this post, please replace it with whatever tool, protocol, service, technology, or other invention you’re personally interested in. Inventing Wheels Is Learning “What I cannot create, I do not understand” – Richard Feynman , Physicist and Nobel Prize Winner To really understand something on a fundamental level, you have to be able to implement a toy version first. It doesn’t matter if it’s any good; you can throw it away later. In Computer Science, for example, there are many concepts that are commonly assumed to be beyond the abilities of mere mortals: protocols, cryptography, and web servers come to mind. More people should know how these things work. And therefore I think people should not be afraid to recreate them. Everything Is A Rabbit Hole Too often, fundamental things are taken for granted. For example strings or paths are super complicated concepts in programming. It’s a great exercise to implement a string or a path library yourself if you’re interested in how they work. Even if nobody ends up using your work, I bet you’ll learn a lot. For example: On the last point, everything is a tradeoff and there are dozens, sometimes hundreds of footguns with every toy problem. Along the way, you will have to make decisions about correctness, simplicity, functionality, scalability, performance, resource usage, portability, and so on. Your solution can be great in some of these things, but not all of them and not for all users. That also implies that existing solutions have flaws and might not be designed to solve your particular problem; no matter how well-established the solution is. Going down rabbit holes is fun in its own way, but there is one other benefit: It is one of the few ways to level up as an engineer… but only if you don’t give up before you end up with a working version of what you tried to explore. If you jump between projects too often, you will learn nothing. Reasons for Reinventing the Wheel There are great reasons to reinvent the wheel: Who knows? The wheel you come up with might not be the best use for a car, but maybe for a… skateboard or a bike? Or you fail building a nicer wheel, but you come up with a better way to test wheels along the way. Heck, your wheel might not even be meant for transportation at all! It might be a potter’s wheel, “a machine used in the shaping (known as throwing) of clay into round ceramic ware” according to Wikipedia . You might end up building a totally different kind of wheel like a steering wheel or a flywheel. We need more people who think outside the box. Reuse vs Reinvent Of course, don’t disregard the works of others – study their work and reuse where you see fit. Don’t reinvent the wheel out of distrust or ignorance of the work of others. On the other side, if you never tried to put your knowledge to the test, how would you ever learn enough about your field to advance it? I observed you can move very quickly by running little experiments. Especially in software engineering, building small prototypes is cheap and quick. Solve your own problem, start small, keep it simple, iterate. So, with all of the above, here’s my advice: Reinvent for insight. Reuse for impact. those who tried to invent a wheel themselves and know how hard it is those who never tried to invent a wheel and blindly follow the advice There is an infinite complexity in everyday things. Building something that even a single other person finds useful is a humbling experience. Humans like you created these abstractions. They are not perfect and you can make different tradeoffs in your own design. Build a better wheel (for some definition of better) Learn how wheels are made Teach others about wheels Learn about the inventors of wheels Be able to change wheels or fix them when they break Learn the tools needed to make wheels along the way Learn a tiny slice of what it means to build a larger system (such as a vehicle) Help someone in need of a very special wheel. Maybe for a wheelchair?

0 views
Matthias Endler 6 months ago

No Matter What

As kids, our parents established a few simple rules that we would all follow, no matter the circumstances. One of them was that we’d always have dinner together in the evening, typically around 6pm. In almost two decades, they never broke that rule. We had dinner on 9/11 and when mom was at the hospital. It’s not always easy. There’s a nice thing that happens when you have such a golden rule: it has ripple effects. Since we had dinner together every evening, we would always have time to talk about the day. Problems would be uncovered earlier. We would know about each other’s appointments for the next day. It provided structure throughout the rest of the day. It put things into perspective. It grounded us. As a kid, it sounded like one of those “stupid” rules only grown-ups would come up with. And in fact, my parents knew that it was stupid. They did it anyway. As a kid, that made their life look extremely dull and boring. I remember pitying my dad once for being such a slave to society. Yet, they persisted because without it, things would fall apart. Skipping dinner is about way more than skipping dinner. These Rules Are Simple, But Not Easy It’s a simple rule with little room for interpretation. However, it’s not easy: there are times when you have to drop something else to make dinner at 6 work. That’s when the rule counts the most! That’s what makes or breaks it. Following the rule 90% of the time is much easier than following it 100% of the time. You have to make sacrifices. You have to say no sometimes. That’s the price it takes to stick to the rule. Yes, such rules “sound” stupid, but there’s a deeper, almost stoic realization to it: Life is complicated and will throw obstacles in your way. But if you really want to make progress, you have to find a way. If nothing else helps, make up a stupid rule; and the harder you struggle, the more specific the rule should be. Dinner. Every day. At 6 o’clock. Only now am I discovering this for myself. In 2019, I mentioned to my friend Abu that I felt bad for not doing any sports. It’s not that I didn’t try, it’s just that nothing lasted for long. He suggested going for a run together on Tuesdays – no matter what. I thought that was ridiculous. I told him that it couldn’t possibly work. Why Tuesdays of all days!? It felt so random. In my mind, I started negotiating. But there’s no point in negotiating with irrationality. Fast forward 5 years, and I still run every Tuesday. I actually suck at running. My pace isn’t fast. The distance isn’t far, but it’s a solid effort. Time was made. It worked out. Again, it had positive rippling effects: I ran on Crete in Greece and Sardinia in Italy. Different people joined me on my runs. If Tuesday finds me elsewhere, my running shoes come along. Now, did I always manage to run on a Tuesday? No. It’s not easy! But I always gave it a solid attempt and I can remember each time I didn’t run. Since Abu and I run together a lot, we would talk about our week. If we didn’t make up that rule, we would never have started to know each other on such a deep level. Some people won’t understand when you tell them that you have to do a thing “no matter what.” Instead of telling them I have to go for a run, I say I’m busy that evening. Nobody ever asks any questions. Isn’t this just a habit? With “no matter what” there can be serious consequences. If you have to take care of a loved one, you can’t skip a day. Or if you’re an Air Traffic Controller, failure is not an option. My stakes are not as high, but I take them very seriously. “No matter what” rules aren’t habits, at least not in the beginning. They can, however, turn into super strong habits with time. I found that the best way to implement a “NMW Rule” is to do it on the spot. When my dentist asked me if I floss every day (I didn’t), I made the decision to start right then and there and never skip a day. Another good way to get started is to take on some lightweight responsibility. For example, I recommend getting plants. Then you have to water them – no matter what. If the plant dries out, you broke the rule; simple as that. The great thing is that the watering interval is usually pretty low, so there’s time to get used to it (but getting used to it you must). If it works, you’ll enjoy the feeling of continuity. It’s like a chain of good deeds. A new habit is born. In the past, I never had any plants. Now our apartment is full of them. I love the companionship and the continuity. What’s your “NMW”? If you already have a “no matter what” rule, you have my deepest respect. If not, whether you want to write that book, run that marathon, or just save a few bucks each month, make it work – no matter what. Bad grade at school? Dinner at 6. Played computer games all afternoon and lost track of time? Dinner at 6. No matter how bad your day was, dinner is always waiting for you.

0 views
Matthias Endler 6 months ago

The Best Programmers I Know

I have met a lot of developers in my life. Lately, I asked myself: “What does it take to be one of the best? What do they all have in common?” In the hope that this will be an inspiration to someone out there, I wrote down the traits I observed in the most exceptional people in our craft. I wish I had that list when I was starting out. Had I followed this path, it would have saved me a lot of time. Read the Reference If there was one thing that I should have done as a young programmer, it would have been to read the reference of the thing I was using. I.e. read the Apache Webserver Documentation , the Python Standard Library , or the TOML spec . Don’t go to Stack Overflow, don’t ask the LLM, don’t guess , just go straight to the source . Oftentimes, it’s surprisingly accessible and well-written. Know Your Tools Really Well Great devs understand the technologies they use on a fundamental level . It’s one thing to be able to use a tool and a whole other thing to truly grok (understand) it. A mere user will fumble around, get confused easily, hold it wrong and not optimize the config. An expert goes in (after reading the reference!) and sits down to write a config for the tool of which they understand every single line and can explain it to a colleague. That leaves no room for doubt! To know a tool well, you have to know: For example, if you are a backend engineer and you make heavy use of Kafka, I expect you to know a lot about Kafka – not just things you read on Reddit. At least that’s what I expect if you want to be one of the best engineers. Read The Error Message As in Really Read the Error Message and Try to Understand What’s Written . Turns out, if you just sit and meditate about the error message, it starts to speak to you. The best engineers can infer a ton of information from very little context. Just by reading the error message, you can fix most of the problems on your own. It also feels like a superpower if you help someone who doesn’t have that skill. Like “reading from a cup” or so. Break Down Problems Everyone gets stuck at times. The best know how to get unstuck. They simplify problems until they become digestible. That’s a hard skill to learn and requires a ton of experience. Alternatively, you just have awesome problem-solving skills, e.g., you’re clever. If not, you can train it, but there is no way around breaking down hard problems. There are problems in this world that are too hard to solve at once for anyone involved. If you work as a professional developer, that is the bulk of the work you get paid to do: breaking down problems. If you do it right, it will feel like cheating: you just solve simple problems until you’re done. Don’t Be Afraid To Get Your Hands Dirty The best devs I know read a lot of code and they are not afraid to touch it. They never say “that’s not for me” or “I can’t help you here.” Instead, they just start and learn. Code is just code . They can just pick up any skill that is required with time and effort. Before you know it, they become the go-to person in the team for whatever they touched. Mostly because they were the only ones who were not afraid to touch it in the first place. Always Help Others A related point. Great engineers are in high demand and are always busy, but they always try to help. That’s because they are naturally curious and their supportive mind is what made them great engineers in the first place. It’s a sheer joy to have them on your team, because they are problem solvers. Write Most awesome engineers are well-spoken and happy to share knowledge. The best have some outlet for their thoughts: blogs, talks, open source, or a combination of those. I think there is a strong correlation between writing skills and programming. All the best engineers I know have good command over at least one human language – often more. Mastering the way you write is mastering the way you think and vice versa. A person’s writing style says so much about the way they think. If it’s confusing and lacks structure, their coding style will be too. If it’s concise, educational, well-structured, and witty at times, their code will be too. Excellent programmers find joy in playing with words. Never Stop Learning Some of the best devs I know are 60+ years old. They can run circles around me. Part of the reason is that they keep learning. If there is a new tool they haven’t tried or a language they like, they will learn it. This way, they always stay on top of things without much effort. That is not to be taken for granted: a lot of people stop learning really quickly after they graduate from University or start in their first job. They get stuck thinking that what they got taught in school is the “right” way to do things. Everything new is bad and not worth their time. So there are 25-year-olds who are “mentally retired” and 68-year-olds who are still fresh in their mind. I try to one day belong to the latter group. Somewhat related, the best engineers don’t follow trends, but they will always carefully evaluate the benefits of new technology. If they dismiss it, they can tell you exactly why , when the technology would be a good choice, and what the alternatives are. Status Doesn’t Matter The best devs talk to principal engineers and junior devs alike. There is no hierarchy. They try to learn from everyone, young and old. The newcomers often aren’t entrenched in office politics yet and still have a fresh mind. They don’t know why things are hard and so they propose creative solutions. Maybe the obstacles from the past are no more, which makes these people a great source of inspiration. Build a Reputation You can be a solid engineer if you do good work, but you can only be one of the best if you’re known for your good work; at least within a (larger) organization. There are many ways to build a reputation for yourself: Why do I think it is important to be known for your work? All of the above are ways to extend your radius of impact in the community. Famous developers impact way more people than non-famous developers. There’s only so much code you can write. If you want to “scale” your impact, you have to become a thought leader. Building a reputation is a long-term goal. It doesn’t happen overnight, nor does it have to. And it won’t happen by accident. You show up every day and do the work. Over time, the work will speak for itself. More people will trust you and your work and they will want to work with you. You will work on more prestigious projects and the circle will grow. I once heard about this idea that your latest work should overshadow everything you did before. That’s a good sign that you are on the right track. Have Patience You need patience with computers and humans. Especially with yourself. Not everything will work right away and people take time to learn. It’s not that people around you are stupid; they just have incomplete information. Without patience, it will feel like the world is against you and everyone around you is just incompetent. That’s a miserable place to be. You’re too clever for your own good. To be one of the best, you need an incredible amount of patience, focus, and dedication. You can’t afford to get distracted easily if you want to solve hard problems. You have to return to the keyboard to get over it. You have to put in the work to push a project over the finishing line. And if you can do so while not being an arrogant prick, that’s even better. That’s what separates the best from the rest. Never Blame the Computer Most developers blame the software, other people, their dog, or the weather for flaky, seemingly “random” bugs. The best devs don’t. No matter how erratic or mischievous the behavior of a computer seems, there is always a logical explanation: you just haven’t found it yet! The best keep digging until they find the reason. They might not find the reason immediately, they might never find it, but they never blame external circumstances. With this attitude, they are able to make incredible progress and learn things that others fail to. When you mistake bugs for incomprehensible magic, magic is what it will always be. Don’t Be Afraid to Say “I Don’t Know” In job interviews, I pushed candidates hard to at least say “I don’t know” once. The reason was not that I wanted to look superior (although some people certainly had that impression). No, I wanted to reach the boundary of their knowledge. I wanted to stand with them on the edge of what they thought they knew. Often, I myself didn’t know the answer. And to be honest, I didn’t care about the answer. What I cared about was when people bullshitted their way through the interview. The best candidates said “Huh, I don’t know, but that’s an interesting question! If I had to guess, I would say…” and then they would proceed to deduce the answer. That’s a sign that you have the potential to be a great engineer. If you are afraid to say “I don’t know”, you come from a position of hubris or defensiveness. I don’t like bullshitters on my team. Better to acknowledge that you can’t know everything. Once you accept that, you allow yourself to learn. “The important thing is that you don’t stop asking questions,” said Albert Einstein. Don’t Guess “In the Face of Ambiguity, Refuse the Temptation to Guess” That is one of my favorite rules in PEP 20 – The Zen of Python . And it’s so, so tempting to guess! I’ve been there many times and I failed with my own ambition. When you guess, two things can happen: Again, resist the urge to guess. Ask questions, read the reference, use a debugger, be thorough. Do what it takes to get the answer. Keep It Simple Clever engineers write clever code. Exceptional engineers write simple code. That’s because most of the time, simple is enough. And simple is more maintainable than complex. Sometimes it does matter to get things right, but knowing the difference is what separates the best from the rest. You can achieve a whole lot by keeping it simple. Focus on the right things. Final Thoughts The above is not a checklist or a competition; and great engineering is not a race. Just don’t trick yourself into thinking that you can skip the hard work. There is no shortcut. Good luck with your journey. its history: who created it? Why? To solve which problem? its present: who maintains it? Where do they work? On what? its limitations: when is the tool not a good fit? When does it break? its ecosystem: what libraries exist? Who uses it? What plugins? You built and shipped a critical service for a (larger) org. You wrote a famous tool You contribute to a popular open source tool You wrote a book that is often mentioned In the best case you’re wrong and your incorrect assumptions lead to a bug. In the worst case you are right… and you’ll never stop and second guess yourself. You build up your mental model based on the wrong assumptions. This can haunt you for a long time.

1 views
Matthias Endler 1 years ago

So You Want to Start a (Tech) Podcast

For the past year, I’ve been hosting the Rust in Production , a podcast about companies who shape the future of infrastructure. This journey has taught me a lot about what it takes to create and maintain a successful podcast. Well, success is always relative; at the moment we have around 5k regular (monthly) listeners. Maybe not a ton of people, but it puts us comfortably into the top 5% of podcasts – at least by some statistics . Whether you’re considering starting your own podcast or just curious about the process, I hope my experiences can offer some valuable insights. The ‘Rust in Production’ podcast cover Do Your Research Before you dive into the world of podcasting, take some time to explore the landscape. Think about branding and positioning first . Topic When choosing your topic, make sure it’s something you can easily generate ideas for. Try to come up with at least 10 potential episode ideas before you settle on it. If you’re planning an interview-based podcast, ensure you have a large enough network to secure at least 10 guests. Competition Research your competition. Listen to similar podcasts and note down what you like and dislike about them. This will help you differentiate your podcast from others in the same niche. If a podcast is already covering your topic, that’s not necessarily a bad thing; it just shows there’s an audience for it. However, you need to find a unique angle or a different format to stand out. If you can’t be the first, be the best. Be the funniest, or the most in-depth, or the one with the most interesting guests. Be honest with yourself about what you can offer that others can’t. If you can’t find a unique angle, it might be better to choose a different topic. If you’re not sure, ask your friends or colleagues for their opinion. Podcast Name What’s the title of your podcast? Especially the last few points are often overlooked. You want to make it as easy as possible for people to find your podcast. I’d say don’t be too clever with your podcast name. It should be easy to remember and spell. If you have to explain it, it’s probably too complicated. Also, don’t use special characters or numbers in your podcast name. It makes it harder to remember and type. Don’t pick a too generic name either. Be specific about your niche. So instead of “The JavaScript Podcast,” go for “Refactoring JavaScript” or “React Weekly.” Don’t forget about SEO. Consider what people might search for when looking for content like yours. My podcast is titled “Rust in Production,” which is a commonly searched term. This has helped with discoverability. Another version of that, which could work, is to think about questions that people Google for. E.g. “What is functional programming?” or “How to refactor legacy code?” and then coming up with a podcast name that answers that question. For example, “Functional Programming Explained” or “Refactoring Legacy Code.” Cover Art Your podcast’s cover is equally crucial. It’s the first thing people recognize about your podcast (except for the title) before they decide what to listen to, so it needs to stand out from the crowd. What I did was open my podcast app and look at the grid of covers. The grid of podcast covers in my podcast app I asked myself which ones stood out and why. I also asked a few friends and my partner to do the same. I got some great feedback that way. This visual first impression can make a big difference in attracting new listeners. Length Next, decide on your podcast’s length. Fifteen minutes is great for news content, 30 minutes work well for commutes, and one hour is suitable for deep dives. Anything longer, and listeners might hesitate to commit their time. Plan Your Content Once you’ve done your research, it’s time to plan your content strategy. Having a regular schedule is key - weekly or biweekly episodes work well for many podcasts. Start conservatively; you can always increase frequency later, but underestimating the workload can lead to burnout. I highly recommend buffering content by recording a few episodes before you start publishing. This gives you a cushion and reduces stress, especially when you’re just starting out. Consider a season-based approach. For “Rust in Production,” we do 7-8 episodes and then take a break. This allows for better planning and reduces ongoing pressure. Respect Your Guests If you’re doing an interview-based podcast, treating your guests with respect is paramount. Explain why you want them on your show in the initial email. Keep them informed about the process and be flexible with scheduling. At the start of the recording, explain how things will work and ask if they have any time constraints. Remember, your guests are likely doing this for free. Respect their time and make the experience as smooth as possible for them. Invest in Quality Audio quality can make or break a podcast. Invest in good equipment - get a decent microphone and headphones, and consider ways to improve your room’s acoustics. If you’re interviewing guests remotely, consider their equipment too. A pre-call to check their setup can be invaluable, or you might even consider sending them equipment if you want consistent quality across episodes. Always remind guests to stay close to the mic. It’s a small detail that can make a big difference in audio quality. On two occasions, I had guests who had their condenser mic backwards, and that sounds pretty dull. You get better at picking up on these things the more you record. It helps to know which way the mic should be facing (usually the logo on the mic and the volume knob should be facing you). Both guests were very grateful for the tip and the audio quality improved significantly. Production Tips One of the best decisions I made was not to edit the podcast myself. I’m incredibly thankful that Simon Brüggen agreed to do the editing for “Rust in Production.” It would have been an enormous amount of work on top of finding guests, recording, and hosting. It also helps that Simon is a Rust developer and understands the content. He can give tips on how to improve the content from a technical perspective. For recording, tools like Zencastr , Riverside , or Descript are excellent. They capture audio on both sides, giving you uncompressed files to work with. Auphonic is great for cleaning up audio, removing filler words, and creating transcripts. When it comes to hosting, I use Letscast . They’re not the cheapest option, but their customer service is top notch and the website is fast and not bloated. Develop Your Style As you progress, you’ll naturally develop your own podcasting style. For me, I prefer to let guests do most of the talking, only interjecting occasionally with questions or comments. The motto is “say less, ask more.” It’s a good rule of thumb for interviews. It’s not about you, it’s about the guest. Let them shine. In pursuit of asking better questions, I wrote an essay on how to ask better questions . I’ve also found that taking notes during recording helps me ask better follow-up questions. Don’t be afraid to encourage your guests when they make good points. A nod, a smile, or a thumbs up can go a long way in making them feel comfortable and valued. Don’t Sweat the Small Stuff While it’s tempting to obsess over metrics, try not to focus on them too much. Instead, concentrate on producing content you’d enjoy consuming yourself. Be passionate about your topic and create your podcast as if no one is listening - ironically, this often leads to the most engaging content. Starting a podcast is a lot of work, but it’s incredibly rewarding. The podcast space isn’t oversaturated yet - it reminds me of the golden age of YouTube a few years ago. Podcasting is becoming more professional now, but there’s still plenty of room for new formats and perspectives. Remember: it’s okay to start small and grow. You’ll learn and improve with each new episode. The most important thing is to enjoy the process and share your personality with the world. If you’re interested in Rust, consider listening to the Rust in Production podcast. I’d love to hear what you think! Is it catchy and easy to remember? Does it convey what your podcast is about? Is the domain name available? Are the social media handles available? Is there a simple abbreviation you can use for hashtags or mentions?

0 views
Matthias Endler 1 years ago

Follow the Hackers

Want to see tomorrow’s important technologies? Watch what hackers are passionate about today. Defining “Hacker” I’m using the term “hacker” in the spirit of the Hacker Ethic, as described by authors like Steven Levy and Pekka Himanen . In this context, a hacker is someone who: These folks are a small subset of the population, but they have some traits that make them excellent predictors of the future: Catalysts For Success And Red Flags Of course, not every hyped technology makes it big. Remember NFTs or Web3? The key difference? Real hackers were never passionate about these technologies - ordinary people were. Another red flag is when the technology’s benefits are hard to explain. If hardcore tech people can’t explain the benefits to you, that’s a bad sign. Look deeper and you’ll find different motivations at work! It’s typically people looking to profit from technology. They brand themselves as Investors, “Serial Entrepreneurs”, and “Thought Leaders”. You’ll find them on LinkedIn, updating their profiles with the latest buzzwords every few months. While a few are legitimate, most are opportunists who couldn’t explain the technology to save their lives. Profit is their only motivation. The hackers? They don’t care what you think about them. They’ve got nothing to sell you. They’re too busy building cool stuff! A question hackers care about is “who owns the platform”? Companies always have an agenda. Pour in your time and effort, and they might lock you out to profit from your work. Hackers don’t like that. Therefore, all the winning ideas I mentioned are open source. If a technology isn’t, that’s a major red flag when evaluating its future potential. It’s not even optional anymore - it’s pretty much mandatory. But there’s another reason why open source is a catalyst for success: Initially, open source projects start as minimally functional versions without user-friendly documentation. They might be tough to set up, but the core idea is there. If people stick with it despite the lack of hand-holding, you know it’s solving a real problem - and that’s a sign of a winning idea. You Still Need Patience You probably know I’m all in on Rust. After all, I make my living as a Rust consultant . It took Rust over a decade of development to gain any real traction in the industry. It’s been a slow but steady climb. It takes time for the public to catch up before a technology hits its stride. For core technologies like programming languages or databases, it often takes a decade or more. That’s simply how long technology needs to mature. That’s why I tell founders to stay slightly conservative when adopting new tech. The industry needs time to catch up, and big companies need specialized tools to integrate new tech into their existing systems. On the other side, investing early in promising technologies is a calculated risk because the writing is on the wall. What Can You Learn From This? Hackers are already living in the future. You can use that to your advantage. Ask 10 hackers what new things they’re really excited about, and you’ll get a good picture of what’s going to be important in a few years. Most business people don’t talk to hackers regularly. That’s a fact you can use to your advantage. If you’re selling to developers ( and you probably shouldn’t ), the key is to really listen to what the hackers are saying and then follow their lead. Follows their passion and seeks self-fulfillment through technology Creates something beneficial for the wider community Values freedom, cooperation, and voluntary work Challenges traditional work ethics with a focus on creativity and sharing They care deeply about their field - programming being just one example They’re passionate about the things they believe in They’d use something even if no one else cared about it They work at the cutting edge, so they need the best tools to do their job They hold strong opinions on what works and what doesn’t, backed by solid evidence They don’t care about investors, quarterly earnings reports, or politics - they purely focus on the technology’s value

0 views
Matthias Endler 1 years ago

Be Simple

Last night I realized that my life is very simple. That’s not by chance, but by conscious effort. Life becomes complex all by itself if you do nothing about it. One day you’ll wake up and you have a mortgage, 10 on-demand subscriptions, 20 insurances, 1000 open browser tabs, a demanding job and a dog. And when you realize it, you wonder how you got there. I keep my life simple because I know my time is limited. Time and health are my best proxies for happiness. Simple Doesn’t Mean Boring Quite the contrary: give me enough time and I find ways to entertain myself. My friends might disagree, but I consider myself to be an introvert. I like to spend time on my own to explore and learn. There hasn’t been a boring moment in a long time. If life was more complex, that would take away my time, but time is the resource I can’t replenish, so I protect it. How? Mostly by saying NO. Great home cinema setup you have there. Thanks for inviting me over! At home, I don’t even have external speakers. You’re planning a trip to the Bahamas? Enjoy! Send me a photo. Regarding technology, that means: Simple Doesn’t Mean Minimalistic My goal is not to have as few possessions as possible – I own a lot – but to lead a simple life. I’ll happily buy things if they make my life simpler. The last big life improvements were a robot vacuum cleaner (four years ago) and an automated cat litter box (two years ago). If I decide to buy something, I make sure it’s the absolute best I can afford. (My rule is actually “don’t buy crap”.) For example, I spent a ridiculous amount on the best laptop I could buy. It’s my daily driver that I spend most of my time with, so it needs to be an absolute workhorse. My work is also compute-intensive, so I saw the purchase as justified. I always pay the price in full. No lease, no monthly payments. I have to use services for work, but I prefer monthly payments over yearly subscriptions, even if they are 30% more expensive. The fact that I can cancel at any time is more important to me. I know that when I buy something, it demands my attention. Maintenance is not fun. Even though I like the idea of owning something, I probably don’t truly own it. That makes me the worst consumer possible. I keep things in my Amazon basket forever . From time to time I look at the items, and when I enjoy seeing them in my basket… I keep them there. The rest, I just delete. This way, I get the “feeling” of owning things without spending any money. Simple Doesn’t Mean Convenient To live with such a person is not easy. We have regular discussions about “investing” money into things that I’m skeptical about. It takes me ages to reach a conclusion. Vacation planning is definitely one of my weaknesses. I am very well aware that my approach is not perfect at times. I am okay with making these sacrifices for protecting my time and therefore my happiness. Recently, I got a few emails from people telling me that my newsletter subscription is broken. I’m aware of that. My newsletter provider shut down. I won’t fix it. It turns out that people find other ways to follow me; either on Mastodon or via RSS. I also don’t have a comment section – Reddit or HN work just fine. Even though there are a few folks on my old newsletter list, I never got around to sending many emails. I don’t particularly enjoy writing a newsletter, so it might be best that it finally broke. I will probably remove the signup box. It would be nice to have it “just work”, but the next best thing is to not have it at all. Simple Means Letting Go Perhaps another way to explain it is the midwit theme: I try to stay on the left side of this curve as much as I can. I’m aware that there are “smarter” ways to do things, but I don’t want to dedicate time to learning about them. I only dedicate time to things that matter to me and that I want to go really deep into. The meme shows simple approaches on both ends, with a complicated phase in between. Getting to the right side of the spectrum takes lots of effort, and I’ve only made that journey a few times in my life. For the rest, knowing there’s an awkward complicated phase in between keeps me happily on the simple side. It’s fine. Simple Means Focused Greatness comes from dedicating time to the things that matter. The most productive people I know are focused. Yes, there’s a creative process and they allow themselves to be creative, but they do so in a very constrained environment: their office. While others chase trends, they do the thing they’re always doing. They put in the hours. It’s way easier to be focused when life is simple. When there’s no room for distractions and complexity. I find that constraints help as well. Technology is one major source of distraction. Some of the best stories were written with a typewriter. In itself, it’s a very limited environment, but it takes away all the distractions and lets you focus on the task at hand. I find that inspiring, liberating. That’s why I like constraints. When I give presentations, I wonder what I’d write if I could only have 5 slides with 5 words each, or I could only use two colors, or only show images. It keeps me focused on the message. It’s simple. Simple is beautiful. Simple makes me happy. No streaming subscriptions. No Disney+, no Netflix. I rarely watch TV anyway. No gym memberships. Just run in the park. No Instagram or TikTok, but part of that is getting older. My shoes are 6 years old. So is my wardrobe. No meetings if possible. I’m the guy who sits at his desk for 8 hours straight, only getting up for bathroom breaks twice. No property; I’m a happy tenant. No commute; I work remotely. Even though I’m a programmer, I only have a single screen. I evaluate tools, but I keep the number of tools limited. My editor doesn’t have a debugger. No Notion or Obsidian if a text file + git is enough. I limit the number of browser tabs with an extension .

0 views
Matthias Endler 1 years ago

What to Write

People sometimes ask me how I come up with things to write. To me, it’s the same as asking how I come up with things to say. There’s always something to say. It might not be novel or interesting to most, but it’s important to me and hopefully to someone else. What people actually want to know is how to come up with something interesting to write. But why should that matter? What if people don’t find it interesting? Was it a waste of time? Why Write? There’s this funny thing which happens when you write for a while: you forget what excited you about writing in the first place. Instead, you find yourself chasing trends, trying to get more views, and build a following. Even if you’re aware that this is happening, it’s hard to stop. Your inner monologue tells you that what you’re writing isn’t good enough or that your readers won’t like it. Writing becomes a chore. Eventually, you stop writing. Somewhat tautologically, people come here exactly for one reason: to read what I write. If I make it about them, I have to guess what they want to hear, which kills the joy in writing, and also, in reading, as the content becomes predictable. Interesting Doesn’t Mean Novel . Just because someone else wrote about the same topic doesn’t mean it’s off-limits. There are a million love songs to disprove that. As it turns out, while they all revolve around the same topic, they’re all unique. They are personal , which is what makes them different. Some of these songs I like because I can relate to them. To me, that’s what makes them interesting: it’s the same story but told in a different way – a personal way. And that personal makes it new and that new makes it interesting . If You Take Away the Personal, You Take Away the Interesting Writing is a lot like that. I get to learn about how other people feel and how they think. It’s mostly an experience; shaped into words. It’s beautiful to think how writing is such a simple way to learn from the experiences of others. And how, with just a few words, you can emotionally connect with a stranger. It’s a very human experience. Often, what you leave out is more important than what you keep; the reader fills in the blanks. Eventually, a story starts a life of its own; when it gets shared; when it gets retold. It’s no longer the author’s story but the reader’s. It becomes part of lore. Who wrote it isn’t that important. I can’t tell who reads this and why should I care? Instead of trying to make other people enjoy my writing, I want to connect with people who like the same topics. Big difference. Knowing That Is Liberating It gives me confidence that I will never run out of things to write. At least not as long as I remember why I write. It’s liberating because I don’t have to chase the new . Instead, whatever it turns out to be is enough. At times, I’m as clueless as the reader to see where this leads me. Maybe someone else will find joy in it, maybe not. It doesn’t matter. What matters is what you think matters, and that’s what you should write about.

0 views
Matthias Endler 1 years ago

Move Slow and Fix Things

Growing up as a kid in rural Bavaria, I always dreamed of moving to the US to run a startup. Many kids in my generation shared that dream. To me, it felt like the only way to combine my two greatest passions: writing code and building things. As I got older, I became disillusioned with the narrative surrounding Silicon Valley. The hockey stick growth, the VC money, the “get rich quick” mentality – it was all one big illusion. For a long time, I couldn’t put my finger on what exactly bothered me about it. Part of what made me increasingly uncomfortable was the glorification of hustle culture – the idea that you have to work yourself to the bone to make it big against all odds. The other part was the “winner takes all” mentality and the mindset that you have to “move fast and break things” to succeed. I don’t believe that has to be the case. As it turns out, I’ve always been drawn to the exact opposite : sustainable growth, robust solutions, and a long-term mindset. That’s why I’ve been contributing to open source for 15 years , why I only run small, bootstrapped businesses or non-profits , and why I focus on writing and knowledge sharing. Paul Graham and his VC buddies would have you believe that your ultimate goal as a founder should be to build a unicorn. But when I look at the Ubers, Facebooks, and Googles of this world, I see greed, gatekeeping, systemic exploitation, user tracking, excessive resource consumption, and lawsuits against competitors. These companies will do anything in their power to stay on top – even if it means bending the law or finding legal loopholes. What kind of role model is that? The Other Side Who’s on the “other side”? It’s the humble minority building small but meaningful things. These people advocate for privacy, develop civic tech, try to live within their means, move deliberately, and fix what’s broken. They fly under the radar because their success isn’t measured in dollars, and they lack big marketing budgets. Instead, they focus on their product, doing a lot with very little. I find that far more inspiring. It’s incredibly rewarding to build something people love that can provide you with a comfortable living. There’s no need to risk it all, drop out of college, work insane hours, and leave a trail of destruction in your wake. You can build something small and useful instead, without a venture capitalist breathing down your neck. It’s still hard work, but you’re leaving the campsite a little better than you found it. Note that moving slowly doesn’t mean you can’t make quick decisions. It’s just that the execution should be deliberate. Don’t wreak havoc along the way. Because the time to fix what you might break rarely comes. VCs are Not Your Friends In “Why to Not Not Start a Startup” , Paul Graham writes: So, paradoxically, if you’re too inexperienced to start a startup, what you should do is start one. That’s a way more efficient cure for inexperience than a normal job. In fact, getting a normal job may actually make you less able to start a startup, by turning you into a tame animal who thinks he needs an office to work in and a product manager to tell him what software to write. Let me be blunt: that’s nonsense. It paints a black and white picture of the world that simply doesn’t exist. You don’t have to choose between starting a startup and working a soul-crushing job as a “tame animal” in a cubicle. There’s a whole spectrum of possibilities in between! For instance, you could work for yourself or with a small team, making use of your creativity and coming up with your own ideas. Paul wants you to start a startup because he wants to fund you and profit from your hard work. His motives are purely egoistical. If you happen to hit the startup jackpot, Paul gets even richer and you might become wealthy too. If you don’t, you’re left with nothing while Paul, already rich, gets to write an essay about your failure. That’s a whole lot of risk for very little upside. You might wonder why I’m picking on Paul Graham so much. It’s because I once looked up to him and valued his essays. He represents a worldview I used to believe in, but now consider harmful. Most of his essays seem true on the surface, but dig deeper and you’ll find his claims are based on a narrow worldview and rarely supported by evidence. Misleading young, impressionable people is dangerous. Startup founders bear all the downside risk, while venture capitalists are well-insulated from failure. VCs spread their bets across numerous startups, ensuring they profit regardless of individual outcomes. For you, the founder, it’s an all-or-nothing gamble with your time, energy, and often your financial stability. Is All VC Money Bad? Of course not. But I’d argue it’s becoming less and less relevant in today’s world. Take building a software product, for example. You don’t need a fortune to get started anymore. There are website builders, cloud hosting solutions, and open source software at your fingertips. Why take on VC money when you’re just starting out? Some might argue that you profit from valuable networking opportunities and business advice along with the funding. But most of that information is freely available online these days. There’s an abundance of podcasts, videos, and books on the subject if you’re willing to learn. It’s trickier, of course, if you’re building a physical product. But even that has become much easier in recent years. Could you sell a 3D printed prototype before scaling up production? Or launch a Kickstarter campaign to fund your first batch of products? There are now print-on-demand services for t-shirts, mugs, posters, and books. Plus, there are plenty of brick-and-mortar stores you could approach with your business idea if you’re looking to collaborate. Let’s say you do become wildly successful and urgently need capital to scale. Maybe then VC money is one way to go. Or you could take out a loan. Either way, remember that money always comes with strings attached. Funding might force you to do things you’re not comfortable with, like compromising your users’ privacy or your own values. And even if not, you’ll constantly be pressured to find new avenues for growth. Wouldn’t it be nicer to focus on making your product better instead? That’s often far more rewarding. But often, if you spend enough time thinking through a problem, you might find a way to prove your concept at a smaller scale. There Is No Infinite Growth Ask yourself: What truly motivates you? Is it power, money, or fame? If so, there are more meaningful things in life. Your self-worth isn’t tied to building a unicorn. I don’t know who needs to hear this, but it’s perfectly fine to be 23 and not be a millionaire founder. If you’re a high school or college student dreaming of running a startup, know that there’s another path. Don’t sell out your moral compass for a quick buck. You don’t have to jump on the AI bandwagon just because it’s the flavor of the month. At least 144 out of 251 companies from the YC W24 batch are building products with “AI”. That’s 57% of the batch. How many of them are actually doing something meaningful with it? How many will still be around in 5 years? What lasting value do these companies bring to the world? We’re accumulating a massive amount of tech debt while rewarding short-term thinking and profit over sustainability. Sure, Paul will benefit if one of them hits it big. You can read all about it in his next essay. But maybe there’s another way. Maybe it’s okay to have a small business with a loyal user base that pays the bills. Maybe you don’t need to grow exponentially. Maybe you can move slow and fix things instead.

0 views
Matthias Endler 1 years ago

Asking Better Questions

Recently, I realized that I mostly get paid to ask questions. The curious thing is that, like most people in a similar position, I never had any formal training in asking questions! I basically just wing it and try to get better over time. That got me thinking: What makes a good question? The other day, I reflected on that. Here’s what I came up with. 1. Good Questions Are Open-ended Recently, we did a survey about our podcast, and someone mentioned that some questions I asked the guests were “either-or” type of questions. Q: “Do you prefer dogs or cats?” A: “Dogs.” Ouch, not a very interesting conversation! A better one might have been “What’s your favorite pet?”. It allows for surprising answers. Q: “What’s your favorite pet?” A: “Tarantula!” We have to ask ourselves what we want out of the answer, which leads me to my second observation: 2. Never Ask A Question If You Don’t Care About The Answer Or to rephrase it, “Only ask things you care about.” If you don’t care about the other person’s answer, why even ask? Ask something else you care about instead! For example, when you ask someone if they prefer dogs or cats, what are you really asking? Dig deeper into “why” you’re asking the question. If it’s one of the former two questions, get straight to the point: Q: “Are you a nice person?” A: … Q: “How do you manage having a pet if you have to work all day?” A: … It will lead to better answers. If it’s about your own agenda and you’re just looking for someone to give you the answer you’re hoping for ( confirmation bias ): don’t. Again, allow them to surprise you! Who knows? You might learn a thing or two about your preconceptions. Which leads to… 3. Good Questions Reveal Something About The Person Who Answers; Bad Questions About The Person Who Asks It’s very easy to slip into a role where you’re framing people, and that lets your bias speak more about you than the person you’re talking to. Be conscious about that so that you can avoid it when it happens. Q: “Why do you love X?” A: “I don’t.” Q: “Tell me something you truly believe about X” A: “I believe that…” The more unique the answer, the more you learn about the person. So I would even say that a good question is one that reveals something unique about the person who answers. Q: “As an expert in X, who has been in the field for 20 years, what is one thing that people always get wrong about X?” A: “People always think that X is about Y, but it’s really about Z.” 4. Good Questions Are Stacked On Top Of Each Other Do you know the Five Whys technique? It’s simple: Ask “why” five times to get to the root of the issue. Q: Are you happy with your job? A: No. Q: Why? A: It drains my energy. Q: Why? A: I have to do boring things. Q: Why? A: My boss thinks they must be done by someone . Q: Why? A: No one got around to automating them. Q: Why? A: We don’t have the skills to automate boring tasks. Aha! If they learn how to automate things, this might lead to better job happiness! That’s insightful. What’s nice is that it was a purely mechanical process. With every step, we dug deeper into the underlying question. At some point, the truth revealed itself. I love this technique. Good questions are built on top of each other. The questions themselves don’t have to be complicated. It can actually be the same question asked a few times in a row – even a child could do that. In fact, they do. A lot! This is how they learn about the world around them. As grown-ups, we should not unlearn this technique. “It’s rude to ask that.” “Don’t pry.” “Don’t be nosy.” We should relearn it! Ask follow-up questions to get to the root of things. But also! Hold the other person accountable. Q: “How can we fix poverty?” A: “I will do everything in my power to fix it.” Q: “But how?” A: “I will try countermeasures which were discussed with…” Q: “Can you give me a concrete example?” A: “…” When someone answers your question, ask yourself if the answer really covered everything you wanted to know. Often, the most interesting pieces are omitted. Sometimes on purpose. But this is the most revealing part, the part at the verge of uncertainty and insecurity and you have to uncover it to get to the heart of the matter! If you don’t do this, conversations stay shallow. Speaking of which… 5. Good Questions Run Deep “Why is the sky blue?” “How do people fall in love?” “Are you happy?” These are simple questions! But they touch on the very foundation of what we know, our perception of the world, and ourselves. The simpler the question, the deeper the answer. Answering with “I don’t know” is totally fine. The important part is to stay curious and to be genuinely interested in the answer. 6. Let The Winners Run And Cut Your Losses Short Sometimes, no matter what you try, there’s just nothing in a conversation. You might have ended up in that weird space where people are simply out of their depth and you turn circles. Cut the cord. Just acknowledge it and move on. Trained conversationalists do it all the time without anyone noticing. The conversation gets boring, so they just move on to the next topic. There doesn’t even have to be a transition. Q: “So, what do you do for a living?” A: “I’m a plumber.” Q: “Oh, interesting. So, what are your plans if you win?” A: … Once you notice that, you will see it everywhere. We do it all the time in our daily lives, too, for example on the phone. Just cut your losses, move on to the next topic. Similarly, if you notice that you both are really into a topic, just run with it. 7. Give People Space To Think Pauses are powerful. Ask your question and then… wait. Just wait. Don’t fill the silence with your own thoughts or insecurities. Let the question speak for itself. If you’re truly interested in a deeper thought, you need to give people time to unpack it - for you and for themselves. If you’re not willing to wait, you’ll miss out on the best part of the conversation. We are trained to give quick answers. If someone asks you “How’s it going?”, the expected answer is “Good, you?”. People are surprised when I take a moment to answer and give them a truly honest answer, which might be deeply personal. Similarly, let people give you their quick answer first. Then wait. Often, they will stop and follow up with a much more personal answer. Use pauses to your advantage. 8. Obvious Questions Can Be The Best Questions If you look close enough, which question to ask becomes obvious. You’re addressing the elephant in the room! But just because you have an obvious question, that doesn’t make it easy to ask! You might know that the question could hurt. Or that the answer is uncomfortable to handle. And yet, it’s still the right question to ask. What I noticed is that oftentimes multiple people have the same “obvious” question in mind. They are just too afraid to ask. Most people dance around the topic because they want to be polite. They don’t address problems head-on because it’s easier! The result is small talk. Especially if you get paid to ask questions, your job is to ask questions that no one else wants to ask. Often, politics, infighting, and hidden agendas make it very hard for people to break out of their role and ask the obvious question. If you’re not afraid to ask the obvious question, you will look like Houdini. Suddenly, an avalanche of follow-up questions gets unleashed. An honest, constructive conversation emerges. The thing is, just because you don’t ask the uncomfortable question, it doesn’t make the problem go away. In fact, you might make it worse in the long run. It’s easier to get it out of the way and move on! Q: Why are we still working on this? A: Actually, I have no idea. Let’s find something else. Q: Should we split up? A: Yes, I think so. Let’s talk about it. Q: How do you feel after the diagnosis? A: I’m scared. I don’t know what to do. But I’m glad you asked. The truth is hidden in plain sight. If no one dares to ask, these questions stay unanswered. The trick is to accept the answer for what it is. Don’t be mad or angry at people who honestly answer your question. Be mad or angry for not asking sooner. If You Don’t Understand The Answer, Ask Again In the past, I would often gloss over an answer and pretend I understood it. Turns out that it was a bad strategy: In the best case, I would have missed out on a great opportunity to learn something new. In the worst case, I wouldn’t have a good question to follow up with. Funnily, I’m rarely alone with this problem. There’s usually more than one confused person in the room. So don’t be afraid to refine your question to clarify any misunderstandings. Q: “Can you explain that differently?” A: … Q: “Am I correct in understanding that you mean…?” A: … Q: “Can you give me an example?” A: … There’s an old Chinese proverb that goes like this: He who asks a question is a fool for five minutes; he who does not ask a question remains a fool forever. Good Observations Yield Good Questions I noticed that many people who ask great questions have exceptional observation skills. They notice things that others don’t. Q: “Why are you still working here?” A: “I need the money.” Q: “Tough luck. What’s for lunch?” A: … Q: “Why are you still working here?” A: “I need the money.” Q: “I noticed that you have this book on your desk. What’s that about?” A: “Oh, that’s my passion! I’m reading up on sales because I want to start my own business.” Q: “Nice! What is it about sales that you find so interesting?” A: … See how this tiny observation about a book on the desk led to a much deeper conversation? Suddenly, you’re talking about someone’s passion and dreams. You might inspire them to have more conversations with customers during work time to get some practice. If you want to improve your observation skills, come prepared. Learn more about the person you’re talking to. If you come prepared, you’ll have an easier time asking good questions. Context makes good questions obvious. The Best Follow-up To An Answer Is A Question Okay, you got an answer. Now what? Many people follow up with a statement about themselves. “Oh, I also like that!” “Yes, I also did that!” “Let me tell you about my experience!” “You should do this!” This shows that you’re not interested in the other person, only in yourself. Instead, what if you could only follow up with a question? Q: “What’s your favorite sport?” A: “Table tennis.” Q: “How did you get into that?” A: “My dad played it when I was young.” Q: “What’s your favorite memory of playing table tennis with your dad?” A: “We used to play in the basement. It was so much fun!” Q: “What made it so much fun?” A: “I don’t know. It was just the two of us. It was our thing.” Q: “What did you learn from your dad about table tennis?” A: “He taught me how to serve. He was really good at it.” Q: “What’s the most important thing about serving in table tennis?” A: “You have to hit the ball at the right angle. Otherwise, it’s easy to return.” Q: “What’s the most difficult angle to return?” A: “The one that goes straight to the corner. It’s hard to reach.” See how this conversation unfolded? It’s like peeling an onion. You get deeper and deeper into the topic. You learn more about the person. You learn more about the topic. Step by step, you tap into someone else’s hard-earned wisdom. Look at all the things you learned in such a short time! Their favorite sport, their childhood memories, their relationship with their dad, how to serve in table tennis, the most difficult angle to return a serve. If you had followed up with “I like that too,” you would have missed out on all of this and probably never learned about it. All just because we kept asking questions instead of making statements. Think about all the people you know. Who do you like to talk to? I bet it’s the people who ask you questions and listen to your answers instead of talking about themselves all the time. Interestingly, it’s entirely selfish to ask questions. You learn more about the other person than they learn about you. You’re in control of the conversation. Summary I’m still not good at asking questions. I wrote this mostly as practice for myself. Maybe it helps someone else too. Here’s a summary of what I wrote: Don’t be mistaken! Asking good questions is hard work! You have to be present, you have to listen, you have to reflect. It helps to take mental notes while you’re talking to someone. After a while, you will get better at spotting the patterns. Asking good questions is a skill that can be learned and improved upon. Asking more questions can’t hurt along the way. So, how do you ask better questions? As a consultant , advising companies As a podcast host In calls with potential clients Do you wonder if the person is nice ? Do you care about the logistics of owning a pet as a full-time employee? Or do you rather want to hear a certain answer from the other person that happens to fit your narrative? (The obvious correct answer is “cats”.) What is it that only they can say? What is it that they have unique insight into? “Why is the sky blue?” “How do people fall in love?” “Are you happy?” “Why are we still working on this?” “Should we split up?” “How do you feel after the diagnosis?” What are they passionate about? Who’s their role model? What are they doing in their free time? What are they reading? Which projects are they working on? Good Questions Are Open-ended Never Ask A Question If You Don’t Care About The Answer Good Questions Reveal Something About The Person Who Answers; Bad Questions About The Person Who Asks Good Questions Are Stacked On Top Of Each Other Good Questions Run Deep Let The Winners Run And Cut Your Losses Short Give People Space To Think Obvious Questions Can Be The Best Questions If You Don’t Understand The Answer, Ask Again Good Observations Yield Good Questions The Best Follow-up To An Answer Is A Question

0 views
Matthias Endler 1 years ago

The Dying Web

I look left and right, and I’m the only one who still uses Firefox. At conferences and in coworking spaces, it’s always the same scene: people using some flavor of Chrome. Sometimes it’s Brave, sometimes Chromium, most of the time it’s just Google Chrome. I find that hilariously appalling. An entire generation grew up with access to great free tools and open standards, which helped them jumpstart their careers and gave them access to excellent technology for free. Now, the world’s largest websites are owned by the same company, which also owns the world’s most popular browser and search engine. Coincidentally, they are also the world’s largest advertising company. And people are wondering why they can’t block ads on YouTube anymore. We gave it all away for nothing. Let me be the first to admit that I too am not without sin. There was a weak moment about 15 years ago when browser performance became so unbearable on anything other than Chrome that it forced my hand to make the switch. And yes, for a while, life was good and websites loaded quickly. Reluctantly, I made the switch back to Firefox after a while, because open standards and privacy were more important than a few milliseconds of loading time. I could still understand why people would use Chrome, but I was happy with my choice. Then Firefox Quantum came around, and I told all my fellow developer friends about it. To me, it was the best browser on the market, and I was proud to be a Firefox user again. It was fast, snappy, and had a great add-on ecosystem. To my surprise, nobody cared. Bad Habits Die Hard Maybe people stayed with Chrome out of habit. Performance and privacy aside, I just don’t know how people can cope with Chrome’s limited customizability. It’s hilarious to watch people with 200 tabs named “G”, “Y”, or “X” struggle to find that one document they opened a week ago. In comparison, vertical tabs on Firefox with add-ons like Sidebery make Chrome look like a toy. Anyhow, Chrome. There was a time when I tried to educate people on the negative effects of browser monoculture. Okay, my mum didn’t get it, but I was more disappointed by my fellow devs. Everyone took the easy route and happily stayed on Uncle Google’s lap. At this point, I neither have the willpower nor the energy to fight back; it’s hopeless. It’s probably easier to get blood from a stone than to convince someone to switch back to Firefox. It’s so easy to switch, you won’t even lose any open tabs ! Nobody Forces You to Use Chrome True, but the issues don’t stop at my front door. As an outsider, I need to live with the consequences of browser monoculture every day. Quite a few websites are unusable by now because they got “optimized for Chrome.” Microsoft Teams , for example, and the list is long . These websites fail for no good reason. There are positive examples, too. Zencastr , for example, used to be broken on Firefox, but they fixed it. Update: Zencastr is still broken on Firefox. Thanks to Randell from Mozilla for pointing that out. Their support page states that Chrome, Edge, or Brave are required . They stopped supporting Firefox in February 2021 as per this blog post . There’s an open ticket in the Mozilla Bugzilla tracking this issue. It’s currently blocked on some other issues, but there’s progress being made. The WebCodecs API , which might be related to this problem, is currently in beta and progressing through Mozilla’s release process. While it’s disappointing that Zencastr doesn’t work on Firefox yet, it’s encouraging to see that Mozilla is actively working on resolving the underlying issues. I also use Chrome for online calls, because tools like Jitsi don’t work well on Firefox. Maybe it’s because of Firefox’s WebRTC support? Or, maybe it’s because of Chrome : Pop Quiz : If a website wants to play out of different speakers on your system, what permission must it have? If you answered 2, then chances are you know your WebRTC stuff well, but you’re probably on a Chromium browser. How could Google get free rein? Because everyone and their car stopped testing their stuff anywhere else. If everyone tweaks their site for Chrome, well, of course the site will work just fine on Chrome! We find ways around Chrome’s weird quirks. More users join the bandwagon because stuff “just works” and the vicious cycle continues. I can’t blame them. It’s easier to ride a horse in the direction it is going. But at what cost? *Elrond voice*: We’ve been down this road before. (Okay, I was there.) We called it the Browser Wars : Netscape vs Internet Explorer. Netscape lost and Microsoft ruled over the web with an iron fist. It wasn’t fun. We had more hacks around browser limitations than actual website functionality. Parents put their kids through college by working around browser bugs for money. Microsoft tried really hard to make life as miserable as possible for everybody: Internet Explorer has introduced an array of proprietary extensions to many of the standards, including HTML, CSS, and the DOM. This has resulted in several web pages that appear broken in standards-compliant web browsers and has introduced the need for a “quirks mode” to allow for rendering improper elements meant for Internet Explorer in these other browsers. — Wikipedia Essentially, they broke the web and we all warmed our hands on the dumpster fire. All we got in return was quirks mode. Google is smarter! They break the web, too, but they make you stand inside the fire. Why should I care about a browser? They are all the same anyways. …says the developer who gets tracked by Google every waking moment. Source: https://www.skeletonclaw.com/image/710734055173472257 You see, Chrome is reeeeally good at marketing. They say all the right things: We’re fast! We’re open source! We have the latest features! What they don’t tell you is that they control the narrative of the World Wide Web. They make you feel guilty for using adblockers and add weird nonstandard browser features because they can. Lately, the uBlock Origin team just threw in the towel and stopped supporting Chrome . But did anyone decide to jump ship? I get the feeling that by now people turn a blind eye to Google’s evil practices. But shouldn’t Brave, Edge, Opera, or Vivaldi be sufficient? Unfortunately not. They all use the same browser engine under the hood. Browser makers make mistakes, so this engine is not perfect. If it contains a bug and there’s no competition, that bug becomes the standard. Alternative browser engines need to implement the bug as well to support websites which depend on it. I Use Safari Congratulations, you switched from a browser controlled by a 2 trillion dollar company to a browser controlled by a 3 trillion dollar company. Oh, and it doesn’t run on Windows or Linux. Both Apple and Google would throw you under the bus if it made them more profit. Oh, and did you know that Google paid Apple 20 billion dollars in 2022 to be the default search engine on Safari? What Can I Do? If you’ve made it this far, do yourself a favor and spend a few minutes trying Firefox. Who knows? You might just like it. Try Firefox today, please? Speaker-selection permission Microphone permission

0 views
Matthias Endler 1 years ago

How To Sell To Developers

One of the hardest challenges I know is how to sell to developers. This is NOT an article for developers. Today, I want to write for non-developers whose job it is to sell to developers. My goal is to help you understand how they think. Developers Hate Being Sold To We tend to be a skeptical bunch! We’re not reachable through Google ads because we use ad blockers. We expect software to be free and open source, so we don’t usually pay for it. We subscribe to a handful of services that provide a lot of value for very little cost. Everything else we build ourselves. See the problem? How do you sell to these people? The Developer’s Dilemma Strangely enough, when developers think about starting a business, the first products they consider are often those aimed at other developers, despite there being many easier markets to sell to! We love building things so much that we try to sell the things we build to people just like us. Here’s my advice: What You Need to Know About Marketing to Developers Here’s the bitter truth. To sell to developers… What if you don’t have the time or the patience? See rule 1 above. My Developer Product Journey So Far You might ask, “Why should I listen to you? Have you ever sold a product to developers?” I’ll let you be the judge of that. Here are a few products that I have built and sold to developers: codeprints Homepage of CodePrints with my GitHub profile as a print This was a fun experiment during the pandemic. We sold posters of GitHub timelines. Our marketing strategy included posts on Reddit and Hacker News, and we sent free prints to a few “devfluencers.” The novelty effect and viral marketing worked well. Eventually, we sold the company to a developer agency because we didn’t want to deal with the logistics. Read more about CodePrints in this blog post . Lychee Homepage of Lychee’s documentation page I built this tool for myself because I needed it. Lychee is a command-line tool that checks for broken links in markdown and HTML files. It has become quite popular on GitHub, with companies like Google and Amazon using it. However, I’ve never made any money from it. I reached out to some companies to sponsor the project, but it was very hard to get a response or explain why they should sponsor a free tool. I wrote about making money with Open Source here . Analysis Tools Homepage of analysis-tools.dev This is a directory of tools for developers. It’s a side project that I started in 2015 (did I mention you need to be patient?), and it has grown to be a popular resource. Together with two friends, we sell sponsorships and ads on the site, which provides a nice side income. I think this project works because it’s not a product for developers but a product for people who build products for developers . Our customers are mostly developer advocates, developer relations folks, and marketing people who want to reach developers. Sponsoring on Analysis Tools is extremely cheap compared to other marketing channels like Google ads. On Google, you can easily spend thousands of dollars per month trying to reach developers. On Analysis Tools, you can reach them for a fraction of that cost. The basic tier is $100 per month, and for that, you get your logo on the site and in every repo. Thousands of developers visit the site every month. It’s basically a no-brainer to sponsor the site if you build a linter, a static code analyzer, or any other tool that developers use. Tools page of analysis-tools.dev Think of it this way: when was the last time these companies had the chance to reach thousands of developers for $100? What is the total cost of acquisition for a developer? How much would you pay for a developer to try out your tool? Only 20% Of Companies Immediately Get It From the companies I’ve talked to, only around 20% get it immediately. There are perhaps 30% that need a little handholding. The other 50% see it as an ad placement and want to know the click-through rate. Let me repeat: It’s not about the click-through rate. It’s about the branding and the reach. You will never reach a critical audience if you don’t start investing in the developer community. This is not a one-time thing. You need a lot of exposure until you get noticed and developers start talking about your product. If you try to fake it, you won’t get far. Devs will avoid your product like the plague and tell their friends to do the same. Your main constraint is the attention of developers! These folks constantly get bombarded with millions of products and don’t have time to evaluate them all. They stopped actively looking for new tools a long time ago. They rely on a handful of trusted sources they follow. Building Trust Is The Only Way Getting into their circle of trust is hard, and for that reason, you need to be patient and invest a lot of time into relationship building. If you can afford it, hire a developer advocate. A good one is heavily invested in open source and knows how to write for developers. At the very least, you need to be present in the places where developers hang out. So reach out to open source maintainers in your niche and see if you can collaborate or sponsor their projects. Don’t waste cash on Google ads or other traditional marketing channels. Go where the developers are. I hope this article helped someone who is struggling to sell to developers. Perhaps one of you will reach out to some open source maintainers in their niche and sponsor their projects. That would be a great outcome! There’s a plus side to all of this: once you understand that you need to invest in the developer community, you will have a competitive advantage because most other companies don’t get it. Don’t build a product for developers. Seriously, don’t build a product for developers. Since you’ll likely ignore the first two pieces of advice, at least learn how to market to developers effectively. You will have to be present in the places where they hang out. You will have to invest a lot of time in community building. You will have to be extremely patient. There is no shortcut.

0 views
Matthias Endler 1 years ago

Cursed Rust: Printing Things The Wrong Way

There is a famous story about a physicist during an exam at the University of Copenhagen. The candidate was asked to describe how to determine a skyscraper’s height using a barometer. The student suggested dangling the barometer from the building’s roof using a string and then measuring the length of the string plus the barometer’s height. Although technically correct, the examiners were not amused. After a complaint and a reevaluation, the student offered various physics-based solutions, ranging from dropping the barometer and calculating the building’s height using the time of fall, to using the proportion between the lengths of the building’s shadow and that of the barometer to calculate the building’s height from the height of the barometer. He even humorously suggested simply asking the caretaker in exchange for the barometer. The physicist, as the legend goes, was Niels Bohr , who went on to receive a Nobel Prize in 1922. This story is also known as the barometer question . Why Is This Story Interesting? The question and its possible answers have an important didactic side effect: they convey to the learner that one can also get to the solution with unconventional methods — and that these methods are often more interesting than the canonical solution because they reveal something about the problem itself . There is virtue in learning from unconventional answers to conventional questions. To some extent, this fosters new ways of thinking and problem-solving, which is an essential part of innovation. Applying The Same Principle To Learning Rust One of the first examples in any book on learning Rust is the “Hello, world!” program. It’s an easy way to test that your Rust installation is working correctly. However, we can also have some fun and turn the task on its head: let’s find ways to print “Hello, world!” without using . Let’s try to come up with as many unconventional solutions as possible. The weirder, the better! As you go through each of the solutions below, try to understand why they work and what you can learn from them. This started as a meme , but I decided to turn it into a full article after the post got a lot of attention. It goes without saying that you should never use any of these solutions in production code. Check out this enterprise-ready version of hello world instead. Solution 1: Desugaring This solution is interesting, because it shows that is just a macro that expands to a call to with a newline character appended to the string. The real code is much weirder . Search for in this file if you want to be amazed. itself desugars to a call to , which is a method of the trait. There is a real-world use case for this: if you want to print things really fast, you can lock once and then use . This avoids the overhead of locking for each call to . See this article on how to write a very fast version of with this trick. Solution 2: Iterating Over Characters This shows that you can implement using Rust’s powerful iterators. Here we iterate over the characters of the string and print each one of them. returns an iterator over Unicode scalar values . Learn more about iterators here . Solution 3: Impl This teaches us a little bit about how traits work in Rust: We define a struct that implements the trait, which allows us to print it using . In general, is intended to make more complex types printable, but it is also possible to implement it for a hardcoded string! Solution 4: Who Needs ? How about we create our own trait instead of using ? We can exploit the fact that we can name our trait methods however we want. In this example, we choose , making it look like it is part of the standard library. This completely turns the macro on its head. Instead of passing a string as an argument, we call a method on the string itself! Solution 5: Who Needs When You Got ? There are other ways to print things in Rust than using . In this case, we use , which prints the string (as a side-effect) and immediately terminates the program. It works as long as we only want to print a single string… Solution 6: I ♥︎️ Closures Rust allows you to call a closure directly after its definition. The closure is defined as an anonymous function that takes a string slice as an argument and prints it. The string slice is passed as an argument to the closure. In practice, this can be useful for defining a closure that is only used once and for which you don’t want to come up with a name. Solution 7: C Style You don’t even need to use Rust’s standard library to print things! This example shows how to call the C standard library’s function from Rust. It’s unsafe because we are using a raw pointer to pass the string to the function. This teaches us a little bit about how FFI works in Rust. Credit goes to /u/pinespear on Reddit and @[email protected] . Solution 8: C++ Style We’re well into psychopath territory now… so let’s not stop here. If you try extremely hard, you can bend Rust to your will and make it look like C++. The trait is used to implement the operator. The struct implements for any type that implements , which allows us to print any printable type. The struct implements for , which prints the newline character in the end. Credit goes to Wisha Wanichwecharungruang for this solution. Solution 9: Unadulterated Control With Assembly All of these high-level abstractions stand in the way of printing things efficiently. We have to take back control of your CPU. Assembly is the way. No more wasted cycles. No hidden instructions. Pure, unadulterated performance. ( Rust Playground ) If you’re wondering why we use Rust in the first place if all we do is call assembly code, you’re missing the point! This is about way more than just printing things. It is about freedom! Don’t tell me how I should use my CPU. Okaaay, it only works on x86_64 machines, but that’s a small sacrifice to make for freedom. Submitted by isaacthefallenapple . Solution 10: “Blazing Fast” Why did we pay a premium for all those CPU cores if we aren’t actually using them? Wasn’t fearless concurrency one of Rust’s promises? Let’s put those cores to good use! Here, each character is printed in a separate thread. The threads are spawned in a loop, and each thread sleeps for a certain amount of milliseconds before printing its character. This uses the full power of your CPU to print a string! It might not always consistently print the characters in the right order ( hey, scheduling is hard! ), but that’s a worthwhile trade-off for all the raw performance gains. Your Turn! If you’ve got more solutions, please send me a message. Also, if you liked this article, you might also enjoy the yearly obfuscated C code contest. Check out the previous winners here . If you were actually more intrigued by the barometer story, read Surely You’re Joking, Mr. Feynman! , a book by Richard Feynman, another famous physicist and Nobel Prize winner, who was known for his unconventional way of thinking. We should all strive to think outside the box and come up with unconventional solutions to problems. Who knows, maybe that’s the key to a deeper understanding of the problem itself?

0 views
Matthias Endler 1 years ago

Deploy Rust Code Faster

I’ve come a long way in my tech journey, from dealing with bare metal servers to exploring the world of cloud computing. Initially, it seemed so straightforward – spin up a server, deploy a container, and you’re done. But as I delved deeper, I realized that the ease of infrastructure is not as simple as it appears. Cloud providers offer a multitude of tools, each with its own learning curve: If you’re adventurous, you might even venture into managed Kubernetes services like EKS or GKE. It’s tempting, with just a few clicks, your application is ready to roll. But the reality hits when you start juggling monitoring, logging, security, scaling, and more. Soon, you find yourself unintentionally leading a DevOps team instead of focusing on your product. You hire more staff to manage infrastructure while your competitors are shipping features and growing their user base. My Frustration The cloud promised to make infrastructure easy, but the array of tools and services can be overwhelming. Even if you don’t use them all, you must be aware of their existence and learn the basics. The result? Your focus on the product diminishes. I appreciate dealing with infrastructure, but I also love delivering a product. Sadly, many companies waste precious time and money on infrastructure, repeating the same mistakes. What if there was a way to eliminate infrastructure concerns altogether? The Allure of Serverless Serverless architecture seems promising - no servers, no containers, just pure business logic. However, it’s not without challenges: Serverless has its merits for certain use cases, but for larger applications, you might still need some servers. Platform-As-A-Service (PaaS) Platforms like Heroku and Netlify introduced a third option – managed services that handle all infrastructure for you. No more infrastructure concerns; you simply push code, and it deploys. What’s great about these solutions is their deep integration with specific programming language ecosystems. I was looking for a platform tailored for Rust developers, aiming to provide a top-notch developer experience. I wanted deep integration with the Rust ecosystem (serde, sqlx, axum,…). A while ago, I came across Shuttle while trying to find ways to make my Rust development workflow a bit smoother. It’s a tool that kind of just fits into the existing Rust ecosystem, letting you use cargo as you normally would, but with some of the infrastructural heavy lifting taken out of the picture. Now, it’s not a magic wand that solves all problems, but what I appreciate about Shuttle is its simplicity. You’re not thrown into a completely new environment with a steep learning curve. Instead, you stick to your Rust code, and Shuttle is there in the background, helping manage some of the server-side complexities. So, in essence, it’s about sticking to what you know, while maybe making life a tad easier when it comes to deployment and server management. It’s not about a revolutionary change in how you code, but more about a subtle shift in managing the background processes that can sometimes be a bit of a headache. My Shuttle Experience So Far Until now, I built two smaller Rust services with Shuttle: Zerocal and Readable. Shuttle takes your Rust code and with very few annotations, it can be deployed to the cloud. The developer experience is pretty close to ideal given that provisioning and deployment are usually the most painful parts of building a service. Instead, it’s just a matter of adding a few lines of code. See for yourself. The boilerplate just vanishes. What’s left is the business logic. Zerocal - Stateless Calendar Magic Zerocal was the first project I deployed on Shuttle. The principle was very simple yet innovative: encode calendar data directly into a URL. This means creating an event was as straightforward as: This would return an iCal file, that you can add to your calendar. Here’s how you create an event in the browser: I tried building this project on Shuttle when they were still fixing some things and changing their APIs here and there. Even with these small issues, it was a good experience. In just a few minutes, my app was up and running. Here’s the code to start the service including the axum routes: I don’t really need Zerocal for myself anymore, so I’m hoping someone else might want to take it over. I think it could be really useful for sharing invites on places like GitHub or Discord. If you want to know more about Zerocal, you can read this detailed breakdown . I would also like to mention that someone else built a similar project inspired by Zerocal: kiwi by Mahesh Sundaram , written in Deno. This is a really cool outcome. A Reader Mode For My E-Reader My appreciation for Firefox’s reader view sparked the creation of a Reader Mode Proxy for a minimalist, JavaScript-free web reading experience, particularly tailored for e-readers. The intention was to transform verbose websites into a more digestible format for distraction-free reading. This project deeply reflected my personal preferences, as I like simple apps that solve a problem. With just a sprinkle of annotations, my code adapted smoothly to Shuttle’s environment. Initially, I had my own local mode, which allowed me to run the app on my machine for testing, but I found no need to maintain that because Shuttle’s own local mode works just as well. While developing the app, there were some bumps along the road. Service downtimes required some code revamping. Yet, Shuttle’s evolution simplified parts of my process, especially when it introduced native static file handling. Before it looked like this: Now it’s just To understand the intricacies of this project, here’s a more comprehensive look . Control and Safety Initially, I was concerned that annotating my code for infrastructure would cause vendor lock-in. I wanted to retain full control over my project. Want to move away? The Shuttle macros get rid of the boilerplate, so I could just remove the 2 annotations I’ve added and get the original code back. Shuttle’s code is also open source, so I could even set up your self-hosted instance — although I wouldn’t want to. The True Cost of DIY Infrastructure Infrastructure may seem easy on the surface, but maintaining it involves various complexities and costs. Updates, deployments, availability – it can be overwhelming. Each hour spent on these tasks carries both a direct and opportunity cost. Infrastructure can be a maze, and Shuttle seems to fit well for those working with Rust. I’m thinking of trying out a larger project on Shuttle soon, now that I’ve got a decent understanding of what Shuttle can and can’t do. If you’re considering giving it a shot, it’s wise to check their pricing to ensure it aligns with your needs. Be mindful of the real cost of infrastructure! As I’ve mentioned before, it’s not just server costs, but a lot more. The biggest factor will probably be human labor for maintenance and debugging infrastructure and that is expensive. If I were to use infrastructure as code, I’d be spending many hours setting up my infrastructure and a lot more to maintain it and that can be expensive, given today’s salaries. Even if it was just for a hobby project, it would not be worth the trouble for me. I’d much rather work on features than the code that runs it all. Google Cloud / AWS GitHub Actions Cold start times Lambda size limitations Memory issues Long-running processes Debugging complexities Lack of local testing

0 views
Matthias Endler 2 years ago

Little Helpers

Yesterday I couldn’t help but feel a sense of awe at all the conveniences modern life has to offer. A lot of the chores in our household are taken care of by little helpers: The dishwasher washes the dishes, the washing machine washes the clothes, and the robot vacuum cleaner cleans the floors. The refrigerator keeps our food cold, the microwave heats it up, and the oven cooks it. We take all of this for granted because the devices rarely fail, but it’s really amazing when you think about it. It’s only been a few decades since much of this was tedious, time-consuming, manual labor. I heard stories about how people used to watch the washing machine do its thing, just because it was entertaining to see the machine do their work for them. Growing up in the 90s and early 2000s, I remember when “smart home” was a buzzword, and now it’s a reality. Smart devices control the thermostat and soon the lights and the door locks in our apartment. Of course there were a bunch of stupid ideas that didn’t work out along the way. I remember when they tried to sell those “smart” fridges that would run a web browser and let you order groceries from the fridge. Who would want to do that? It’s so much easier to just order groceries online from your phone or computer. On the other hand, of all the people I talked to, I’ve never met anyone who regrets buying a vacuum robot. We recently got a cat and quickly automated all the tedious stuff. The litter box cleans itself, there’s a water fountain that keeps the water fresh, and soon we’ll get a food dispenser. That means we have more time to focus on the fun stuff, like playing with the cat. And yes, I fully realize that this convenience comes from an incredible position of privilege. A privileged position that we should never take for granted! Instead, we should be grateful for the little helpers that make our lives easier and make them more accessible to everyone.

0 views
Matthias Endler 2 years ago

A Reader Mode Proxy for the Slow Web

Reader showing an article in light and dark mode. tl;dr: I built a service that takes any article and creates a pleasant-to-read, printable version. It is similar to Reader View in Firefox/Safari, but also works on older browsers, can be shared and has a focus on beautiful typography. Check out the source code . The web used to be such a fun place. Nowadays? Meh. Trackers, ads, bloat, fullscreen popups, autoplaying videos… it’s all so exhausting . I just want to read long-form posts without distractions with a good cup of tea, the cat sleeping on the windowsill and some light snow falling in front of the window. The Slow Web I’m a big fan of the Slow Web movement and of little sites that do one thing well . For reading long-form text clutter-free I use Reader View in Firefox, and while it doesn’t always work and it’s not the prettiest I like it. There are reader modes in other browsers as well, but some of them — like Chrome — hide it behind a feature flag . Other browsers, like the one on my eBook reader, don’t come with a reader mode at all, which leaves me with a subpar and slow browsing experience on my main device used for reading. So I built a reader mode as a service with a focus on beautiful typography which works across all browsers. It’s very basic, but I use it to read articles on my older devices and it could also make content more accessible in regions with low bandwidth or while travelling. Building It Lately I saw a post about circumflex, a Hacker News terminal client . The tool did a solid job at rendering website content and I wondered if I can retrofit that into a proxy server. The Golang cleanup code is here : They use go-readability , a port of Mozilla’s Readability . The Rust equivalent is readability and it’s simple enough to use: Before we write a full proxy server, let’s write a simple CLI tool that takes a URL and outputs a clean, readable HTML file. The output already looked surprisingly good. Next I added a simple HTML template to wrap the response content. No need to use a full-blown template engine for now; we can just use to replace the placeholder with the actual content. 😉 Proxy Setup The proxy setup is super simple with shuttle . It’s my second project after zerocal , which is hosted on shuttle and I’m very happy with how smooth the process is. 🚀 Let’s call the app : This creates a small Axum app with a simple hello world route. Roadblock No. 1: When I integrated the readability crate into the project I hit a minor roadblock. I used just like above and the proxy started locally. However when I wanted to fetch a website from the proxy, I got an error: This meant that I started a runtime inside a runtime. After checking the source code of the crate, I found that it builds a and uses that to fetch the URL. After that request, the client is dropped which causes the runtime to be shut down. I fixed this by using a instead of the . Now I had the content of the article, but I still needed to pass it to . Fortunately they provide a function named that takes something that implements and returns the extracted content. However, the doesn’t implement (in contrast to the ). So I needed to convert it to a able type myself. Luckily, the has a method that returns a object. The object implements and I can use it to call . Roadblock No. 2: Routing The app didn’t crash anymore, but I still didn’t get any response. My router looked like this: Turns out that when I use as the route, it doesn’t match the path because matches only a single segment up to the first slash. The solution was to use instead, which is a wildcard route that matches all segments until the end. Typography and Layout New York Times website (left) vs reader mode (right) For my first prototype I used a CSS framework called yue.css because it was the first thing I found which looked nice. For the final version I ended up mimicking the style of Ruud van Asseldonk’s blog because it always reminded me of reading a well-typeset book. For fonts I chose two of my favorites Both are licensed under the SIL Open Font License 1.1 . You can even use from the terminal. Caveats The proxy is far from perfect. It’s something I built in a few hours for my personal use. Credits I was not the first person to build a readability proxy. I found out about readable-proxy when I did my research, but the project seems to be abandoned. Nevertheless it was nice to see that others had the same need. Thanks to Ruud van Asseldonk for open sourcing his blog . 🙏 His writing and documentation are always a great source of inspiration to me. Conclusion The browser on my old Kobo eBook reader using the readability proxy. In times where the most popular browser might kill off ad blockers , a little service for reading articles without ads or tracking can come in handy. I’m not saying you should use it to send all your traffic through it, but it’s a nice tool to have in your toolbox for a rainy day, a warm drink and a great article. ☕ Feel free to deploy your own instance of or use the one I’m hosting. The source code is available on GitHub . Maybe one of you wants to help me maintain it. Crimson Pro for the body text. JetBrains Mono for the code. It doesn’t always produce valid HTML. JavaScript is not executed, so some websites don’t work properly. Some might say that’s feature, not a bug. 😉 That is also true for websites with sophisticated paywalls or bot-detection. A workaround would be to use a headless browser like ScrapingBee or Browserless , but I didn’t want to add that complexity to the project. The library takes a lot of freedom in formatting the document however it pleases. It can sometimes produce weird results. For example, it loves to mangle code blocks.

0 views