Good team culture strives for cohesion. Once organizations get large enough, a tension emerges between the culture of individual teams and the culture of the larger organization. How do you achieve team cohesion across small teams and the larger organizations they comprise?

The culture at Artsy is driven by every team member, not mandated or handed down from above. This adds another level of tension, between individuals and their smaller teams. Team working agreements embrace that tension to provide a framework for converting tension into healthy culture.

Read on →

Software deploys! What a concept. You have some code running somewhere, and you need to get it running somewhere else. What could possibly go wrong? While web developers have become accustom to some really slick deploy processes, iOS developers have to work within some very different constraints.

Today I want to explore the differences between deploying iOS software and front-end/back-end web software. Some of these differences are inherent to how the code gets executed, and some of the differences are incidental to choices that Apple has made. These are constraints that iOS developers need to work within. As Artsy has adopted React Native over the past four years, we have had more and more of our web engineering colleagues contributing to our iOS app. For these web engineers, getting familiar with the iOS deploy constraints is as important as getting to know Xcode and CocoaPods.

Read on →

Coordinating changes across many packages in the node ecosystem can be quite the challenge. You can use npm link or yarn link to create a symlink of the package you're developing on into another package, but it has some drawbacks. If you're doing local development and need to rapidly see updates and yarn link isn't working out there's always tools like yalc to help you out. That's really only for local development though.

What if you need to test packages together in a staging environment? Generally the approach would to be to deploy a canary version to npm that you can use in your staging environment. I'll go over how to do that and how Artsy automates it.

Read on →

It's the year 2020. You use a modern front-end stack of Relay, GraphQL, React and TypeScript. You can build an infinite scroll 'feed' type UI totally out of the box with these tools, by mostly putting together boilerplate (proper connections, along with a pagination container). You have a design system, and are rapidly building up a component library. Things are great!

Then you take a look at the latest design comps for a 'browse' type page, and you see that the controversial infinite scroll has been replaced by a more traditional pagination bar.

You know the one. Like the following, from Amazon:

You start to realize that the cursor-based setup of a connection, along with a Relay pagination container, does not lend itself to this more traditional UI. For one thing, a user can arbitrarily 'jump' to any page by including a ?page=X query param (typically). For another, the user can only actually see the current page of content, versus a feed. As you go to sleep and dream of REST, Rails controllers, kaminari, will_paginate, and a simpler time, you start to have a vision...

Read on →

In 2013, Artsy shipped the first version of our iOS app. Typical for an early-day startup, the app was a "minimum viable product" (with a big emphasis on "minimum"). One of the features that didn't make the cut was something you expect to see in most apps: a log out button.

When I joined Artsy a year later, there was still no log out button. And there would be no log out button for another six years, until today.

I want to talk about this quirk of our app, from both product and technical perspectives. Why wasn't this already in our app? Why was it so difficult to build? These are interesting questions, and their answers shed light on how products mature over time. I also want to talk about how we finally managed to prioritize this kinda weird feature request (spoilers: it was our company-wide hackathon). Let's go!

Read on →

This will be the first in a series of posts about how we used advanced GraphQL tooling and functionality to better handle errors occurring during query resolution, and better equip clients to reason about such errors.

The goal is to describe our current approach, but also do a deep dive into specific ways we've extended our GraphQL server to help us accomplish that. If you are an interested GraphQL user, you may find this useful, even if some of the larger context specifically around how we are using it to help standardize error handling doesn't apply.

Read on →

You are a software engineer.

You consider yourself an introvert, and you really appreciate "engineering time", where you prefer to work for extended uninterrupted periods because interruptions wreck you. You are used to being misunderstood. Ever since you can remember the people around you have been kind of baffling: they constantly fail to notice stuff that's really obvious and important to you, and then they have the audacity to get frustrated with you for not understanding them.

But whatever, you can deal with this, right? This is just how life goes, right? Everyone's like this, right?


Read on →

Regular readers of our blog might be familiar with Culture Amp, a tool Artsy uses to collect anonymous feedback and take action on cultural issues (we most recently discussed the tool in this blog post). At a company-wide level, Culture Amp has helped guide everything from Artsy's evolving culture, to our physical work spaces, to our support for remote work. At an engineering-team level, we've also been using Culture Amp to guide our choices in technology, documentation, and training.

In this blog post I'll be detailing a recent learning course we ran to share knowledge about how Artsy builds iOS software for our entire engineering team.

Read on →

Email! Electronic mail! What a concept! Like many companies, Artsy has built products on top of email, but this is a decision that (like many companies) Artsy periodically regrets. But overall, our email systems work well!

But what about when it doesn't? Well that's what today's blog post is about: what happens when things break and you don't know why?

Read on →