The Obvious logo on a yellow background

We started Uncommon six years ago with a view to building beautiful, performant mobile applications. We were excited about the possibilities a powerful computer in everyone’s pocket allowed. Back when good design was yet to be recognised as ancillary to performance, we saw the possibilities that existed. We began with this vision: design for India and design for the future.


Like many other companies that started from a design-first approach, our clients often approached us as if we were interior decorators, whereas, a better analogy for the role we play is that of an architect. Rather than just picking out a new rug to tie a room together, we looked at the purpose that each space had, broke down some walls to allow people to flow from the kitchen to the dining room more easily, put in a modular shelving system to house a future book collection, and, in some cases, brought in a geologist to survey the bedrock that the house was built on.


Having worked with over 120+ clients, where others see dots, we see patterns. We have the advantage of…vantage. Of both having solved similar problems across different industries and having solved so many types of problems, that we’ve evolved a series of processes and ways of working that allow us to rapidly get up to speed on where our client’s problems lie, and what methods to follow to allow us to get to the right solution.


As technology becomes a necessity rather than a luxury, we hope to be the first port-of-call for any organisation that’s looking to use technology as a force-multiplier. Regardless of whether it’s an app-based startup, a paint manufacturer that’s looking at creating an internally-focused inventory management solution, or a massive consumer giant that’s looking to deliver a personalised experience for its customers, we believe that co-creating solutions with end-users, validation through prototyping and rapid iteration are the ways in which design can be channeled as a business-enabler.


We started our journey as a digital agency by setting ourselves up as an alternative to mainstream ways of thinking about software – we wanted to be, and were, uncommon. Over these years, we’ve now realised that we don’t want the processes that we follow or the ways in which we run our organisation to be limited to us – we don’t want these to be uncommon, we want these to be followed by everyone: we want to be more obvious.


We’re moving to a policy of public-by-default on all our processes, work and policies (check out our Playbook here). We’re making our work—and our ways of working—more obvious. We want our clients (and other designers, people who aren’t clients yet—anyone really) to take our ways of working and build on top of them. We will not come up with the obvious solutions but the solutions we do come up with will be obviously right.



As more of our work shifts to massive scale (into the hundreds of millions range from the tens of millions), design will need to be more obvious. It has to fit in with people’s lives, fit in with their contexts. Good design needs to be less uncommon, and far more present. It needs to be available. It needs to manifest less as the difference, and more as the default option.

Good design: it’s got to be Obvious.


Read more

I presented some work at Droidcon London 2018 on a particular problem I had solved using Android Path APIs nearly 2 years ago. Here I flesh out the problem and the steps that I took towards a solution. Project linked here.


I came across a problem on Stack Overflow in which an original poster wanted a custom progress view containing text within it. And this text needed to change its colour based on the background.




So when the background is orange, the text is white; when the background is white, the text needs to be orange. There is a similar problem related to underlying text by Romain Guy that introduced me to Path APIs for the very first time.


Why this particular problem?

I saw this problem posted in our local Android community Slack chat. I knew how to solve it thanks to Romain Guy’s article. I spent 3-4 hours building this animation where the color of the text changes based on the background. I finished the project, pushed it online, and made it open source here. I presented this solution to the original poster (OP) and it was exactly what they were looking for, and they were quite happy.

Tech behind the solution: Android Path APIs.

We started off with an introduction to set theory in order to help the audience understand the concept of operations that we applied to shapes, but in simpler terms using numbers. (The audience interaction was great fun ^_^ But we’ll skip that for now).

There are two parts to this:
— Left Hand Side (LHS): Curved rectangle with parts of text removed from it.
— Right Hand Side (RHS): Text with parts of curved rectangle removed from it.

Place LHS and RHS next to each other to create the complete animation.

When the seekbar position is updated, we update the width of the curved rectangle.










Place LHS and RHS next to each other and we get the full animation.













Conference Experience

My peers at Obvious were extremely supportive in helping me prepare for the talk. We had four rehearsals together. I did 20+ rehearsals on my own time to ensure the talk ran smoothly and the jokes landed!


I was very excited to take my first flight, and that it was an international flight to London. It was almost unbelievable, having pre-conference casual conversations in the party with Android developers I had followed for so many years. I met many cool Android devs working at Google, Facebook and other places. I got to speak to Android legends like Christina Lee, Jake Wharton, Stacy Devino and Florina Muntunescu. And of course, London was beautiful and extremely kind to me 🙂


The conference was huge and had thousands of people attending. There were 5 parallel talks all the time. I got to learn about interesting things in the Android world like Architecture Components, Android security, Coroutines and others.




London personal experiences

I had a good time on my own too! Cheese tasting, whiskey tasting, burgers, the Tower Bridge, Apple HQ, watching  The Play That Goes Wrong, pub-hopping with new friends, shopping and so much more!


Link to talk: 


Read more

At Obvious, we spend considerable time doing user research in all forms and sizes. Here, I want to talk about how I optimized my workflow for usability tests to build realistic prototypes faster. I don’t want to get into the importance of user research and why is it essential to validate our assumptions. There are many great articles and books about this. I want to share my learnings while building prototypes under time pressure. I assume in this post that the readers have a basic understanding of Sketch and Invision.

Why build a prototype?

