Always Solve for X

Reflecting back on the products I’ve released over the years I noticed a key difference between the successful products and the non-successful products. The difference wasn’t in market or craftsmanship. The difference started before I wrote a single line of code.

With ImageXY we were focused on designing a solution to real estate agents uploading photos that were the wrong size or too large into a crm. When building it we concentrated on that single use-case and kept our solution focused. The result was a batch image resizing app that didn’t have all the complexities of its competitors. And it turned out a lot of non-real estate agents also had the same problem and our solution worked for them as well.

Other products, like Byoyomi, a timer application that let you save and run multiple timers on your Mac, were flops. The application was stable and worked as advertised, but it was more of a solution in search of a problem.

As developers its easy to dive straight into writing code or designing interfaces the moment we have an idea that we think might work. And as a developer taking those random ideas and turning them into a reality is fun. But the chances of those inspiration-turned-hacking sessions turning into a successful product are slim.

Instead of diving into code the moment we have an idea, it’s critical that you do the hard work before your hacking sessions. The work that isn’t necessarily fun and feels like work. Take a step-back form Sketch and define, with words, the problem you’re trying to solve.

If you can’t clearly articulate the problem and who’s having that problem, any solution you build will be equally muddled.

When designing anything, you first need to define the problem that you’re trying to solve.

The major difference between my successful products and those that were just that. The successful products had a clear problem that they were solving for a specific niche while the unsuccessful ones did not. It’s much easier to solve for X when you’ve looked at the rest of the equation.

The Slow Web

It’s been almost 5 years since I wrote Slow is not a Dirty Word. Reflecting on the sentiment in that article, that the best things in life take time and we needn’t rush as society tries to force us, didn’t quite go far enough. The concept of Slow should also be applied to the web.

The Slow Web

What is the slow web? At it’s core it’s the idea that we shouldn’t fill our mind with junk and we should connect with those around us. Social media is fast food for the mind. Consuming it feels in the moment, but when you look back you’re not left with anything memorable. Moreover, because of the lack of nuance afforded by platforms, such as Twitter, it encourages behavior based on dopamine and adrenaline impulses.

  • The slow web is formulating your thoughts and expressing them fully.
  • The slow web is about owning what you produce.
  • The slow web is open.
  • The slow web is yours.

The Slow Web in Practice

For most people the slow web is best manifested as a blog. This could be a simple Wordpress blog, a micro.blog, a bunch of static files on a server somewhere, anything that works for you. The important part is that you have control of your content. That you can control how and when it appears.

Sharing

