Durable tech

I pay hardly any attention to anything that can be considered the “tech du jour”. When it comes to tech I’m a late adopter (if not a laggard), and unapologetically so. Sometimes I miss out on really cool tech that works amazingly well, but most of the time new tech is a dead end. Either it doesn’t catch on, or it does but it doesn’t work well, and even then it’s likely to get displaced by the new hotness in just a few years.

Take smart devices. Are smart home devices here to stay? I don’t doubt it. Do I want to have my house filled with the kind of smart devices that are for sale today? Absolutely not[1]. Smart devices are still hobbyist devices. For people who enjoy tinkering and the never-ending process of making different brands and protocols work together. Do I want a wifi-enabled garage door opener that breaks when some cloud service goes down? I don’t. Nor do I have the patience to upgrade the firmware on smart lightbulbs.

That these smart home devices don’t work properly isn’t the worst thing. The worst thing is that they demand constant time and attention and that the process of getting things to work is never educational. You can’t get “good” at home automation. You just google and mess with config settings until it starts working and then you hope it will continue to work for as long as you don’t touch it. (If only!)

I like to fix things such that they stay fixed. And I like to learn skills in the process that will serve me well for the decades to come. Because it’s this combination that allows you to move forward and go fast. The more fragile tech you use the more energy you waste on ducktape fixes. The more fashionable your tech is the more energy you waste memorizing minutiae. And then you have to migrate your stuff from the old way to the new, starting the process all over. Chasing new tech can feel like work, but you’re really just tiring yourself out without getting anywhere.

Once you’re on the lookout for durable tech you find nondurable tech everywhere. Web frameworks have notoriously little durability. When you memorize the concepts of a web framework you gain short term productivity, but you don’t acquire any fundamental knowledge. If you’re not careful you’ll spend your entire career chasing the new hot thing in web tech.

If you learned Javascript 10 years ago, haven’t used it since, and decide to make something today, it’s very easy to get back up to speed. Browsers have gotten amazingly fast, but this benefit you get for free. You now have “let” instead of “var”. You have real dictionaries instead of Object. In total there are maybe 100 new additions, and you can learn about all of them in an afternoon or two. JavaScript has gotten way better, but fundamentally it’s still the same language.

By contrast, if all you know is jQuery (15 years old) or AngularJS (10 years old) you now have a way steeper learning curve ahead of you. Frontend libraries like these don’t age well, and everything you memorized about the “angular” way to develop applications is not worth anything anymore. If you decide to learn another framework, React maybe, then you risk investing in what could turn out to be a technological dead end. Will reactive design be the way we develop apps in the next 20 years? Probably not. And apps built with “legacy” web stacks? They become unmaintainable, so you’re pretty much forced to rewrite them. Good luck finding people who want to work on an Angular 1.0 app in 2022.

Software written in C 20 years ago still works flawlessly today. Old DOS games can run in Dosbox or a browser emulator. Webapps that are a hairball of ducktaped libraries and microservices fall over unless you do constant maintenance. Some tech endures while other tech falls apart. The difference is night and day.

The Ancient Roman Bridge, a Timeless Engineering Feat | by Richard Bruschi  | History of Yesterday
This roman bridge is I don’t know how old, but it’s still here.

You want to invest time and effort in technologies that clearly won’t go away. Becoming good at vim or MS Excel might not be an optimal time investment, but the time isn’t wasted because even 20 years from now vim will be vim and and excel will be excel. Being able to ssh into any machine in the world and being able to effectively edit files is extremely useful today just like it was 10 years ago. When you’re good at Excel you can quickly crunch some numbers and plot some charts. Why spend days or weeks on dashboards that track metrics when you can do the same in Excel in a fraction of the time?

Durable tech skills are knowing fundamentals of C/C++, Python, JavaScript or any other mainstream programming language. You can learn vim, bash, strace, and rsync. These utilities aren’t going anywhere. You can learn algorithms and you can learn how to relational databases work, instead of some company’s proprietary API or ORM. Write things yourself, from scratch, with as few dependencies as possible. This way, once something works it will continue to work, maybe forever.

I can’t predict the future, but one trend is clear. Simple, monolithic systems that are rock solid tend to continue to work. Fragile systems composed of many libraries, services, and glue code start out unreliable and never seem to get better. Look for durable tech and try to make things that last.

[1] the only smart device I own is a Spotify connect receiver that stops working every 2 weeks and the only “fix” I found is to hard reboot by pulling the power cord. It also has HDMI CEC which works 70% of the time.

Products want to be platforms

Imagine two startups. One startup makes a business chat app similar to Slack. The other startup has a business wiki product. In principle, these are very different apps that solve different problems. In practice, both apps face constant pressure from their customers to become more like the other.

Users of the chat app start demanding threaded discussions, archived discussions, pinned discussions, rich text options, and the ability to draft responses. Any individual feature might make customers happier and increase retention and conversion rates, but mindlessly adding all these features will turn a good product into an unfocussed mess. You end up with an ugly hybrid app that is half chat half wiki. It doesn’t have a clear audience anymore.

You can see how a wiki app can end up in the same place by adding more and more messaging features. Different chimera, but equally bad.