We run a lot of usability tests in our work, whether it is for a Design Sprint or our own research and conceptualization cycle that we call Relay. These user interviews are often an hour long and we test our product design with real users. In most cases, the product hasn’t been developed as yet, and we have to show them a simulated prototype, a very rough version that can be built and stitched together in a day or two, maximum. If this prototype mimics a real product closely, the findings from the users are richer. Building a realistic prototype in one or two days is crazy, there is no better word to describe it. I want to share my key learning on how I try to make it happen.

The ability to plan well is an underrated skill. If we do a good job, everything is smooth sailing. Only when trouble arises do we look over what went wrong in planning.


In order to plan ahead, we need to know all the constraints that we are working with.

  • How well is the prototype I am going to build fleshed out?
  • How much time do I need to spend on design details?
  • How many existing resources and guidelines can I use so that I don’t waste time creating assets?
  • How familiar am I with Sketch?


Pro tip: For our prototype, I try to use as many existing resources as possible—Screenshots, Libraries, anything that saves time for asset creation in Sketch.


In our engagements, we usually have two designers working on a project. Ideally, the person who is building the prototype should not be the one preparing and conducting the interview. However, if it is the case that only one person is at work, it’s important to keep in mind that this is a lot of work and requires a chunk of your time.


In my experience, it is always better to take smaller portions of work, something that I know can be finished on time. There will always be some unforeseen situation blocking you here and there, so it’s a great idea to have a sizeable buffer time. Since we want the best and clearest results, it is always better to present a smaller, better-crafted prototype to your users rather than a huge apparatus that tends to fall apart every other click. All small details matter, like naming consistencies, real data, spellings and so on.


This is what I consider a reasonable amount of clarity and planning for a prototype for one of our projects. This is, of course, after 3 days of a Design Sprint so we already had a lot of clarity on the goals and ideas to achieve them at this point.


Do whatever is possible in Sketch

Building all the screens is probably the chunk of the work. Unfortunately, not much speeds up this process other than using screenshots and existing libraries. Once I have finished building all screens and assets, I start stitching the prototype together in Sketch. This helps me save a lot of time. Linking Screens online in the InVision page can be tedious, so doing as much as possible offline speeds things up. Here is a great Tutorial on what all can be done and how.


Pro tip: If you have a long scroll, you can create a link to any place on the same page and InVision transitions the screen quite nicely.


With the craft plugin installed, you can link any layer to an artboard. Select a layer (i.e. your CTA), press ‘c’ and click on any artboard to establish a connection.


This way, I connect all screens that can be connected offline until my entire prototype is stitched together. This process can slow your computer down a tiny bit but is much faster than doing it online. In this approach, I don’t have to create hotspots and can use the actual layers in my sketch file. If I decide to move a button later, the link moves with it.


100+ Artboards and multiples of that in connections linked together in Sketch from one of the prototypes that I used in a user study


Sync with Craft

There isn’t much left of the glory that the Craft plugin used to bring into Sketch, but syncing your artboards still works and that is all that I am using it for at the moment. It’s still quite useful as long as you don’t change the names of your artboards: you can change them and update them online, hassle-free.

A small confession: while building a prototype under time pressure, I don’t care about naming artboards at all, so you might find 50 artboards in InVision called ‘something copy 56’. But as I said, as long as the names are consistent, it doesn’t matter. And since you don’t have to link, and hence, find artboards online, it doesn’t matter. But this is only because it is a one-time effort and we throw the prototypes out after we’re done.


Pro tip:If I have to add some special event online that I cannot create in Sketch, I actually leave a bright note on the artboard that I can find it easily in the InVision preview.


Leaving notes on an artboard that I know what to do online.


Once I made the change online, I can remove the note in Sketch and sync the artboard again. It’s a truly quick and dirty style of building, but my prototypes need to survive only for a day, and so I don’t care about scalability or maintainability.


Be careful with overlays

Having a popover or a menu expanding somewhere is often a part of an interactive prototype. The InVision overlay functionality promises more control over how something appears on top of a screen, like fading and transparent backgrounds. Having said which, I don’t think they work very well in InVision. They tend to break the prototype and are often the opposite of a smooth transition. I’d rather use a new screen and de-prioritise a fading transition to get a stable prototype. I would advise caution when using overlays.


InVision auto-events

Sometimes, I need to bring up an onboarding screen — Coach Marks or some sort of helper — if the user is unable to proceed on her own. For example, a pop-up should ideally appear after the user is unable to proceed for more than 15 seconds. Auto-events are great for creating that illusion. The interface for InVision is easy and straightforward. It’s pretty easy to set duration and a destination in Invision since you browse through your screens.


At the cost of being laughed at, I just want to mention what ms (milliseconds) are to avoid the confusion I had for some time. 1 second has 1000ms. If I want a screen to come up after 9 seconds, I have to set the duration to 9000ms.


You can also use auto-events to create very crude animations. I once used it to create a loader that had only three states (30, 65, and 100 % full). The three states are three screens with auto-events happening on them after ca. 300ms (for animation, see the following paragraph). It gave the illusion of something happening at the background of the prototype and made it more real for the user. Overall, auto-events are great and I recommend them highly.



The power of Gifs

Enter: Gimock Plugin.

Whether it is a loader or a small animation, moving objects make the prototype better and these little details go a long way. This plugin costs 14 USD and is definitely worth the money. Making loaders is incredibly easy and even complex animations can be made in minutes. You can use Gifmock’s built-in features or turn artboards into frames and export them as a GIF. InVision supports GIFs without any problem. The only downside is that you have to manually upload the GIFs outside your Sketch file. The same overrides work if you update your source file but keep the same name.