So much of sharing on the web these days is based on these social media platforms. So how do you get the word out about your new latest pieces in the slow web?

  • Writing unique content that matters to you and like-minded people will find it via search
  • RSS Feeds (standard in most all blogging systems)
  • POSSE (Publish (on your) Own Site, Syndicate Elsewhere

Ignore the Numbers

Knowing the number of visits to your website or article only serves to feed disappointment when one article doesn’t match your expectations. Avoiding that sense of failure will inevitability lead to a habit of not writing and only consuming.

Privacy

The common methods of tracking visits can not only break your site, it also invites an invasion of privacy for your readers. Are there more privacy-minded ways to collect visitor statistics? Yes. Do you even need to collect the information in the first place? Probably not.

Don’t Over Engineer

As technologies it’s often easy to get caught up in nuts and bolts. We’re want to build our websites to handle all the traffic the world can throw at it, so we setup database servers, build servers, deploy servers, proxy servers, and CDN caches. And for what? A trickle of traffic? All of this could be easily served off a single server, reducing operational complexity and reducing the places where things can break when you really just want to publish a blog.

Making the Jump

Making the jump to the slow web doesn’t mean you cannot participate in the social networks, you’re just changing the terms of engagement. Instead of being the default place to collect your thoughts and ideas, it simply becomes another channel to link back to your site.

Because you no longer tweet every clever thought you have into the void, you’re able to slow down your mind, formulate your thoughts, and take back control.

This isn't a masterpiece

Building your own products is hard. There are thousands of tiny decisions that need to be made and nobody else to make them for you. To make matters worse, no answer is EVER 100% correct.

So we make the best decision that we can.

And sometimes the decisions we thought were right, were wrong. So we take a step back.

We tell ourselves that next time, we’ll make a better decision. We decide not to do anything until we’re certain. But nothing ever is.

We paralyze ourselves with this fear. Fear that decision will be wrong. Fear that our effort will be wasted.

But by doing this we miss out on a big part of the process. We forget that learning what doesn’t work is just as important as learning what does.

“It needs to be perfect before we can show anyone”, we tell ourselves, “This is our masterpiece.”

But we shouldn’t think of this as our perfect masterpiece because then our work will never see the light of day. Exposing our work to criticism and different perspectives is the only way we can complete the creative process and improve our product.

Stop aiming for perfection and ship.

Fear vs Shipping

Ask 100 makers what they want to do more of and the answer is always to ship more work. Ask them why they don’t, and the common response is fear.

It’s a common issue that all makers face. You face it when you release a new product or upload a new video. I’m facing it now with this essay. We all get scared when it comes to submitting our work to the public.

We fear we have nothing to say, that it has already been said by others and that everybody already knows and understands it. We’re scared of judgement from strangers, that people on reddit will think we’re stupid. That nobody will show up and read our work. We’re anxious that our English isn’t good enough.

All of these “what-ifs” run through our heads and stop us from posting. We get paralyzed by the “Upload” or “Post” button. We sit down and watch TV instead. Consume more content rather than produce it. That way we don’t have to face the fear.

You look at all the other makers out there and think they are better than you as they don’t have the fear of shipping. You see them writing blog posts, sending newsletters and shipping new products. They mustn’t face the same fear as you right?

Wrong.

They have just learned one secret.

The anxiety of shipping never goes away. It just affects you less the more you ship.

The rate at which we ship things is directly proportionate to the amount of anxiety we feel when shipping.

It’s a very catch-22 situation. You are scared to ship, but the only way to get over that fear is to ship; and to do it often. The reason why you see makers like Justin Jackson, Brennan Dunn and Paul Jarvis produce so much stuff is because they consistently press that “post” button and so they are less anxious each time.

With practice and consistency you too will reduce the fear. It won’t ever go away completely, but you will learn to live with it, and next time you hear the little voice in the back of your head telling you it’s not good enough.

Don’t listen to it.

Press the “post” button, ship your work, and reduce the fear for next time.

Quality isn't an accident

How many times have you tried to plug in a USB cable and failed on the first try? If you’re like me that number is nearly the number of times I’ve ever attempted to connect a USB device. How many times has this happened with a network cable?

While most people have heard of the term kaizen, or continuous improvement, when talking about Toyota and it’s lean manufacturing principles, fewer have heard of kaizen’s unsung sibling poka-yoke, or mistake proofing.

The main idea of poka-yoke is to draw attention to human errors as they occur, so they can be corrected or prevented, reducing the number of defects in a product.

After observing a defect, we identify the root cause of the mistake, and then apply a fix or change in process that attempts to prevent the same error from happening again. This learning can then be applied to improve the design and function products.

Building your products with poka-yoke requires more initial effort, however the end result is a higher quality and more reliable product.

As developers, our tool to poka-yoke our services are unit tests.

Tests are small pieces of software that exercise a piece of code and verify that it’s behaving as intended. Writing tests are, however, many developers least favorite thing about creating software. We like to build new services and libraries because they’re fun and there is a sense of immediate gratification.

While writing good tests is time consuming and not fun. Setting up the scaffolding, defining test cases, and setting the test data can feel like tedious grunt work without an end in sight. However boring tests may be, they are essential to quality software.

With Kwoosh we’re aiming for high reliability, minimum regressions, and fast operations. Part of our testing strategy is to have “workflow” integration tests. These tests aim to help make certain that our tests are comprehensive while being easy to understand.

Each test currently has a maximum of two tests named ‘test_get_workflow’ and ‘test_post_workflow’. Each test then calls a series of descriptively named helper functions to assert behavior.

def test_get_workflow(self):
      # Make sure that anonymous users are redirected to login
      # and that users are denied access to data that's not theirs
      self.redirect_for_anon_get()
      self.not_found_for_wrong_account()

    # Check that our filter interface is filtering data properly so
    # calls to "mine" only show tasks assigned to me and so forth.
    self.filters_response(self.sub_task_data['title'], 'all', [])
    self.filters_response(self.my_task_data['title'], 'mine',
        [self.sub_task_data['title'],
        self.completed_task_data['title']])
    self.filters_response(self.completed_task_data['title'],
        'complete',
        [self.sub_task_data['title'],
        self.my_task_data['title']])

def test_post_workflow(self):
    # Make sure that all post requests are redirect
    # or return 405 and denied
    self.redirect_for_anon_post()
    self.post_not_allowed()

As a lot of the tests will have some helpers in common (such as confirming anonymous users get redirected to login), we can bundle up these helper methods in small classes and include them into the tests, reducing the amount of code we need to maintain.

Less code = Fewer places for bugs = Less maintenance

Having descriptively named helper methods will allow future me to glance at the test I wrote today and identify exactly what’s being tested, without having to read through hundreds of lines of code.

Quality isn’t many things. Quality isn’t free. It isn’t flashy. It isn’t fancy. And it sure as hell isn’t an accident.