It’s a problem that all b2b SaaS apps struggle with. If you say yes to every feature request your product eventually turns into a platform product like Office 365. Customers always ask for Forms, workflows, calendars, project management, chat, writing, and email features. And they’re not wrong to want a single integrated solution as opposed to a hodgepodge of overlapping products. If they like a product they want it to solve more of the problems they have. So what is the app developer supposed to do?

As a SaaS vendor you have a couple of options. One option is to embrace the platform vision. Max out on engineers and build it all. This is the Google Suite, ZoHo and MS Office 365 strategy.

A second option is to stay strictly on course. You build out your narrow product and make it the best it can be without adding any platform features. Instead of making your product wider you go deeper. You keep your focus and you refine and perfect your product, and users will have to use an API for everything else. You get really good at saying “no” to customers. The big disadvantage of this approach is that you spend a lot of time making small improvements only a handful of powerusers care about while ignoring the features your customers really want but that don’t fit neatly in your product vision.

A third option is the “tiny platform” approach. Instead of building a whole platform you only build the easiest 5%. You implement a couple of key features of each platform product and go no further. This is the Basecamp approach. The big disadvantage here is that you end up with a product that is okay at many things but doesn’t excel at anything.

A fourth option is to make your product an add-on to an established platform like Office or Google Suite. You focus on your product features and you can provide integrations with the other application suite products for everything else. This strategy makes a lot of sense, except, you tie your future to a 3rd party that really doesn’t care about you. It’s a precarious position to be in. The platform owner can pull the plug at any time. One day you’ll wake up to an automated email that an API function has been deprecated. Your app stops working. Your customers are angry, you are helpless, and years of work go down the drain.

There is no correct approach to this platform dilemma. Software is never finished and you can always keep building and building in any direction. Build in the right direction and you’ll get many happy users. Build in the wrong direction and you’ll attract the wrong kind of customers that will push your product even further away from product-market fit. That’s why it helps to have a clear platform strategy. It can tell you when to say no.

This is what we have to figure out for Thymer. Thymer will have task management and planning features, but this has some overlap with the features provided by conventional calendar software. And everybody already has a calendar app that Thymer can’t realistically replace. Neither can Thymer replicate all major functionality people have come to expect from calendar software. So what do we do? Do we go all-in on API integrations with 3rd party calendar software? Do we tolerate scope creep and reimplement all calendar features we think are important? Do we add a minimalistic calendar to Thymer and accept that users will still have to use a different calendar product on the side? Or should we kick the can down the road in the hope the correct answer will become clear in the future? I don’t know.

Making sense of contradictions

There is a ton of startup advice out there, and much of it is contradictory. Let me explain what I mean with some examples:

  • Entering a crowded market: It’s smart because in a crowded market you can always find people looking for a new product. Or: It’s risky because it’s difficult to make your product stand out from the crowd.
  • Product pricing: You should charge as much as possible, that way only you need to find a handful of customers to become “ramen profitable”. Or: make your product inexpensive so you can undercut competitors and enjoy free word of mouth marketing.
  • Rapid prototyping: Smart because it allows you to quickly validate if your business model works. Or: It’s unwise because if you rush to market your product won’t be great.
  • Originality in product: It’s good because people don’t get excited about things they’ve seen before. Or, maybe, it’s bad because it means you’re solving a problem that doesn’t exist or nobody cares about.

It’s not hard to come up with arguments for or against anything when it comes to software startups. This is in part because the world of software is big. Strategies that make sense for a lavishly funded startup in the valley won’t work for a bootstrapped company in Japan. A biotech startup has different constraints than a simple web startup.

Contradictory startup advice is also common because there are many different ways to get a company off the ground. What worked for others in their particular situation probably won’t work for you. Different time, different product, different market, different people. Every startup is unique and the world is changing rapidly.

When you get or read advice ask yourself if the opposite could be equally true. It easily could be. It’s up to you to figure out if you should follow well-meant advice or do the opposite. It’s rarely obvious. So take the time to really think everything through. As a rule of thumb, you can learn the most from founders that are slightly ahead of you and that have a product in a similar but different market. Then you can look at what they do and see if it works. What does their marketing and sales strategy look like? Is their product good? Do people talk about their product on social media? What do they say? How and where they they get their first users? If you keep your eyes peeled for evidence like this you’ll learn a bunch.

Magical thinking

Most startups fail. Some startups don’t launch at all. Maybe the founders get into a big fight, or they lose interest, or the product is too hard to build, or something else throws a spanner in the works. Other startups launch but don’t get any traction. Either they get no signups or the users don’t like the product. The founders then get discouraged and quit. Then there are startups that pass the first two hurdles but stumble at the third hurdle: they launch and get a bunch of happy users but they fail to monetize. Failure at different stages but failure all the same.

With our app we really want to pass all three hurdles: launching, marketing, and sales. There is some luck involved and we can’t discount the possibility we’ll fail as well. Things beyond our control can take us out. That’s part of the game and we accept that. What we don’t want is to fail because of unforced errors. We don’t want to do dumb stuff that predictably results in failure. We want to learn from other startups what works and what doesn’t.