This is the main reason I continue to use InVision and not the prototyping tools in Sketch and Figma; as animations like these can make quite a difference!


This animation in the form of a GIF was made in just 10 minutes, but I believe it really made a difference to the user who had to learn and understand a new functionality


Real, real data

Using ‘Lorem Ipsum’ or other random data in a prototype is never a good idea. It makes the prototype appear less real. It appears even less real in prototypes that contain user profiles or other personalised information. We need a prototype to be as real as possible in every aspect.  On the evening before an interview, it should be clear which user is attending and the names of users should be accessible for the person organising and scheduling the testing sessions. While there might not be a lot of time, it should be possible to make use of this information. It can make a big difference to find your own name in an app or website and it helps to establish a connection to the product and provide better insights during the testing session. Using real data shifts the session from a hypothetical scenario to a real scenario and that is the expectation that a prototype should fulfil.


In this screen recording, a user is looking for public acknowledgement of the contribution she made to a story. She is positively surprised to find her actual name on that very page and starts explaining why public acknowledgement is important for contributors. This gave me valuable insight into developing the feature which wouldn’t have been the same if I hadn’t used her actual name.


Record it

I don’t like taking notes. Especially when I am the one conducting the interview. So, I use Silverback to capture all that matters: what happens on the screen, the mouse movement, the sound and the user’s expression. This way, I can listen and see what happened at a later point when I want to summarise my findings. Silverback has a free version, too, if you don’t mind the watermark on your export. These recordings then become my validation and proof for the client as well. In any case, it is a good idea to record user testing sessions

(Hint: Always ask for consent to record. I remind myself of this by making this the first point on the notes I prepare for the interview).

Silverback makes it very easy to record different users in a session and export them all at once. It captures a picture of the user as a thumbnail for the video. In my opinion, it is a great piece of software and incredible value for money.


Pro tip: Listen to your recording at a higher speed, you still get all the information. For me, the maximum that works well is 1.6x.


I am quite excited to see other prototyping tools develop and improve the process, and I love to learn how other designers or prototypers deal with these challenges. I hope this article is of use to people with profiles similar to mine. If you want to find out more about the work that we do, or just have a chat, send a mail to


Read more

…and what we’re doing to build more diverse teams

We started Obvious six years ago and have since grown to a team of 20+ deeply-skilled craftspeople interested in design, technology, people and the intersection between these three. But there was a problem. Right from the get-go, our founding team was entirely male and between the ages of 25 and 30.


We know that we live and work in a world where certain groups are underrepresented in most spheres of work. In the design and technology space in India, most organisations are largely homogeneous entities with people whose experiences of life are by and large the same. Under representation is most visible in terms of gender, sexuality, disability and caste. We’ve been thinking about this, and about the ways in which we can change the status quo in our workplace.


We strongly believe that the strongest solutions (from technology and design perspectives) are made when a diversity of voices, opinions and perspectives are brought to bear on problems that our clients hire us to solve. We’ve learnt this from many (often disturbing) examples. Take for example ‘The Problem of the Abusive Ex’ —examples here and here. This is a prime example of what happens when technology solutions are designed primarily by people with a similar set of life experiences. There is also Inadvertent Algorithmic Cruelty, where even a well-intentioned product feature can lead to a situation of emotional distress for users (an idea from Eric Mayer who later wrote a book on the topic which you’re welcome to borrow from our library).


We need to be more diverse, not just because it makes business sense, but also because it makes us a better company. We’ve made some baby-steps towards a more inclusive work space. We wanted to share some of the progress we’ve made with you. If you’re from an underrepresented group, you can a) see what it might be like to work here, and b) exhort us to do better — we’re always open to suggestions and criticism. We try and do our best even though we work within the limits that exist for a small, self-funded company.


We’ve started work on changing our organisational DNA. Some of the things we have put in place are:


Paid Menstrual Leave

Following our compatriots Nilenso, we have adopted (read: wholesale stolen) a no-questions-asked menstrual leave policy.


Family health insurance which covers your spouse, and up to two children

While our health insurance is fairly comprehensive, we’re still trying to find a provider that covers domestic partners as well as mental health expenses.


Sane working hours, which allow for a life outside the office

Women all over the world work two jobs — one at the workplace, and another at home with household chores. We cannot change structural attitudes and practices that are deeply entrenched in society, of course, but we adhere to strict 40-hour working weeks. We do not penalise people who aren’t able to devote the entirety of their lives to writing code.


No late-evening events

The ability to travel safely and without hassle is heavily gendered. Transport for women is more expensive and far less safe. We try and ensure that our days end at consistent times. We don’t organise meetings and work events late in the evenings, taking care to ensure that nobody is excluded from valuable networking and career-building opportunities.


Paid Parental Leave

We were very pleased to discover that India has one of the more progressive maternity leave laws in the world. Mothers can take 26 weeks of leave after the birth of their child. We believe that fathers (and partners) should participate in the labour around…labour, and offer 12 weeks of paid paternity leave as well.


Clear policies on discrimination and sexual harassment, plus regular refresher workshops

Despite laws requiring all organisations in India with more than ten employees to set up a committee to address complaints about sexual harassment, implementation remains an uphill task. We have an independent committee whose decisions are mandatory to be accepted by management, backed by Parity Consulting, who serve as the external member on our ICC.

