Hello! I'm Brad Jasper, an independent software developer (Web/iOS/Mac), follow me on Twitter at @bradjasper.

Focus

Focus is a Mac productivity app that blocks distracting websites. This is a write-up of some of the decisions that went into building the product. If you're interested you can download Focus or view the source code on GitHub.







The Idea

Focus is a small Mac app that blocks distracting websites and services.

I built it because when I'm working, I don't want to be distracted. But computers are getting better and better at distracting and interrupting us.

Focus is an easy way to say "I'm working" and shut everything out.

Evaluating the Market

There were already a few existing products that block distracting websites (the least of which is /etc/hosts), but none them hit all of my goals:

  • Simple, intuitive, stays out of your way
  • 1-click toggle from the menu bar
  • Easily undo (not "forcing" productivity)
  • Works without browser restart (some have internal DNS caches)
  • Works on instant messenger services
  • Only requires admin password one time
  • Ability to show custom message on blocked website

Since I didn't find any apps that satisfied my requirements, I decided to start building Focus.

For larger apps I would have spent more time validating the idea with customers. But since Focus was a small app that I personally wanted, I wasn't as worried about this.

Building the Product

Focus is a menu bar app.

Focus menu bar icon states
Focus modes in the menu bar (top to bottom): off, on, on (grayscale)

It doesn't have any windows (besides it's preferences window). This means I didn't have to write lots of UI or view code—rather most of the work on Focus was in the background.

Focus preferences window
Preferences window

Focus blocked sites window
Blocked websites window

Here are some of the major pieces of Focus that work in the background.


Privileged Helper Tool

Under-the-hood, Focus requires an administrator password for many of the tasks it performs, but constantly entering your password is a bad experience.

There are a few ways to solve this, but the best I found was using a privileged helper tool, which gets installed the first time the app is run. The helper tool keeps the escalated privileges and can receive messages from Focus to do the tasks it needs without asking the user for their password over and over.

Privileged Helper Tool installation
Example of helper tool being installed so password is only prompted once

Some other apps consider this password prompt a feature because it adds friction.

Focus doesn't take this approach. It's goal is to block interruptions and gently remind you when you get distracted—but not to force or annoy you.

If you want to get back to your blocked websites, you should be able to.


Blocking and Intercepting Websites

There are many ways to block and intercept websites, here's a few Focus explored:


/etc/hosts: The easiest way to block distracting websites is by using /etc/hosts, and this is what Focus originally used.

Unfortunately, some browsers have an internal cache and require a restart. This was painful enough to search for alternatives.


IPFW/PF: Mac OS X has built-in firewalls that can block IP's really well. They can even slow down traffic rather than block it directly, which is a great feature.

But managing the HOST -> IP conversion is a pain. Some hosts resolve to many IP addresses and resolving them can be slow.

Also, intercepting webpages and displaying custom content was harder than with other methods.


DNS: Setting up a custom DNS server that blocks host lookups is an option, but it also takes responsibility for the entire Internet connection, which is a big liability.

Plus, it is somewhat common for people to use custom DNS servers—so overal this wasn't the best option.


Automatic Proxy Configuration: The option Focus ended up using was called Automatic Proxy Configuration. Mac OS X has this built-in and is a way to configure proxies for certain sites dynamically—perfect!

This allowed Focus to intercept websites and display a custom message, without taking control of the entire network connection.

It relies on an Automatic Proxy Configuration file (PAC file), which is a file that contains a single Javascript function with instructions on routing.

This is what it looks like:

function FindProxyForURL(url, host) {
    if (dnsDomainIs(host,'facebook.com')) return 'PROXY custom.proxy1.com:8080';
    if (dnsDomainIs(host,'twitter.com')) return 'PROXY custom.proxy2.com:8080';
    // ...
    return 'DIRECT';
}


This ended up being a great option for Focus and it satisfied all major goals.

Serving a custom message instead of blocked website


One unique feature of Focus is intercepting the blocked website and displaying a custom message (a motivational quote by default).

Focus block message
Example of Focus blocking a website

This is accomplished using the Automatic Proxy Configuration option described above with a custom proxy server that can intercept requests and block them.

But it turns out you don't actually need a full proxy server to accomplish this, rather just a regular simple HTTP server.

On HTTP requests you can return a custom response, which works as expected.

On HTTPS requests, browsers are confused by the invalid proxy response and display a broken webpage—which is a suitable compromise for Focus (the alternative is installing custom root ceritificates, which is really insecure).

No Sandbox, No App Store


One bad thing I learned early on into the development of Focus was that it couldn't be in the App Store.

It requires administrator privileges because it modifies system-level network settings. Unfortunately this means Focus can't stay in a sandbox, so it can't be in the App Store.

I decided to build it anyway, but expect this will have a pretty significant negative effect on sales.

Unfinished Promotional Video


I wanted to do something fun and creative to promote Focus and decided on making a stop-motion promotional video.

I'd never filmed a promo video before, so started making short test videos and iterating on early concepts to try to learn and improve.

The videos improved significantly, but ultimately I decided not to pursue the promo video after I learned Focus couldn't be in the App Store. The size of the video project was growing and it was hard to justify that with a smaller app.

The early videos were just testing concepts and were never supposed to be released, but here is the first one :)

Conclusion

Focus was a fun app to build and I learned a lot during the process. I'm really happy with how everything came together and think it solves the problem of blocking distracting websites well.

Focus seems like a very simple app and in many ways it is. There are, however, a lot of decisions that happened behind-the-scenes to make everything come together in an elegant way. This was an outline of some of those biggest decisions and the reasoning behind them—hope you found it useful!

If you're interested you can download Focus or view the source code on GitHub.





Like this write-up? You can hire the developer behind it to work on your awesome project! My name is Brad and I'm a web & mobile developer who loves building great products with interesting people.

Email me to setup a time to talk about your project and see how I can help.