I’m going to describe three different startup failure scenarios that I see time and time again. I’ve anonymized the stories because my goal here isn’t to make fun of people who failed but to analyze what happened so we can learn from it.

Our fictionalized founder makes three apps over the years:

  1. a desktop app that helps you organize your music collection on Linux
  2. an iPhone app that tracks and charts your grocery expenses
  3. a job listing webapp

The projects fail for different reasons but with a shared root cause. I’ll get to that later. First let’s go over these startup attempts.

Attempt 1: Linux music library app

Two common pieces of startup advice are to (1) build with the skills you have and (2) solve a problem you understand well. Our protagonist takes this advice very literally and decides to make a desktop Linux app. He has written software for Linux before and he knows he can make a better app for organizing your music.

Our heroic founder spends nights and weekends to get his music library app done. He starts coding in c++ for performance reasons, but eight months in he decides that programming that way just takes too long. The product architecture got a bit messy, so he decides it’s time for a rewrite in Rust. He doesn’t know Rust, but it’s a cool new language with smart memory management that he wanted to learn anyway. Fast forward a year later and the app kind of works. At this point the founder no longer has much passion for the idea. He’s not convinced people will buy his app. Working for two years straight in isolation is a long time and he decides he it’s time to launch. He spends two days on a website, but our protagonist has no web design skills and it looks pretty bland. He submits his site to Hacker News, reddit, and sends the link to some friends.

Crickets. His website gets a few dozen visitors. A download or two. Traffic drops to zero after a few days. Frustrated, the programmer abandons his project. He tells himself that failure is inevitable on the road to success. That failure isn’t real failure if you learn from it. He reflects on why his startup didn’t take off and concludes that the fundamental problem is that his app didn’t have a big enough audience because Linux is too niche. He figures he should have made something for “regular people”, instead. He also decides he should make something simpler.

With full determination he decides to try again.

Attempt 2: iPhone app for grocery expenses

Our founder has no particular passion for grocery phone apps but he figures that everybody shops for groceries so it should be a good and large market. If he charges $10 then for every 0.01% out of a billion iPhone users that buy his app he’ll make a million dollars (less 30% Apple fees and taxes). Previously the founder struggled with distribution and now he has Apple to take care of this for him. He also doesn’t need to worry about invoicing, credit card payments, or any of the other annoying business-y stuff anymore.

Our protagonist starts building. A year and two rewrites later he’s happy with the product and submits his app for review. His app is approved and soon after he gets the first sale! Making your first dollar of internet money very exciting. Then again, a trickle of downloads and one $10 sale per week won’t cut it if you need to make a living. But what to do? Lower the price? Ads? Rename the app? Change the logo? Translate the app to multiple languages?

Six months and many experiments later our protagonist is ready to give up. He can get more downloads if he charges 99¢ but he’s still only making beer money. Switching to in-app purchases results in more downloads, but getting people to upgrade is no mean feat. A few mean app store reviews later he’s completely done.

Okay, lesson learned, he thinks to himself. Next time, he’s going to make something SIMPLE with BUSINESSES as customers.

Attempt 3: job board

With renewed spirit our founder gets to work. Where previously he spent the better part of a year to get a prototype going now it’s just a matter of weeks. Job boards are pretty easy. What do you need? A place for people to look for jobs in their region. Search and filter by keywords and requirements. Done. What else? A backend for employers to submit new job openings. He decides a job listing costs $100 for 30 days. Slap a credit card form on the page and done.

This time our founder has a plan to get users. He’s going to contact hundreds of companies and recruitment agencies over email and LinkedIn with his pitch. He figures that by charging less than the established players he can win their business.

No dice. Companies just don’t want to advertise on an empty website. And job-seekers have no reason to visit an empty job board either. Catch-22. Our protagonist decides to reach out to a more experienced founder and asks for advice. The secret, he’s told, is to cheat. Create fake listings, fake users. Fake it all. Once you’ve got real companies and real job-seekers you can phase out the fake traffic.

The founder can’t believe what he just heard. That’s an ethical line he doesn’t want to cross. Disgusted, he concludes that startup life just isn’t for him.

Retrospective

Three attempts over many years amounted to nothing. Every time the founder believed he learned from his mistakes and would surely succeed next time, but he was wrong. The founder didn’t get anywhere because he learned only specific lessons: don’t make a Linux app; reaching the top of the App Store charts is hard; you can’t bootstrap a marketplace from nothing without cheating. The founder didn’t discover the root cause of his startup troubles and consequently didn’t learn anything of value. He could try five more times and he would continue to fail if he did.

The fundamental mistake this founder made is that he tried to arrive a good startup concept by reason. You can come up with reasonable sounding arguments in support for the most hopeless ideas. “Good arguments” therefore carry no weight at all.

Instead, the founder should have looked for evidence. Have other people found success with commercial desktop Linux apps for consumers? If yes, how did they succeed? Did they bootstrap, self-fund, or take VC funding? How did they find an audience? Can you find the wreckage of other people who tried what you’re about to do but failed? Why did they fail? If you can’t find success stories that’s big red flag.