We make our clients aware that they are also covered by our prevention of sexual harassment guidelines, and build termination clauses into our contracts that would automatically trigger in the event of any reported sexual harassment.


Sponsoring community events (PyLadies and HasGeek)

If you’re running an event or a community that works with under-represented groups, you’re welcome to use our space (as PyLadies BLR has been). We work with HasGeek (an organisation we deeply respect) to build more diversity into their conferences. Their CEO, Zainab Bawa goes into more detail on their efforts here, here and here.

Many of us, including all three of our founders (Dhruv, Pratul and I) spend time meeting and mentoring people at the beginning of their careers. We try to make sure our time is available for people who are underrepresented.


Physical spaces
  • We’ve learnt from colleagues, friends and partners that work spaces often stigmatise menstruation. We know that something as simple as stocking menstrual supplies is not yet common sense. Learning from this, we make sure to stock necessary menstrual supplies in our bathrooms for free, and we hope this makes our workplace more welcoming.
  • Everyone comes in different shapes and sizes. We’ve put in considerable effort and expense to ensure that everyone in the office has ergonomic, height-adjustable furniture, allowing for a workspace which everyone can adapt to themselves.
  • We were not surprised to find that office temperatures are benchmarked against the metabolic rates of an average (wait for it) man, leading to uncomfortable working conditions for most female employees. An awareness of these gendered biases which have been codified into “standards” allows us to avoid them, and helps us create an office space which is more productive.


Which brings us back to what we wanted to talk about: if this is a workplace where you would like to be, please do write in. We’re looking for product designers, researchers, illustrators and developers for mobile devices and the web.

We do interesting work, with almost all the household name startups in India. This year, nearly 60% of our work will be openly-licensed (we’ll write about our open-source work soon on our website). We care deeply about our craft and the context in which our work will be used. Our work reaches hundreds of millions of people every month, and we sweat the details.

Write in to me, send me a DM on twitter, or drop by into our sunny Central Bangalore office. We’d love to work together.


Read more

I’ve been more or less mute for the last four weeks because I somehow managed to get an injury inside my throat. Not being able to talk means going out and meeting people is not much fun (wonder what that says about me), so I’ve been spending a lot of time tinkering at home.


… and some days I just do this


I’ve been curious for a while about how much impact merely including a JavaScript framework has on the performance of a web page. I started thinking about this a few months ago, when I spent a rather frustrating afternoon trying to improve the parse and evaluation time of a JavaScript bundle on a cheap phone, only to find that most of the bundle’s size was taken up by React and its associated libraries.


Truth is, when you build your application on top of a modern JavaScript framework, you agree to pay a certain baseline performance cost that can never be optimized away. In exchange for paying this cost, you gain maintainability, developer efficiency, and (hopefully) better performance during runtime.


Well, duh. You didn’t need me to tell you that.



However, let’s phrase this differently: when you build your app on top of a JavaScript framework, you’re making peace with the fact that your app will never load in less than X seconds, for some value of X that varies from framework to framework.


So what exactly is this baseline performance cost, this X? Glad you asked! I had a free afternoon and a Redmi 6A lying around, so I ran some numbers using React, Vue, and Angular.



Here’s how I arrived at the benchmark results you’ll see below:

  1. Initialized new React, Vue, and Angular projects using create-react-app, Vue CLI, and Angular CLI. I didn’t make any changes to the projects generated by these tools.
  2. Installed routing and data management libraries in each project, and made sure they were part of the JavaScript bundle.
  3. Deployed all three projects to Netlify. Here are the pages: React, VueAngular.
  4. Connected a Xiaomi Redmi 6A to my computer and ran a profile on all three pages using the Chrome DevTools.


The routing and data management libraries I used for each project were: react-router and redux for React, vue-router and vuex for Vue, and the built-in Angular router and ngrx for Angular.


When I ran my benchmarks, I was interested in two numbers:

  1. The time taken to download all the JavaScript required to render the page. I only took the content download time into account, and ignored the network latency, the time required to setup an SSL connection, etc. because I don’t have as much control over these factors as my bundle size.
  2. Time taken to parse, compile, and evaluate the JavaScript bundle

I should mention that the Redmi 6A is a pretty new device, and most Indian users are still using the older Redmi 5A with a slower CPU.


The Numbers

Here are the numbers, starting with the bundle sizes for each application.


Gzipped bundle sizes for all three frameworks plus their routing and data management libraries


Angular’s JavaScript bundle is about twice large as the bundles for Vue and React! My guess is that this is because Angular has a much larger API surface and ships with the entirety of RxJS. I’m hoping somebody more familiar with Angular can enlighten me here.


Time requires to parse and evaluate the JavaScript bundle for each framework


While it takes a respectable 200 milliseconds for Chrome to parse and evaluate the React and Vue bundles, it takes over half a second to evaluate the Angular bundle. That’s a large enough interval for your users to notice, and can really cut into your performance budget.


Content download time, without taking network latency and other factors into account


Unsurprisingly, the React and Vue bundles are downloaded in under a second, but the Angular bundle takes over 2 seconds to download.

What’s important here is not how large or small the numbers are, or the relative performance of the three frameworks compared to each other. What’s noteworthy is the fact that your React application will never load faster than about 1.1 seconds on an average phone in India, no matter how much you optimize it. Your Angular app will always take at least 2.7 seconds to boot up. The users of your Vue app will need to wait at least 1 second before they can start using it.


