Underdog.io logo

This post was written by Chris Maddern (Co-Founder) & Max Bulger (Product Manager)

Button is creating a connected app ecosystem that improves inter-app user experience and app discoverability. The Button platform enables developers to effortlessly add Buttons to their app & build commerce partnerships. Buttons connect apps.


Tech Stack

On our back end, Button is composed of several services— each one of which is named after something or someone in the Wire (like Hamsterdam, our aggregation of inventory suppliers, Rawls, our quick-and-dirty stats service, or Sobotka, our logs shipper).

Each service is built with the language and tools that make the most sense for the use-case. These include:

  • Python. Our core storage service is built in Python.

  • Javascript (Node.js + Express). This is our go-to language for most services and makes up the bulk of our platform code base

  • Go. Golang is just great at some things and so we have a service written in Go - it’s also just fun to play with.

  • Ruby. Our marketing site and some of our internal tools are written in Ruby. It’s just great for CLIs and open source tooling.

For infrastructure, we host (almost) everything on Amazon EC2 and use S3 for storage. We also use Apache Mesos and Marathon for spinning up some of our smaller services. We Dockerize religiously and use Ansible to orchestrate deployment.

On the client side, we build native SDKs for Android & iOS so build with Java & Objective C, respectively. We do support Swift but there are a lot of challenges with writing SDKs with broad support in it. Gradle and Cocoapods are our preferred method of distribution.

We invest heavily in testing and have solid coverage across the board. On the client side, we do a lot of automation & screenshot testing to verify that everything is working as it should across versions, languages and partners; it’s the only way to be able to move fast and ship great software.


Engineering Focus

Button faces a wide range of challenges in developing our core technology and platform, but our biggest priority is always serving our partners and users with the highest standards of omotenashi. Serving our users means pushing the boundaries of what’s possible on Android and iOS to create seamless connections between apps, and to match the user’s intent with a high level of relevancy. To serve our partners, we have to create robust and reliable infrastructure that abstracts away fragmentation and complexity, and exposes our features through a simple interface. Balancing the needs of these three constituencies— end users, partners integrating our SDK’s and API’s, and the mobile platforms— can often be challenging and complex. Our client SDK must provide best-in-class user experience, absolutely minimal overhead for our integration partner’s app, and facilitate Button’s innovative AttendedInstall app download process and cross-app transactions.

As an SDK, we’re always a guest in another app. We think of it in terms of being a guest in somebody’s home - when you’re a guest, you don’t walk into the kitchen, grab a beer, put your feet up on the table and change the TV channel (I hope). You behave in a way that is respectful, doesn’t interfere with the normal operations or enjoyment of their home, and ends in being invited back. The same thing is true when being an SDK inside of somebody’s app; but the resources in question aren’t beers & televisions, they’re networking & permissions, background time & appearance.

The burden of quality and functionality isn’t on par with being in-house for our partners, it’s higher - it has to be better, more thoroughly tested with smoother animations & finer detail than our partner would expect to undergo the rigorous vetting that we expect any great company to do on partners that they let into their app.

On top of all of this, the area that we’re working in is at the forefront of the technology being worked on by both Apple & Google in iOS & Android, respectively, which means we have to be first-to-market with new features and advancements. Moving fast to build the best & most robust software we’ve ever seen is a fun challenge that we take on every day!

Our platform needs to aggregate a vast amount of data about partner inventory, user context and client requests, perform complex relevancy calculations, and expose all this to clients in a simple, transparent and highly performant interface. Because our product is built into critical user flows of partner applications, our platform also needs to shield clients from any upstream failures or inconsistencies in partner API’s.

With our partnership count continually growing, we centralized the API management for our partner inventory suppliers. This hub (called Hamsterdam) provides a system where new partnerships are quickly integrated without any sacrifice to customization, allowing us to showcase the unique use cases each partnership has to offer a user. The use of real-time data to drive the most contextual decisions on user experience is the heart of our “data decides” mentality. Our data pipeline allows us to react in real time based on user behavior, providing the most contextually relevant opportunities for users based on not just what they did last week, but also what they are doing right now.

Since our technology sits at the forefront of our partnership experience, our platform must provide a simple abstracted interface that can accommodate various domain concepts, models, uptime, and API styles with graceful degradation. After all, since our partnerships are global, we’re always making someone’s experience better!

Apply to top startup jobs in 60 seconds →

Sign up for Ruff Notes

Every week we send out a newsletter called Ruff Notes with our personal thoughts on something interesting we’ve read, as well as product updates and news from our community.