It’s easy to explain failure with hindsight. There is no commercial competition for Linux desktop apps because Linux users don’t pay for software. The Apple App Store by contrast is highly competitive. You have to figure out why apps succeed and fail in app stores before you spend a year on an app of your own. You need a captive audience of businesses and professionals in search of jobs before you start on your job board or you’ll fail. But these specific explanations are not important. What matters is the process of looking for evidence that supports or invalidates your startup idea before you commit. The alternative is magical thinking and it looks like this:

The diagram doesn’t look like this in the founder’s head. The founder has all sorts of strategies and plans that sound great, but plans that aren’t backed up by evidence are just wishful thinking. If you remove everything based on wishful thinking what you’re left with looks like the flow chart above. Build. Launch. Pray. Give up. (Repeat.)

The founder also made many other mistakes. But so what? Everybody makes mistakes. Mistakes can be fixed if your startup gets the important things right. Your best best is making an original product for an established market and by applying sales/marketing strategies that are known to work.

Written like this it seems trivial. But it’s not. I see an endless amount of magical thinking by founders who earnestly believe that just making something and hoping for the best will work out for them. I’m not judging, though! We’ve also spent years on hopelessly flawed products. When we failed we totally deserved it.

I mentioned in the introduction that we intend to pass the three startup hurdles of launching, marketing, and sales. For each of these hurdles we’ve collected clear indicators that our general approach should work. We’re intentionally a “single miracle startup“. We’re taking an educated gamble with our product, but our marketing and sales will be conventional and straightforward. Our plan may fail, but we have a real plan.

Start small

Especially as technical founders, when designing a product, it’s fun to think about everything it could be.

However interesting that might be for us, it’s important to not get carried away too much when it comes to actually building the product. It’s great to have a vision of where things could go and explore those a bit, but we need to keep the first version small. It’s not easy saying no, especially to your own ideas. Working on whatever you want is a big reason to run a business in the first place, but to increase the chances of success, the order in which you work on something matters.

The type of ideas we like to work on is where the long term vision of a product is sufficiently large, but where the very core, the smallest possible version, is very small (although very small is relative depending on the stage of your company of course). Working on something which could potentially be used by many many users all over the world makes the problem that more interesting to work on for us. But if we want to start up and grow, especially as a bootstrapped business, we need to be able to build the first version quickly.

Thymer is a good fit for us with these requirements. If we manage to get traction and get to the point of lift off, it’s easy to see how we could keep developing the product into a larger vision. Because it’s a very horizontal product, a feature like plugins alone could grow it into a platform, to become a control center of sorts for managing everything you need to work on or organize in your life.

At the same time, the core vision is really easy to describe: an IDE, but for planning/tasks. This alone is plenty of work, so we’re building just the (polished) parts which convey the core of that vision. That this core vision is oddly specific (many people will have no idea what an IDE is) is a good thing. It might be tempting to think building “project management software” is a better idea because it’s a huge market, but it’s very vague, has endless scope, doesn’t offer ways to reach any audience in particular, and there’s nothing unique about it. You can’t launch with a generic “platform” on day 1.

In the beginning you need the focus: reduce the scope on the product side so you can launch faster, and find a niche on the market side to find initial fans.

Building a huge product for everyone from day 1 makes it incredibly hard to succeed. In terms of marketing, paradoxically, if the product is for more people (everyone!), the less people will care. It’s just not exciting for anyone in particular, so it’s harder to reach initial passionate users that way. Plus, building up any kind of momentum takes time. If you spend years building, it needs to be an overnight success on the day you launch because you’re out of time. That’s a huge gamble. Instead, always be launching. When launching something small first and then building more on top while it’s already out there, you can do the momentum building and product building in parallel. There will be many more “launches” this way to generate some renewed interest with every add-on or new development.

Even companies with larger goals have a “secret master plan”, i.e. get to a smaller goal first

On the building side, if you only keep building, you will eventually run out of runway. Even with a large runway, the longer it’s going to take, there’s a chance you’ll simply run out of motivation. And as long as you’re building in the proverbial basement, you don’t train your launching muscle. It’s easy to get bogged down in details which don’t matter that way and drift further and further from the shores of actual user/customerland. You also don’t get any feedback, so by the time you get new insights from initial users, it might be too late to course-correct.

Another risk is that by the time your “perfect” product is finally finished, it’s obsolete, and you need even more time to make it “perfect” again. That’s not to say you need to go on some death march either, or stress out about being the fastest and worry about competition all the time. There’s usually plenty of time, but markets and trends do move on eventually, so taking too long does have risk. All in all, the chance you will really launch something successful in the end will go down.

And yes, we all know some counter-examples of products being built over the course of years to become an instant hit. But that’s a lottery, and you don’t know all the many examples where it didn’t work, where launching that way failed, and the movie/book about its story was simply never written.

Next to the approach for building a single product, this also applies to what ideas to work on. In other words, it’s easier to build Zip2 first before you start SpaceX. Start small, keep it simple, grow from there.

High conviction, low conviction

We’re making a todo/planning IDE. Think Visual Studio Code for tasks and projects. For our startup to work we have to get three pillars more or less right: product, business model, and marketing. Marketing because you don’t get anywhere when nobody knows your product exists. The business model is the part where we figure out how to make money. Most importantly we have to make a product people love.