This is when we haven’t even started looking at some of the other essential libraries that most projects end up using. This includes polyfills, form management libraries, date and time libraries, utility libraries such as lodash, drag and drop libraries, charting libraries, etc.



If you want your application to become interactive on your users’ devices in under 5 seconds, can you afford to spend a fifth of that time just booting up React?


Are Frameworks Evil?

I’m not advocating that frameworks are evil, or that you should write all your applications in VanillaJS. That would waste far too much productive developer time, and the result will probably end up performing badly at runtime. Frameworks exist for a reason.


But it’s important to consider your audience. If you’re building for resource constrained devices — which you certainly are if your product targets a country like India — you could consider using a lighter framework such as Riot or Preact. Your users will thank you.


Or consider not using a framework at all. For websites that primarily display content, it’s more efficient and cost-effective to just send some server-rendered HTML down the wire. If there are areas of your website that require interactivity, you can always use JavaScript to build those specific parts.


In the end, it’s important to strike a balance between developer productivity and user experience. The answer will vary from project to project, so don’t take anyone’s advice as gospel. Build for your own audience, not somebody else’s. Run benchmarks on devices that represent real-world scenarios, and then decide what technologies make sense for you.


Read more

Every aspect of Obvious is an opportunity to apply design thinking to situations and our infrastructure is no exception: we live on the internet —and therefore, our internet should always be alive. When it was time to redo our office network, the question I asked myself was: can it be a pleasure to set up, manage, and derive insights from something as mundane as our network connection?

I have deep doubts and misgivings about WiFi (reasons in detail here), so one of the key requirements that I gave our architects when we were renovating our office was that every desk should have an ethernet port, directly connected to our network backbone for full-duplex, gigabit internet access at every workstation. One post which I kept going back to while designing our office was Joel Spolsky’s “Bionic Office” (from 2003!):

Every office has its own 8-port network switch, so you can plug in your laptop and your desktop and your Macintosh and that old computer you keep around to read Joel on Software when your main computer is rebooting to install today’s Windows Update, and still have 3 ports left over (attention math geniuses: no need to email. One port is the uplink.) I sneer at silly building managers who still think that one LAN port per office is about right. For lawyers, maybe.

However, in addition to dedicated ethernet ports, we also need to have excellent WiFi — as our work and our devices are far more mobile than when Joel wrote about the Bionic Office.

Enter Ubiquiti

It was unsurprising to find that Ubiquti was founded by an ex-Apple engineer. Their products are elegantly plain, mostly white and glow gently, a-la the old Macbook breathing LEDs (which I miss sorely). Their wireless access points blend into the surroundings, unlike “high-end” consumer routers (Exhibits A, B, C and oh dear god what).

Unifi’s Wireless Access Points even have “skins” to match their surroundings

Ubiquiti (and other semi-professional networking equipment) separate out routing, switching and WiFi access into separate devices which perform one function well. Our internet comes into their router — the Unifi Security Gateway Pro, which supports multiple ISPs for failover and load-balancing.

Our router

The next piece of equipment is our core network switch — a managed switch with power-over-ethernet. This powers a bunch of smaller devices, including our network controller, a RIPE Atlas probe (courtesy @louiswu) and potentially thin clients or IP cameras in the future.

Any port in a storm

The cool thing about a PoE-switch is that the wireless access points don’t require a separate power cable, and draw their power right off the network cable. This really simplifies where you can place them — you don’t require a power outlet to set up an access point. We have two AC Pro routers, which are honestly probably overkill for the amount of space that we have.


Enough about the hardware — the coolest part about Ubiquti is what they call “software-defined-networking”. Their control interface is fantastically cool — and looks something like this:

The Unifi Dashboard
Speed tests (L) and Network Topology (R)
Live coverage maps (L) and detailed port statistics (R)

I can easily spot issues with either our network traffic, see if there are particular access points which are overloaded, upgrade firmware on all the network connected devices — it even has an extremely well-designed mobile app, which you can use to login to all your networks from anywhere in the world, and perform fixes, diagnose problems, all the sys-admin-y tasks that you would usually have to be on the same network to perform.


Don’t buy any Ubiquiti gear off Amazon/Flipkart. Prices there are highly inflated. Look at Ubiquiti’s prices on their US website, and don’t pay more than 5–10% extra. We’ve had good results with the following dealers:

To redo your home network, all you probably need is an access point (or two). You can run their controller on any computer, and can reuse your existing router. You can then add to your network iteratively, adding in the Security Gateway or a managed switch over time.

Alternatively, for an even simpler approach, where you sacrifice some configuration ability, look at their Amplifi range. This is a mesh system, with beautifully designed hardware.

Pretty fly for a WiFi…

We accomplished all our goals with this network gear:

  1. Fast and reliable internet across our entire office
  2. Easy to set up failover, load-balancing and scales to hundreds of users
  3. Simple enough for a non-technical person like myself to set up and run
  4. Isolated guest networks with simple login, bandwidth restrictions
  5. Passes the critical Designer Test: looks and works elegantly

It looks like we’re also in good company:


The only unfortunate part of this entire story is that now having seen how elegant and stable this network is, I am undertaking an expensive exercise to replace all the routers and access points both at home and at my parents with this gear.

Read more