Product

We want to make Thymer text based. The design trend over the last decade has been towards shiny interfaces with lots of whitespace and poor usability. Software has gotten easier to use but also dumbed down a great deal. We want to go in a different direction. We want higher information density, a text based interface, extensibility, and we don’t want simplicity at the expense of powerusers. On these things we are high conviction.

We have a clear vision of what we want to build. If we deviate from this vision based on early feedback we’ll end up with a product that lacks cohesion and that nobody will get excited about. We can pivot somewhat, but we can’t change what our app is fundamentally about. If it turns out that people just don’t want this kind of software (or don’t want to pay for it) we’ll throw in the towel and build something else.

Marketing

These are some of the marketing channels we can use to get the word out:

  • Social media (reddit, hacker news, linkedin, discord, other communities)
  • Google ads, Twitter Ads
  • Youtube channel
  • SEO marketing pages to boost organic search engine traffic
  • Twitter
  • Magazines
  • Blogging
  • Guest spots at podcasts
  • Guest blog posts
  • Bulk deals (e.g. Appsumo)
  • Integration with 3rd party products or protocols
  • Viral features/word of mouth

We won’t know which marketing channels will work for us. Presumably one or two marketing channels will end up producing the bulk of the traffic. We’ve just got to try everything and we’ll discover what works in the process.

When it comes to marketing and distribution we’re low conviction. We’ll have to figure it out as we go. As long as we get traffic and trial signups I’m happy.

Business model

On principle we’re only willing to try a couple of business models:

  • Freemium (mostly free users; small percentage upgrades to paid)
  • Freemium + B2B SaaS (also have subscriptions for businesses)
  • One time fee for lifetime access
  • Pay for usage or flat fee?

We don’t want ads in our product, but any combination of free+paid we can try. We can make some educated guesses on what works, but ultimately consumers aren’t rational agents. How much users are willing to pay, if anything at all, depends on emotional factors that are hard to forecast. Can we charge based on the value we provide? Will customers price anchor based on competitors? Will customers feel strongly that software should never cost more than $X? We don’t know. Needless to say, with regard to pricing, we’re low conviction.

If we can’t drive enough traffic to our website to get trial signups in volume, then maybe we’ll pivot and introduce features that appeal to businesses. As we wrote about earlier, a business subscription is easily worth 30x a single user subscription. A B2B SaaS product can thrive on a trickle of traffic.

Marketing is the real bottleneck and biggest unknown. Given enough traffic and enough trial users I’m confident we’ll be able to fix all major issues in our product and the business side will take care of itself.

Most deals fail

One of the hardest parts of running a startup, next to doing the actual work, is knowing what to work on. There’s a seemingly endless list of things screaming “highest priority level”. One category in particular can be very distracting and time-consuming: deals and partnerships.

Especially when starting a business for the first time, all these deals can easily be mistaken for validation and important work, where in fact most of it is playing shop. The extra difficulty comes from the fact that you need just the right amount: you need to stay the course, but sometimes it helps to tack to beat against the wind.

The danger in saying yes to everything is that you just end up wantrepreneuring away your time. Most time should be spent on building your product, and talking to actual users. It’s very easy to spend all day jumping on calls with other startup folks, join in competitions, going to conferences, hang out with business networking groups, and not end up with a better product or a single customer. Trickier still are offers which actually look like they’re helpful. Especially when you just launch, you might see your inbox fill up with those very quickly, from amazing ad campaign offers to requests for collaborations.

One of those typical offers is a potential customer (or even an actual existing customer!) reaching out with an idea to get extra business. Wow, you just launched, and not only do you have a very passionate customer, but they’re willing to think along, have ideas of their own and spread the word for you!

What makes this difficult is that the common advice is to listen to your customers and use feedback to improve your product. But in my experience, anything more than getting feedback to learn more about the problem space, so you can then improve your product based on your own ideas, is a huge distraction. Proposals for deals or partnerships are cheap, and it will most likely be a lot of talk with very little result. Quite often you will end up becoming more of a freelancer building a solution which is only great for one customer. Stay the course and stick to your original mission.

We made this mistake too at the beginning. A customer reached out and thought our horizontal product would do especially well in their vertical. Perhaps we could white label it? They had a huge network in their market and were convinced they would be able to sell this easily to many of their customers and businesses in their network. Especially being technical founders, and only just having our first customers or two, only having to write a bit of whitelabel code and having someone do the sales to bring in even more, that’s amazing right? They just needed a few features which would be really critical for this market.

You can see where this is going. Only they ended up using the whitelabeling and extra features, for their own business. They never managed to refer anyone else or reach any other businesses. And of course why would they? Running your business is your job, not theirs. They aren’t as invested, it’s just a random idea for them. We all have random ideas, the execution is the hard part. Only as an owner of the business are you willing to do the actual hard work of building and selling, no customer is going to actually want to work as hard on that as you are.

Related offers to do affiliate marketing or marketing outreach for you will usually have the same result. Most of the time this just ends up being a way for a customer to ask for a discount or free plan in return for maybe telling others about your product. A better deal is to just not waste time on this and see if they want to pay so you have an actual customer.

Another very good example are emails from private equity firms or invitations to “chat” about investments or even potential acquisitions. If there’s a mother lode of distractions so large they can cost you your business, then this is it. But there’s so much to say about this (plenty of anecdotes there ;), that’s probably better for another post sometime.

The point is to remember with all these deals is that most of them will fail. They seem like a shortcut but they’re just be a distraction. What really moves the needle in the end is just improving your product and going to where your customers are to talk about it. The only caveat here is that sometimes saying yes increases your luck surface. Many good things in life can happen because of random connections, and business is no exception. As a rule of thumb that’s why I usually only say yes when the distraction is not too big and it’s either fun or to help someone and pay things forward. But time is limited so choose very wisely and say no most of the time to stay the course.

Wild ideas for Thymer

When you’re working on your first prototype for a new product you’ll inevitably come up with many wild ideas. It’s just part of the creative process. If you are a disciplined you won’t let yourself get distracted by actually building any of them, but it’s fun to think about what your product could be like one day.

Right now we focus 100% on what is strictly necessary to get a prototype done. The prototype has to have just enough functionality for us to get useful user feedback, but no more. Then we can iterate based on that feedback and fix flaws in our design.

That means we can’t add any of the stuff below to Thymer. Not yet, anyway.

Blog plugin. Use Thymer editor to write simple text based posts + maybe pictures. Render to static .html to publish.thymer.com or something like that. Maybe let users write public and private blog posts. If the Thymer editor is really good and you already have your notes in it, being able to share them makes sense. You could also share posts privately, with end-to-end encryption. Users would then need to enter a password to decrypt the shared note. It’s an easy plugin to write, and maybe it’s something people would like.

Kanban board plugin. Instead of rendering Thymer tasks as a vertical task list we can render them horizontally with tiles like a Kanban board. Add support for drag&drop. Enjoy easy planning.

Thymer is effectively a tree editor. Allowing users to view/edit their data in different and visual ways is probably an easy win for us.

Transclusions. A transclusion is when one document appears partially inside another document. Digital documents don’t need to be strictly linear, and it would be very cool to have something that’s more powerful than a plain hyperlink to another part of your Thymer document. We already need to make something where a planning view (an ordered list of things you plan to do next) can have items from anywhere on your document on it. Generalizing this concept and adding full-blown transclusions to Thymer might be worth it, because it unlocks opportunities down the road.

End-to-end encryption. Thymer is an offline-first app. You download all your data when the app loads, and it syncs in the background when/if you’re online. Because the app has to work offline the server doesn’t need to get involved during normal operation. That means we could just encrypt all data locally. Then the server would only see the tree structure of your document, but nothing content-wise. The major downsides here are that we won’t be able to offer server-side search, a practical API, or 3rd party integrations if the server can’t read the data. Personally I strongly favor apps that put encryption front and center. We’ll have to wait and see what the beta users think.

Roadmap plugin. Thymer will get a personal schedule where people can add tasks they plan to do Today, Tomorrow, Next week or whenever. But sometimes you want to do higher level and long term planning. We could make a plugin for that. It’s unclear at this point how it would work exactly, but if you have 5 or 10 people in a team you want to have some kind of overview where you can see what’s happening in broad strokes. Maybe this overlaps with Change History and Meeting Mode below. I don’t know.

Poweruser console. When you’re working with your own software you do bulk actions all the time. You find some objects based on some criteria, and apply some changes with a for loop. A REPL or a browser’s debug console are huge for productivity, but consumer apps never offer something like that. Why not? You can tediously make changes with point and click. If you’re lucky the app allows you to bulk move/delete, but that’s where it ends. I’d really like Thymer to have a REPL. Then users can do whatever they like with their data. Users of productivity apps have their idiosyncrasies, and the more Thymer can accommodate how people like to work the better.

Change history. Some way to see a what changed in a condensed way. If you get back from a holiday you want to see what people have been working on. How has the schedule changed? What items have been deleted/abandoned? Who is currently working on what? What decisions have been made in your absence? Ideally, you’d get some kind of executive summary that isn’t too long. Because the Thymer document is a tree it’s reasonable to to assume things higher up in the tree are more abstract/high level. Maybe a summary view can condense changes based on that.

Emoji Flags. People want to use their task list in different ways. We won’t be able to anticipate all our user’s needs, but we can provide people with options to organize their tasks to their own liking. We can store arbitrary metadata in tasks. Allowing users to choose their own status emojis doesn’t seem like a big stretch. Want to give a task a ⌛ or 🐳 status? Sure, why not.

Meeting mode. During a meeting some tasks get deleted, new tasks get added, tasks get assigned and reassigned, and people’s schedules get changed. You want to see what has been changed during the meeting separately from other changes made to the Thymer document throughout the day. Ideally meeting notes that contain the rationale get linked to the changes made to the Thymer document. I don’t think it makes sense to have meeting notes that duplicate the changes made in the Thymer planning. But when there are no meeting notes at all the “why” goes missing. Somebody who hasn’t attended the meeting should be able to see what has been discussed and what has changed as a consequence. I don’t think there is any product out there that gets this right, so it’s probably more difficult than it looks.