When Obvious was brought in to refactor a big legacy app last year, we found ourselves in a strange situation. Our client was maintaining a common library for handling networking — HTTP, FCM, MQTT — across all apps under their brand. This library (let’s call it SadLibrary) had an API that was badly designed and dated, but not using it was not an option — a dedicated team was working on it and their manager started showing signs of protest.

Most modern Android apps use Retrofit to access REST-style APIs in an elegant and simple way. We wanted to see if we could make Retrofit work with SadLibrary and decided to give it a shot. Our initial idea was to fork Retrofit as RetroUnfit and plug-in SadLibrary instead of OkHttp. Thankfully, this spectacularly bad idea was shot down in no time. After going through Retrofit’s code, learning how Retrofit delegates calls to OkHttp and, how OkHttp further delegates them to interceptors, we realized that the correct solution was far simpler.

OkHttp and The Magical Interceptors

For those unaware, OkHttp uses interceptors for not only letting clients hook into calls and modify their request/response bodies, but also for finally running the call on the network. This is done inside the very last interceptor and can be seen in action here: okhttp3.RealCall#194.

So to make Retrofit work with SadLibrary, all we needed to do was add an interceptor that redirects all network requests from OkHttp and forwards them to SadLibrary. Here’s an example:

Using this interceptor is no different from using any other OkHttp interceptor:

That’s all! Retrofit could now be used for making network calls without dealing with SadLibrary and its sad API!

Making Retrofit work for you

Using Retrofit in this manner is very similar to what Nick Butcher does in his beautiful Dribbble client, Plaid. Since Dribbble does not provide a search API, Plaid manually downloads the search page as HTML and parses it using Jsoup. But, instead of leaking this ugliness to the rest of the app, this functionality is exposed through Retrofit as if it were an actual Dribbble API.

The response body is parsed inside a Retrofit Converter:


And used like a boss:


You can watch Jake Wharton explain this in more detail in his talk, Making Retrofit Work For You (GDG Cincinnati).

Cover photo by Bryan Colosky.

Read more

Over the last three months, we’ve been busy at work setting up our new, Central Bangalore office.



We’re finally settled in, and we’d love you to come by and say hi, have a $BEVERAGE_OF_CHOICE and shoot the breeze. Feel free to bring a friend, or three.


When Where How What


Date and Time

7pm onward, Friday the 13th, 2018



#40 Primrose Road,
Bangalore — 560025

Or just ask Google.



If coming from North Bangalore/MG Road: Turn left off MG Road, just before Prestige Meridian. Come down on Primrose Road and pass Happy Belly Bakes on your left. Take the first right turn. Our office is the third building on the left.

If coming from South Bangalore/Residency Road: Turn right next to Garuda Mall/HomeStop, and make the first left turn onto Primrose Road. Take the first left turn and our office is the third building on the left.

Public Transport: The Trinity Circle Metro station is the closest to our office. Get off and walk towards Prestige Meridian (~400m), turn left onto Primrose Road. Walk down and make the first right turn after Happy Belly Bakes. Our office is the third building on the left.



We have very limited parking and encourage you to use public transport, or bicycle to work (helmets and safety gear compulsory). We will have bicycle parking in the driveway.


Dress Code



Pratul Kalia | | +91 95355 20400
Wolfram Thurm | | +91 97414 33463


Code of Conduct

Uncommon does not currently have a code of conduct in place. Until such time as we do, we are borrowing from work done by the Ada Initiative. We require everyone attending an event organised by us whether social or otherwise, to read, agree and abide by the code of conduct listed below:

Please note: Replace “Conference” with “Event” in the previous link.


Read more

Spans in Android are something that don’t get as much attention as they deserve for how widely they’re used across the platform. I was fortunate to be able to talk about them at Droidcon San Francisco this year.


Do you know what’s common between the blinking cursor, hyperlinks and text highlighting in TextViews? They’re all implemented using spans. Spans are tiny objects that Android uses heavily across the framework.


If you’ve worked with text styling such as bold or italics, then you’re already familiar with the basic usages of spans. But they are capable of much more than just modifying the visual representation of text like changing indentation, receiving URL clicks, listening to text changes, displaying spelling suggestions, images and much more.


This talk will do a deep dive on the various spans that Android offers out of the box as well as custom spans and how they can be used for displaying text in any way imaginable.


You can also find the slides here:


The lesser known world of spans — Droidcon San Francisco was originally published in uncommon on Medium, where people are continuing the conversation by highlighting and responding to this story.


Read more

One of the methods we use a lot in our everyday battles with Android is findViewById(). It lets us find Views from layouts written in XML and returns a reference to their Java objects. And yet we know very little about how this thing works. How do layouts hierarchies written in XML get automatically converted to Java objects and delivered back to us in our Activities?

To understand this, we need to look at Android as a pure Java framework. For anything written in XML, the framework spends extra effort converting that into Java. Layouts are the best example of this and the class responsible for “inflating” them is LayoutInflater, which is precisely what we’re going to explore in this post.

Example usage of LayoutInflater in Fragment#onCreate()


The entry point to LayoutInflater is its inflate() method and we use it in a lot of places:

  • Fragments,for inflating their layouts.
  • Adapter backed Views,for inflating the layout of each item in a RecyclerViewSpinner, etc.
  • Activities: This is not obvious, but every call to setContentView()internally gets routed to LayoutInflater. The source for this can be seen in PhoneWindow (or AppCompatDelegateImplV7 when extending AppCompatActivity).