Any project, even something as simple as a todo list, will grow in scope if you let it. You can’t just add every random feature to your product. Your product will lose its cohesion and you’ll never launch. But you can write down all your half-baked ideas. Once you’ve got some users go back to the list and see if you can actually make some of your wild ideas reality.

Don’t let mistakes cascade

You’re in the kitchen, preparing a meal. You’re in a hurry and you’re hungry. So you move fast. You grab a plate from a cupboard but you drop it and it shatters. You bend over to pick up some shards and as you get up you hit your head on the cupboard door you left open. You curse and rub your head. As you walk to the trash bin to throw away some of the broken ceramic you notice a pot starts boiling over. You rush back to the stove to turn off the heat and step on a shard you hadn’t picked up earlier. Now your foot is bleeding. You want to move the pot from the stove but there is no available counter space. You try to shove it on there anyway. A plate pushes into a cutting board that in turn pushes into a couple of glasses that were precariously placed right next to the sink. They fall in, and break.

It’s 2am and your phone buzzes. You see a notification your app is down. You’re confused and wonder if it’s a false alarm, but you look at your email and you see a bunch of angry messages. Oh crap. You’re exhausted and groggy, but you open your laptop look at some logs. 500 errors everywhere. You realize yesterday’s feature update is the problem. You revert the code but the database is now newer than the app expects, and the ORM doesn’t know how to deal with the new columns. Now your app service doesn’t start at all anymore. You decide to drop the columns you added yesterday, but in your haste you drop the wrong column from the database and now you’re in a lot of trouble. Do you restore the database from backups? How old are the backups, do you accept the data loss? How long does restoring from backups take anyway? Do you want to restore only the missing column from backups? How long will that take? How will you fix all data inconsistencies? It’s now 2:30am, you can barely think straight, everything is down, your database is broken, and all your options look terrible.

This Is Fine GIF

These are stories of cascading mistakes. With one unforced error after another even something small can turn into a major headache. But errors don’t have to compound like this. If you just take a moment to stop and think these problems almost disappear. Imagine this, instead:

You’re in the kitchen, preparing a meal. You drop a plate and it shatters. You stop and pause for a full 10 seconds. Ask yourself what your next action should be. Answer: turn off the stove. Close the cupboard. Move things out of the way you might bump into. Then slowly clean up all the shards. Then stop for 10 seconds and ask yourself if you forgot something else. You decide to free up counter space by loading up the dishwasher. Then you resume cooking. Total delay? Maybe 5 minutes. Really no big deal.

It’s 11 at night and you finish a feature you’ve been working on. You’ve tested it, and it looks OK. You decide it’s too late to push to production. Certainly too late to do a database migration. The next morning you make some coffee and launch your feature. Everything seems fine, but after a couple of minutes you notice something weird in the error logs. A customer emails asking if the service is down. Uh-oh. You think for a minute and decide not to do a full rollback — you already migrated the database after all — but decide instead to stub out the feature. You only have to change one line of code. You reply to the customer with an apology. You fire up your dev VM and fix the bug. Looks good. Push to production. Email the customer again to inform them the problem is resolved. You’re not happy about the bumpy release, but it really wasn’t so bad.

Everybody messes up sometime. We do, too. But we’ve never had significant downtime. Never lost customer data. Never had a database migration go badly wrong. In part it’s luck, but in part it’s because we try hard not to make bad things worse.

  1. when something breaks the first thing we do is stop and reflect
  2. then we diagnose
  3. then we stop and think how the fix might backfire on us
  4. then we ask ourselves if the fix is something we can roll back if need be
  5. then we stop again to think of an easier fix
  6. and only then do we apply the fix and test if it worked

Afterwards, we look for ways to eliminate the root cause of the problem. In the case above, it’s better to release the database migration and the feature separately. That way you can roll back a buggy feature without even thinking about it. Additionally, you want to feature flag complicated new features. That way you can gradually release features in production, and when trouble arises you can just turn the feature off. It takes basically no extra effort to take these precautions, and they’ll save you a lot of time and aggravation when you do something dumb like pushing to production right before you go to bed.

Some more lessons we learned the hard way about cascading problems:

  1. Don’t do routine server maintenance when you’re in a hurry, when tired or distracted. Regular maintenance should only take a few minutes, but you have to be prepared for things to go very wrong. If you do maintenance at 11pm you risk having to work throughout the night and that’s just asking for mistakes to compound. Maintenance work is easy, but you want to do it in the morning when you’ve had your coffee and you’re fresh.
  2. Don’t hit send on emails when you’re tired or annoyed. It’s OK to let a draft be a draft and you can hit send in the morning.
  3. Have local on-machine nightly backups of all config in /etc/, deployment files, and everything you might break by accident. If you do something dumb and need to roll back in a hurry nothing beats being able to restore something with cp.

    Config backups like these saved me twice: one time I deleted a bunch of files in /etc on a production server that were necessary for the system to boot. Figuring out which Debian packages corresponded to the missing files is tricky and besides, the package manager won’t run if /etc is missing. Print directory structure with find for /etc and /backup/etc. Use diff to see which files are missing. cp -arf to restore. Use the -a (archive) flag so you restore user, group, access permissions, and atime/mtime along with the files themselves.

    Another time our JS compressor crashed and output partial data (on perfectly valid Javascript input no less) and there was no quick way to diagnose the problem. Our entire app was effectively down, so I needed a quick fix. It’s at those times that you really appreciate being able to restore last night’s JS bundle with a single copy command.

    You need a simple backup system that works every time. Some people put /etc under version control, but this isn’t great because every server is at least somewhat unique (e.g. /etc/hosts, ip bindings). Nightly backups that allow you to simply diff and see what changed will never fail you. Many backup systems try to be too clever and you need to google command line options for basic operations. rdiff-backup gets almost everything right, although it breaks if you try to back up too much data.
  4. Learn how to boot from a rescue environment and chroot into your system. chroot is basically magic. You can use this to fix your boot partition, broken packages, broken firewall/network config, mangled kernel installs and more.

    We’ve only had to use this trick twice in the last 10 years. If a server doesn’t come back after a reboot and you start sweating, that’s when you need to keep your head cool and do some quick diagnostics. You can fail over, but failover is not without risks, and if you have no clue what happened you don’t know if the failover server(s) will collapse in the same way. Downtime sucks, but you always have 5 minutes to do some preliminary diagnostics and to think carefully about the next steps to take.

The lesson here is so simple and also one of the hardest ones for me personally to learn:

Slow down. Breathe. Don’t make things worse. Consider your options before acting.

Mistakes are unavoidable, but if you don’t let small mistakes cascade into something bigger you’ll notice you’ll spend very little of your time putting out fires.

Your app needs a USP

Your app need a good answer to the question: “Why not go with the established competitor’s product?”. That’s what your Unique Selling Proposition (USP) is for. This is especially important when you start out, because a new product has fewer features than the competition. You also don’t have brand recognition. People buy Apple products just because they’re made by Apple. A startup doesn’t have that advantage.

Your product is also likely to have some serious shortcomings. It takes years for software to get good, so you need something to compensate for your lack of features, lack of brand, and other ways in which your product isn’t great.

You can try to compete on price. Just charge less than everybody else, right? Except, this can backfire on you in two ways. One, you send a signal that your product belongs in the “budget” section and is therefore worse than other products. And two, the cheapest products get the most difficult-to-please and most demanding customers. I’m not entirely sure why this is, but my hunch is that people who look for the cheapest products have a negative disposition. Maybe they’re afraid they’re getting taken advantage of, or maybe they resent having to pay for software in the first place. When you charge more you get customers that look at the value provided by your software and decide based on that to go ahead with a purchase. For the first kind of customer any price is too high. The second kind of customer will be happy if you explain in plain language what your product costs and what they get in exchange. You don’t want to be the most expensive product in your market and you don’t want to be the cheapest. Just be somewhere in the middle. Maybe somewhere the lower 3rd, that way you can easily raise your prices as your product gets better without pricing yourself out of the market.

Can you distinguish yourself with some really cool feature? Probably not. It might work in the beginning, but once you get some success your competitors will notice. Established businesses have more resources and most features can be copied. Usually competitors will make a feature that’s equivalent and not exactly identical, but it amounts to the same thing. The one feature that made your product unique has been commoditized and you go back to square one.

You also can’t distinguish yourself based on “universal benefits”. You can say your product is “fast”, or “easy to use” but every competitor will say the same. You can say your product is “secure”, but even competitors with the worst security practices (and the record to prove it!) can put any number of logos on their website that prove their product meets every industry standard. Ever noticed how companies with terrible customer support have these Customer Service awards plaques on their website? You should absolutely work your hardest to provide great service, but to really distinguish yourself you need more.

So you can’t compete by having more features, you can’t compete on price, you can’t compete with cool unique features. If none of these approaches are good, what can you do?

To differentiate yourself in a way that lasts your product needs to be something the competitors explicitly are not. Good products drive a wedge in a market where customers have to choose whether they want a product of Type A or Type B, but they can’t choose both. If you segment the market intelligently you’re the first and therefore best product in this new subcategory. This puts you as a new startup in a terrific position.

If you’re going to compete with Gmail you don’t want to be the product that’s cheaper (Gmail is already free) or the product that’s faster (Gmail used to be fast, too) or the product that has the most features. You want to be the product that is about privacy. No ads. You fight newsletter spam and email open tracking and other bad practices. What is Gmail going to do? Nothing! Gmail is an ad-based product, after all.

With Thymer we’re boldly choosing a text-based UI. Many people, like us, use text-based IDEs all day. It’s the kind of software interface we like, so odds are, other people will like it too. It’s not a feature our competitors can just copy, because it defines what our app is. If we succeed I’m sure people will try to copy us outright. That’s inevitable. If our app is good enough clones won’t hurt us much.

There is a final reason why it’s important to have a clear USP for your app. You want to be the best product for this new segment you’ve created. Any time you think about adding a new feature or adding some text to your product page you can ask yourself if it fits with your core theme. This helps you focus on what matters. You don’t want to dilute your vision, you want to make it stronger. It will put off many people, but those who like it will end up really liking your product. When you start out, that’s exactly what you want.