LayoutInflater begins with the root ViewGroup of a layout and recursively starts inflating its child Views, forming a tree of View objects. For each View found in the layout hierarchy, it instantiates its equivalent Java object in three steps:

1. Parsing XML using XmlPullParser

The first step involves parsing the View name (e.g., TextView) and its attributes from the XML layout file. This is done using the help of a class known as XmlPullParser, which is an XML parser (just like Moshi for JSON).

2. Constructing attributes using AttributeSet

After reading a View from XML, the second step involves understanding its plain values read by XmlPullParser and constructing a data-set out of them. This includes:

  • Understanding the unit of a value like “24dp”.
  • Following the reference to an external layout in <include layout=@layout/include_toolbar" />.
  • Resolving resource identifiers. That is, figuring out if
    @drawable-v21/button_background.xml should be used over @drawable/button_background.xml depending on the API level.
  • Resolving duplicate attributes from different sources. This usually happens when the same property is defined inline on a View as well as inside a style applied on it.

3. Instantiating View object using reflection

After extracting data in the first two steps, herein lies the most interesting part of LayoutInflater. Using the View’s name and attributes, LayoutInflater attempts to instantiate its Java object in a trial and error manner using reflection.

For those unaware, reflection is like black magic. It lets you examine the type system of a class at runtime, making it possible to access & modify members of a class (fields and methods) that are otherwise private or inaccessible, including invoking the constructors of the class:

Class<?> cl = Class.forName("com.example.SomeClass");
Constructor<?> cons = cl.getConstructor(Param1.class, Param2.class);

LayoutInflater uses this same magic for instantiating the View’s object by passing its fully qualified name to Context#getClassLoader()#loadClass().

For extracting the fully qualified name, LayoutInflater categorizes Views into custom Views and framework Views by using a hack: searching for dots in the name. If dots are found, the View is categorized as a custom View and a framework view otherwise. Beautiful!, line #748.

a) Framework Views

For framework Views like TextViewImageView, etc., which do not require their fully qualified names in XML, LayoutInflater attempts to guess the package name in a trial and error manner:

String[] potentialPackageNames = {
for (String packageName : potentialPackageNames) {
    try {
        View view = createView(packageName, viewName);
        if (view != null) {
            return view;
    } catch (ClassNotFoundException e) {

In each iteration, the createView() method attempts to invoke the constructor:

TextView textView = (TextView) context
        .loadClass(packageName + ".TextView")

b) Custom Views

On the other hand, for custom Views it is impossible for LayoutInflater to guess the location of their sources. That is exactly why Android requires their fully qualified names in XML layouts, which LayoutInflater can directly use for invoking their constructors:

RecyclerView recyclerView = (RecyclerView) getContext()

In case the loadClass() call results in a ClassNotFoundException because an invalid View was found in our XML layout, LayoutInflater re-throws it as an “Error inflating class” exception.

And that’s it.

With each inflation, LayoutInflater links the instantiated View to its parent ViewGroup and its children Views, essentially creating a tree of our View hierarchy. The View then simply traverses these links every time findViewById() gets called.

The use of reflection by LayoutInflater makes it an expensive and slow process, which is one of the reasons we should avoid complex View hierarchies. Not doing so directly affects the startup time for Activities, Fragments or any adapter backed ViewGroup.

There’s another interesting step involved in the inflation of layouts that I decided not to include in this article because of its complexity: Layout Factories. They are classes that can hook into the inflation process for generating their own Views and are used by AppCompat (for backporting material design to API levels below Lollipop) and Calligraphy (for applying custom fonts without using custom Views). Look at the Calligraphy source for more details on how layout factories are used.

Read more

Interface design has moved from Photoshop to a new contender: Sketch. Designed by Bohemian Coding, a company with less than 20 people, it has eclipsed the nearly 5-billion dollar behemoth, Adobe, to capture more than a third of the market for digital design. There are lots of good articles and blog posts that one can read to get the hang of it (for switching from Photoshop check here, for the learning community behind Sketch here and the Sketch collection on Medium here).

We challenge our tools all the time and I am personally very excited to see the evolution of live-collaboration within tools like Figma for instance. However, in this article, I want to share how I use Sketch, what works for me and what I have learned along the way.

Things to consider before you even start…

Following a few simple steps can simplify your life, especially when you work on large projects or when more then one person is working on the same Sketch file. Even though I know that following these rules can be annoying at times, for me it proves itself worthwhile every single time.

Always work on a clean file…

That sounds obvious, but it’s very crucial to actually do it. I structure my files by the features of the application that I am designing. For example, if I were working on a mobile taxi-hailing app, I might structure my file as follows:

  • 01-Login
  • 02-Home
  • 03–Ride
  • 04-Food
  • …and so on and so forth

That means I use one page for each flow or a feature. That allows me to name Pages and Artboards in a way that when we present work to each other or clients, it’s easy to identify exactly which screen we are talking about.

Since every Artboard across our Sketch document now has a unique ID, I can identify each Artboard individually and don’t have any duplicates like Enter Name or Menu etc.

I find this very helpful when I have to navigate a client through a flow over a phone call or Skype. It’s much easier to say “Screen 04a goes to 07g and then to 08b”.

Parent Folder / Child Folder / Grandchild

You can use a slash (/) to tell Sketch to create a folder structure. For example, when you export your screens, Sketch uses the titles of the artboards with the slash as a folder separator. So, a title like this “01-Login/01a-Login with Facebook” creates a file called “01-Login with Facebook” under a folder called “01-Login”. The same thing works for nested symbols and styles.

ProTip: How to use the Slash to create a folder structure in your Sketch exports

Name your layers…all of them!

Well, that sounds like a lot of work but it isn’t at all, considering the amount of time I save later in my design process. I follow a very simple, yet very effective rule. Name a layer for what it is, and not what is in it. So all these layers called Group671 (yes, it took me a while to learn that lesson) should become something like List Item Double Row or Full Bleed Button. Now I don’t use names like Enter Phone Number or Select All. Instead, I call them Single Line Text Input and Menu Item. This goes very well with the search panel in Sketch when you want to select the same elements across multiple Artboards.

Sketch has Symbols and Styles — and they are very powerful tools!

There are many good articles out there already that explain Symbols and styles very well. There are also Text Styles and Shared Styles. These are one of the reasons that Sketch is so great.

Most UI elements can be converted into symbols, and believe me, that saves a lot of time. Sketch has improved the functionality of symbols quite a bit — in the latest update, for example, you can even swap nested symbols. While this might seem advanced at first, once you’re designing lots of screens, you’ll need to utilize these options to tame your files!

UI elements library

I use symbols to create libraries of UI elements. Once we hand over our Sketch source file to a client, we make sure they get something that our client’s in-house team can take forward easily. That way it becomes very easy to extend the design later, for example, to add a feature or functionality. Similarly when handing over a file to developers one should be able to find all assets well organised so that the transition from Design to Development is as seamless as possible.

We create libraries using symbols

Text Styles

One way to use text styles is to set up a style guide before you even start your file. This, however, implies that you already know how many, and what kind of text styles you need. I create a text style library along the design process and name them according to their function. That way it becomes easy to change and adjust them later on. As before, use the ‘/’ to organise your styles in folders according to their function i.e. Dialog/Title or App Bar/Tab Inactive.

Grids are great!

They are easy to make…

You need them all the time, so never waste time on difficult margin adjustments and copies of layers. Especially when you want to be pixel perfect — I know that Sketch allows you to use fractions of pixels, but having the option doesn’t mean it should be used. Ever.

Design in a grid

You can set up a grid according to your Layout and Control+Gswitches the Grid on and off. If you are designing for mobile just keep it at 8px — life will get much easier.

Shortcuts that I can’t work without

Ok, most people probably know all of them, but just in case, there are some essential ones that one has to know. Standard shortcuts like hold Shift while transforming to keep the ratio, are the same in Sketch as they are everywhere else.

  • cmd+alt+v: this lets you paste the style of any object into another object
  • cmd+shift+v: this lets you paste in the same place. For instance, pasting something from one group into another in the same art-board.
  • cmd+click: Simple, yet extremely useful. having pressed cmd you can select any layer no matter how deep it is nested inside a group.
  • Don’t browse through your layer list to get into higher levels in your groups. Just press Esc.
  • If you looking for another layer in the same group, press Tab to go through them one by one.
  • Press Alt to measure all the distances
  • Use A to create an Artboard, S for Slice, R for Rectangle, U for Rounded Rectangle, O for Oval/Circle, L for Line, V for Vector, P for Pencil and T for Text.

Well, most of all one should go through this list of shortcuts and start using them. They will help you speed up a lot. Once you start using plugins, their custom shortcuts are also very useful!

Plugins we use on a daily basis

Speaking of plugins: they are the best, and they make Sketch incredibly powerful. You can make your own Plugins and there are tons already out there and new ones coming out all the time. Consider signing up to the Sketch Newsletter to stay updated. The ones below are the ones I use and find essential every day.

  • Sketch Toolbox: lets you download, install and manage all plugins that are out there in one place.
  • Craft by InVision: this is probably the most powerful Plugin out there. Sync your work, create a style library, pull in placeholder images, stock and life data (text, pictures, tables) and duplicate elaborate nested groups having full control over individual content (think of contact lists, an email inbox, picture grid etc). You even can have one style library that you share across multiple Sketch documents. That means if you want to change one colour in all of you screens as well as in multiple files you can do that with one single click. And I am quite excited about Craft Prototype when it fully releases.
  • Remove Unused Symbols: Well, let’s just say not all of my Symbols survive the design process and as I said earlier, having a well-sorted symbol page is great, make sure you get rid of what you don’t need.
  • Rename It: a very useful plugin, to rename multiple Layers or Artboards at one go. You can sequence them, add dimensions and much more.
  • Sketch Commands: Everything and the kitchen sink. It’s best to go through the documentation; this plugin definitely comes in handy.
  • Sketch Constraints: When you design for multiple screen sizes, there is no way around this one. You can define any position and alignment relative to other objects as well as borders.
  • Relabel Button: this is quite a simple plugin, but I use it all the time. It means that no matter what the label of your button is, the margins stay the same. The cool thing is that works for any kind of bounding box.

Handing over finished designs to our friendly developers in a way that they can easily use is extremely important. Zeplin offers exactly that. Its integration with Sketch makes this process super easy.

In Conclusion

The set of available design tools is ever changing and improving. I always try to explore different ways of getting things done and exploring new tools which allow us to do new kinds of design work. For me, that means following a very simple rule: never be afraid of learning a new tool, even if it means investing some extra time in the beginning. Nothing is worse than stagnation, especially in design.

If you have better ways of doing things do let me know below. I am always eager to learn and to improve the design process that I follow.

Read more