# Artsy

Artsy Mobile 2025 Wrapped ...

This is one page of public article previews, not the complete archive. Follow Next page to continue. Summaries are not the original full articles.

## Artsy Mobile 2025 Wrapped

DevFeed: [Artsy Mobile 2025 Wrapped](<https://devfeed.tech/articles/artsy-mobile-2025-wrapped-19167.md>)

Original publisher: [Read original article](<https://artsy.github.io/blog/2026/01/09/artsy-mobile-2025-wrapped/>)

Published: 2026-01-09T00:00:00Z

Content type: article

Language: en

Sources: [Artsy](<https://devfeed.tech/sources/artsy.md>)

Topics: [React Native](<https://devfeed.tech/topics/react-native.md>), [Expo](<https://devfeed.tech/topics/expo.md>), [Mobile](<https://devfeed.tech/topics/mobile.md>), [Tech Debt](<https://devfeed.tech/topics/tech-debt.md>), [migration](<https://devfeed.tech/topics/migration.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [ios](<https://devfeed.tech/tags/ios.md>), [migration](<https://devfeed.tech/tags/migration.md>), [mobile](<https://devfeed.tech/tags/mobile.md>), [mobile-apps](<https://devfeed.tech/tags/mobile-apps.md>), [react-native](<https://devfeed.tech/tags/react-native.md>), [tech-debt](<https://devfeed.tech/tags/tech-debt.md>)

### AI overview

Artsy reviews 2025 improvements to its mobile apps, including adopting Expo, moving all apps to React Native's new architecture, refactoring navigation, and addressing legacy code and technical debt.

### Source excerpt

The past year has been an exciting one for our mobile apps (Artsy, Folio and Palette Mobile) and we started to finally get closer to where we want to be: High-performing and developer-friendly React Native applications, enabling rapid feature iteration and a superior user experience. We would like to share with you some of the improvements we made that might also be applicable to your react-native app. Infra Expo! At the end of 2024, after RFC: Trial Expo in Energy and/or Palette-Mobile, Spike on Eigen Risks, Rewards and Effort, we decided that we are giving Expo a try. Quickly afterwards, we added Expo with Prebuild on 2 out of 3 of our Apps: The CMS App, named Folio and our design system app, named Palette-Mobile. For our main app, Eigen, adding expo sdk happened faster than we thought after Microsoft decided to retire VS App Center. We needed an alternative for code-push, and we settled for Expo over-the-air updates. Eigen still has a lot of native code blocking us from fully migrating to Continue Native Generation (CNG) and sometimes conflicting with Expo. However, our experience from Energy and Palette-mobile has been positive so far and we could imagine CNG in Eigen! We will definitely share more about this if it happens. The new architecture Yes! We did it, all our apps are on the new architecture now. Expect a blog post about this! Tech Debt Eigen is an old repo, it's probably one of the oldest react-native apps out there. This comes with a price though. The industry changed a lot in the past years and a lot of the legacy code can now be rewritten using modern patterns more easily (and efficiently). To address that, we identified some weaknesses we had and prioritised them and decided to address them. Some notable mentions here include: Refactor our navigation Not long ago, it was hard for us to imagine our navigation infra all handled in react-navigation. But with more and more screens being rewritten in react-native and RN becoming more performant, it actu

## Two years of Next.js at Artsy: A Retrospective

DevFeed: [Two years of Next.js at Artsy: A Retrospective](<https://devfeed.tech/articles/two-years-of-next-js-at-artsy-a-retrospective-19166.md>)

Original publisher: [Read original article](<https://artsy.github.io/blog/2024/03/07/nextjs-at-artsy-retrospective/>)

Published: 2024-03-07T00:00:00Z

Content type: opinion

Language: en

Sources: [Artsy](<https://devfeed.tech/sources/artsy.md>)

Topics: [Next.js](<https://devfeed.tech/topics/next-js.md>), [Framework](<https://devfeed.tech/topics/framework.md>), [Low-Code / Internal Tools](<https://devfeed.tech/topics/internal-tools.md>), [Front end](<https://devfeed.tech/topics/frontend.md>), [JavaScript](<https://devfeed.tech/topics/javascript.md>), [TypeScript](<https://devfeed.tech/topics/typescript.md>), [Authentication](<https://devfeed.tech/topics/authentication.md>), [Databases](<https://devfeed.tech/topics/databases.md>)

Tags: [authentication](<https://devfeed.tech/tags/authentication.md>), [framework](<https://devfeed.tech/tags/framework.md>), [front-end](<https://devfeed.tech/tags/front-end.md>), [internal-tools](<https://devfeed.tech/tags/internal-tools.md>), [javascript](<https://devfeed.tech/tags/javascript.md>), [next-js](<https://devfeed.tech/tags/next-js.md>), [react](<https://devfeed.tech/tags/react.md>), [typescript](<https://devfeed.tech/tags/typescript.md>)

### AI overview

Artsy recounts two years of using Next.js, including a hackathon proof of concept for deduplicating artist records and a subsequent rebuild of a complex internal tools application. The article credits Next.js's conventions, framework-level setup, and documentation with helping a platform engineering team deliver core functionality, while noting remaining work around authentication and runtime secrets.

### Source excerpt

Where to begin! Where to begin... Lets start with a good measure of success, one that I think most engineers could agree on: a from-scratch rebuild of a complex, internal tools app. Success with rebuilds is often fleeting, as many can attest. There's risk involved. Extending the challenge further, lets assign (most) of the task to a team of platform engineers who aren't too familiar with modern front-end technology - and then say that we succeeded. Is Artsy crazy? Or is Next.js (along with our team 🙂) just that good? Well, it's a little of both. And it's a little bittersweet, in a way. Here's our tale. Beginnings Our first formal use of Next came from a project spun up during Hackathon, two years ago. Hackathon's are great opportunities to push technology forward, and Artsy has had a lot of success with them. We'd been talking about Next.js for a while, and experimenting here and there, but we were never able to find the proper intersection of product and purpose to take things further. With this in mind, one of our Engineers (Roop 👋) spun up a Next.js POC that allowed us to deduplicate artist records. On the surface, the effort was non-trivial. It involved authentication, DB communication, and more. Yet when presented during Hackathon, all of this was done and it also looked beautiful. How could so much product work get completed in such a short period of time? A large part of that is due to Next.js's framework design, and how it simply gets out of the way and allows one to start building product features. The defaults made sense; to create a new route, simply create a new folder or file in the pages directory, and Next takes care of the rest. And what about compilation, TypeScript, linting, and all of the other extraordinarily confusing JavaScript toolchain details that folks typically struggle over? (Most) of the setup was taken care of at the framework level, and the API side of things was light and easy to understand, thanks to great documentation. There are omit

## A Pre-Deployment Checklist for Risky Data Migrations

DevFeed: [A Pre-Deployment Checklist for Risky Data Migrations](<https://devfeed.tech/articles/the-checklist-for-deploying-a-scary-change-19165.md>)

Original publisher: [Read original article](<https://artsy.github.io/blog/2023/09/13/deploying-a-scary-change/>)

Published: 2023-09-13T00:00:00Z

Content type: tutorial

Language: en

Sources: [Artsy](<https://devfeed.tech/sources/artsy.md>)

Topics: [Command-line interface](<https://devfeed.tech/topics/cli.md>), [Docker](<https://devfeed.tech/topics/docker.md>), [Kubernetes](<https://devfeed.tech/topics/kubernetes.md>), [Sidekiq](<https://devfeed.tech/topics/sidekiq.md>), [Latency](<https://devfeed.tech/topics/latency.md>)

Tags: [command-line](<https://devfeed.tech/tags/command-line.md>), [data-migrations](<https://devfeed.tech/tags/data-migrations.md>), [deploy-process](<https://devfeed.tech/tags/deploy-process.md>), [docker](<https://devfeed.tech/tags/docker.md>), [error-reporting](<https://devfeed.tech/tags/error-reporting.md>), [kubernetes](<https://devfeed.tech/tags/kubernetes.md>), [latency](<https://devfeed.tech/tags/latency.md>), [logs](<https://devfeed.tech/tags/logs.md>), [migrations](<https://devfeed.tech/tags/migrations.md>), [retry](<https://devfeed.tech/tags/retry.md>), [ruby-on-rails](<https://devfeed.tech/tags/ruby-on-rails.md>), [sidekiq](<https://devfeed.tech/tags/sidekiq.md>)

### AI overview

This article presents a pre-deployment checklist for risky data migrations and other changes that could affect production services. It recommends planning rollback steps and monitoring error rates, reported errors, latency, logs, functionality, and failing Sidekiq retries after deployment.

### Source excerpt

Lately, I've been getting involved with some sketchy stuff. You know what I'm talking about-data migrations. I've been rolling out changes that have a significant risk of breaking our production environment for mission-critical services. It's been exciting work (keep your eyes out for more posts on the exact project, coming soon™), but I've definitely caused a couple incidents along the way. After accidentally taking down a key service for a couple hours, I decided I needed to have a better pre-deploy process for these changes. I did some thinking and came up with a short checklist to run through before I press the shiny green button. Here's the checklist I came up with: What is your plan if something goes wrong? Run through ramifications of rolling back. If there's a reason you're worried about rolling back, then you're not ready to deploy the change yet! Figure out exactly what command(s) you will need to run to roll back. At Artsy, this is usually a one-liner using Hokusai, our command-line Docker/Kubernetes CLI How will you tell if something is going wrong after you deploy? Error rate (DataDog) Specific error reporting (Sentry) Latency (DataDog) Logs (Papertrail) Functionality (does it still work? Are people using it successfully? Important for things where errors may not be bubbled up correctly or reported immediately) Sidekiq (are there lots of jobs queued to retry that are failing?) With this checklist in hand, I'm deploying more confidently and causing fewer incidents along the way. Do you have something similar? Are there things you think this checklist should include? Let me know in the comments!

## Using TypeScript Intersections to Preserve Literal Autocomplete with Arbitrary Strings

DevFeed: [Using TypeScript Intersections to Preserve Literal Autocomplete with Arbitrary Strings](<https://devfeed.tech/articles/typescript-magic-19164.md>)

Original publisher: [Read original article](<https://artsy.github.io/blog/2023/03/01/typescript-magic/>)

Published: 2023-03-01T00:00:00Z

Content type: tutorial

Language: en

Sources: [Artsy](<https://devfeed.tech/sources/artsy.md>)

Topics: [TypeScript](<https://devfeed.tech/topics/typescript.md>), [Design system](<https://devfeed.tech/topics/design-system.md>), [React Native](<https://devfeed.tech/topics/react-native.md>), [CSS](<https://devfeed.tech/topics/css.md>)

Tags: [autocomplete](<https://devfeed.tech/tags/autocomplete.md>), [css](<https://devfeed.tech/tags/css.md>), [design-system](<https://devfeed.tech/tags/design-system.md>), [palette](<https://devfeed.tech/tags/palette.md>), [react-native](<https://devfeed.tech/tags/react-native.md>), [tools](<https://devfeed.tech/tags/tools.md>), [types](<https://devfeed.tech/tags/types.md>), [typescript](<https://devfeed.tech/tags/typescript.md>)

### AI overview

This tutorial explains a TypeScript type pattern that preserves autocomplete and typechecking for predefined design-system color values while still accepting arbitrary strings such as hexadecimal, RGB, HSL, and CSS color names. It uses an intersection-based type trick to keep specific string literals distinct from the general string type.

### Source excerpt

At Artsy, we love TypeScript. We use it in most of our node/web/mobile repos. Today, I want to talk about a specific case we found while trying to make our types more strict on palette-mobile, which is our Design System for React Native. Check this out: const welp: "hello" | "world" | string // `welp` is of type `string`. Like the comment says, even though we have two specific strings, the fact that we do a union with string, makes welp have a type of just string. This is because both "hello" and "world" are strings, and the union tends to go to the type that includes the most. Think of set theory and bubbles. "hello" is a type by itself, and "world" is a type by itself. Unioning them together gives us a new type, which is a bubble that contains both "hello" and "world". In that "hello" | "world" union bubble, we see both "hello" and "world" types as subsets. The string bubble contains all strings, so it contains "hello" and "world" and "hello" | "world", so the union of them with string is string. That is usually ok, but for our case, it didn't work. Here is what we wanted to do. The problem In our Design System, we have certain color, named like black100, black80, blue100, red150 etc. We can have a type like type ColorDSValue = "black100" | "black80" | "blue100" | "red150" // | etc and that works great. We get to have autocomplete, typechecking, all the good stuff that TypeScript brings. But we also want to support any other string, like "#000000", "#000", "rgb(0,0,0)", "rgba(0,0,0,0.5)", "hsl(0,0%,0%)", "hsla(0,0%,0%,0.5)". Ok, you might say, just make more types like type ColorHexValue = `#${string}` type ColorRGBValue = `rgb(${number},${number},${number})` type ColorRGBAValue = `rgba(${number},${number},${number},${number})` type ColorHSLValue = `hsl(${number},${number}%,${number}%)` and so on. That's great. So far, so good. We also want to make sure CSS color names are accepted. So then we add something like type ColorCSSString = "red" | "blue" | "hotpink" //

## Diagnosing Incorrect Results in a MongoDB Geospatial Radius Query

DevFeed: [Diagnosing Incorrect Results in a MongoDB Geospatial Radius Query](<https://devfeed.tech/articles/are-you-using-the-right-mongo-geospatial-query-19163.md>)

Original publisher: [Read original article](<https://artsy.github.io/blog/2023/02/10/mongo-geospatial-queries/>)

Published: 2023-02-10T00:00:00Z

Content type: article

Language: en

Sources: [Artsy](<https://devfeed.tech/sources/artsy.md>)

Topics: [MongoDB](<https://devfeed.tech/topics/mongodb.md>), [Rails](<https://devfeed.tech/topics/rails.md>), [API](<https://devfeed.tech/topics/api.md>), [data](<https://devfeed.tech/topics/data.md>)

Tags: [api](<https://devfeed.tech/tags/api.md>), [best-practices](<https://devfeed.tech/tags/best-practices.md>), [code](<https://devfeed.tech/tags/code.md>), [data](<https://devfeed.tech/tags/data.md>), [debugging](<https://devfeed.tech/tags/debugging.md>), [geospatial](<https://devfeed.tech/tags/geospatial.md>), [gravity](<https://devfeed.tech/tags/gravity.md>), [json](<https://devfeed.tech/tags/json.md>), [mongodb](<https://devfeed.tech/tags/mongodb.md>), [rails](<https://devfeed.tech/tags/rails.md>)

### AI overview

This article investigates why a MongoDB geospatial query omitted a gallery from Los Angeles exhibition listings. By widening the radius and visualizing the results, it finds that points near the left and right edges of the circle were incorrectly omitted.

### Source excerpt

We recently got a report from one of our galleries in the Los Angeles area that they weren't showing up on our Los Angeles exhibition listings. I fielded the report and right away confirmed: when we asked our core API for /shows?near=<los angeles coordinates>, sure enough this gallery partner didn't make the cut. Turns out they are based in Santa Monica, a separate and neighboring municipality. They must not be within the 25km radius that we use by default for these sorts of queries. Case closed. Or so I thought. After some back and forth with our partner I decided to investigate more thoroughly, this time using some tricks of the trade from my other life outside of Artsy. Casting a wider net If there was something wrong with our 25km radius query, I wanted to start by casting a wider net and visualizing the results. I consulted our Rails application code to find the query logic in question, and then issued the same query directly to MongoDB. Something like the following query (simplified for clarity): // a $geoWithin $center query db.events.find({ coordinates: { $geoWithin: { $center: [[-118.24, 34.05], 25 / 111.32], }, }, }) In the query above we are asking MongoDB to give us all events within a 25km radius around the point 34.05°N, 118.24°W which we have designated as a central point within Los Angeles. For our purposes in this post we can consider "events" ~= "exhibitions" ~= "shows." We are not asking for the 25km radius directly, but rather converting it into an equivalent amount of geographic degrees by using a conversion factor of 1° ~= 111.32 kilometers, a factor which is true at enough the equator. I modified the above query to cast a 50km net in order to see if there were some edges cases that needed scrutiny. Taking the resulting JSON response, I fired up Placemark, my favorite new tool for wrangling geospatial data. (Incidentally I recommend reading Tom Macwright's recent reflection on creating Placemark as a bootstrapped indie developer.) All shows within

## Parallelizing Jest and Cypress.io Tests on CircleCI

DevFeed: [Parallelizing Jest and Cypress.io Tests on CircleCI](<https://devfeed.tech/articles/parallelizing-jest-and-cypress-io-tests-on-circleci-19162.md>)

Original publisher: [Read original article](<https://artsy.github.io/blog/2022/09/07/quick-tips-to-speed-up-ci/>)

Published: 2022-09-07T00:00:00Z

Content type: tutorial

Language: en

Sources: [Artsy](<https://devfeed.tech/sources/artsy.md>)

Topics: [Jest](<https://devfeed.tech/topics/jest.md>), [Cypress](<https://devfeed.tech/topics/cypress.md>), [ci](<https://devfeed.tech/topics/ci.md>), [Developer experience](<https://devfeed.tech/topics/developer-experience.md>)

Tags: [ci](<https://devfeed.tech/tags/ci.md>), [circleci](<https://devfeed.tech/tags/circleci.md>), [cypress](<https://devfeed.tech/tags/cypress.md>), [developer-experience](<https://devfeed.tech/tags/developer-experience.md>), [jest](<https://devfeed.tech/tags/jest.md>), [tests](<https://devfeed.tech/tags/tests.md>), [unit-tests](<https://devfeed.tech/tags/unit-tests.md>)

### AI overview

This tutorial explains how to parallelize CI test workloads using Jest sharding and CircleCI's split command for Cypress.io integration tests. It describes dividing Jest tests into buckets so separate processes can run subsets concurrently, reducing overall test execution time and developer wait time.

### Source excerpt

At Artsy, exploring ways to improve the developer experience is part of our makeup. Whether it's implementing hot-swapping for Express.js or integrating the Rust-based SWC compiler into our front-end build pipeline, we're always trying to reduce the amount of time it takes for a code cycle to take place. CI is no exception. When a developer opens a PR, we want to ensure they get timely feedback. Do their unit tests pass? Does the app build correctly? And how about smoke tests? Each of these jobs are complex processes that take time, and the more one can parallelize said tasks the less devs will need to wait. Scaled out to a whole engineering org, minor improvements to CI can be radical. In this regard, two things came across our radar recently that we'd like to share: sharding via Jest, and a (free) way to parallelize Cypress.io integration tests via CircleCI's split command. Sharding in Jest "What is sharding?" Good question! In short, it means "a small part of a whole". The database community has employed sharding techniques for decades, where a large database is split up into smaller, more manageable chunks, usually to improve performance at scale. The same idea can be applied to any process or task involving a lot of data, including tests. Think about it like this. Imagine an app that has thousands of tests. One can open up their terminal and run yarn test and execute all of the tests at once in a single process, or one can open two terminal tabs and run yarn test src/utils and yarn test src/routes, and have both processes allocate a pool of memory to complete each (smaller) subset of tasks. Because each process has its own memory pool the performance characteristics are generally better, and thus the overall time required to run our tests is reduced / decreased. Running each of these commands scoped to a particular folder is easy enough, but in a CI environment this is somewhat cumbersome; we'd need to define two new jobs and then the conditions in which they r

## How Artsy Preserved Cookie Preferences Beyond Safari's 7-Day Limit

DevFeed: [How Artsy Preserved Cookie Preferences Beyond Safari's 7-Day Limit](<https://devfeed.tech/articles/hacking-around-safari-s-7-day-cookie-limit-19161.md>)

Original publisher: [Read original article](<https://artsy.github.io/blog/2022/08/23/getting-around-7-day-cookie/>)

Published: 2022-08-23T00:00:00Z

Content type: tutorial

Language: en

Sources: [Artsy](<https://devfeed.tech/sources/artsy.md>)

Topics: [browser](<https://devfeed.tech/topics/browser.md>), [WebKit](<https://devfeed.tech/topics/webkit.md>), [User experience (UX)](<https://devfeed.tech/topics/ux.md>), [client](<https://devfeed.tech/topics/client.md>)

Tags: [apple](<https://devfeed.tech/tags/apple.md>), [browser](<https://devfeed.tech/tags/browser.md>), [ccpa](<https://devfeed.tech/tags/ccpa.md>), [cookies](<https://devfeed.tech/tags/cookies.md>), [gdpr](<https://devfeed.tech/tags/gdpr.md>), [privacy](<https://devfeed.tech/tags/privacy.md>), [safari](<https://devfeed.tech/tags/safari.md>), [server](<https://devfeed.tech/tags/server.md>), [ux](<https://devfeed.tech/tags/ux.md>), [wwdc](<https://devfeed.tech/tags/wwdc.md>)

### AI overview

This article explains how Artsy addressed Safari's seven-day limit on client-side cookies, which caused cookie-consent preferences to be repeatedly requested. It describes replacing the client-side cookie with a same-domain, secure, server-side cookie so the preferences persist beyond seven days.

### Source excerpt

Amongst the many, many things that organizations have to contend with around cookie consent laws is Apple's very own browser, Safari. Did you know that Safari will only retain a client-side cookie for 7 days? This is in support of Apple's Intelligent Tracking Prevention (ITP) feature, designed to protect a user's privacy. These privacy efforts are great but, in hand with laws like GDPR and CCPA, their rollout often creates a UX nightmare for users without some extra care. Here at Artsy, we've landed on a way to make things slightly less bad and want to share our approach. Scenario: Imagine that as a EU resident you visit artsy.net for the first time. A banner appears asking you to Accept or Deny tracking cookies from our site. You don't like tracking cookies, so you click the "Deny" button and the banner disappears. All good, right? Nope! You visit Artsy a week later and again, a banner appears asking you to choose your preferences. This happens again and again until you switch browsers and realize that what you were experiencing was Apple's ITP feature in action. After choosing your preferences, the cookie we use to store them is erased after 7 days, necessitating another interaction. We thrashed around in this vicious cycle for months until we found a simple, elegant solution thanks to a WebKit engineer's prompt (during Apple's open lab calls at WWDC - which you too can schedule!) She mentioned that the 7-day cookie limitation only applies to client-side cookies and that same-domain, secure, server-side cookies are not limited to these constraints. This got us thinking. Our third-party cookie consent management service sets a client-side cookie, not a server-side cookie. Could we perhaps overwrite the client-side cookie with a server-side cookie of the same name and trick Safari into persisting the user preferences beyond the 7-day limit? We gave it a try and... Yes. We. Can! And this means that you can too (and it's also real easy to implement). First, define an AP

## Artsy Deprecates the KAWS Collections Service by Moving Its Functionality into Gravity

DevFeed: [Artsy Deprecates the KAWS Collections Service by Moving Its Functionality into Gravity](<https://devfeed.tech/articles/third-time-s-the-charm-deprecating-kaws-19160.md>)

Original publisher: [Read original article](<https://artsy.github.io/blog/2022/05/09/deprecating-kaws/>)

Published: 2022-05-09T00:00:00Z

Content type: article

Language: en

Sources: [Artsy](<https://devfeed.tech/sources/artsy.md>)

Topics: [API](<https://devfeed.tech/topics/api.md>), [Node.js](<https://devfeed.tech/topics/node-js.md>), [Database](<https://devfeed.tech/topics/database.md>), [GraphQL](<https://devfeed.tech/topics/graphql.md>), [elasticsearch](<https://devfeed.tech/topics/elasticsearch.md>), [TypeScript](<https://devfeed.tech/topics/typescript.md>), [Rails](<https://devfeed.tech/topics/rails.md>), [Ruby](<https://devfeed.tech/topics/ruby.md>)

Tags: [api](<https://devfeed.tech/tags/api.md>), [database](<https://devfeed.tech/tags/database.md>), [elasticsearch](<https://devfeed.tech/tags/elasticsearch.md>), [graphql](<https://devfeed.tech/tags/graphql.md>), [kaws-refactoring-gravity](<https://devfeed.tech/tags/kaws-refactoring-gravity.md>), [node-js](<https://devfeed.tech/tags/node-js.md>), [rails](<https://devfeed.tech/tags/rails.md>), [ruby](<https://devfeed.tech/tags/ruby.md>), [typescript](<https://devfeed.tech/tags/typescript.md>)

### AI overview

Artsy explains why it deprecated KAWS, a service for defining artwork collections, and moved its functionality into the main Gravity database and API. The article describes KAWS's Node.js, MongoDB, GraphQL, TypeScript, and Elasticsearch-based design and the lessons from retiring it.

### Source excerpt

How do you tell when it's time to deprecate a system? If something mostly works OK, is it worth spending time and effort replacing its functionality? At Artsy, we realized several years ago that we needed to be able to group a bunch of artworks together. If we wanted to have a page with all of the ceramics by Lucio Fontana, or contemporary prints from the IFPDA Fair Sprint 2022, or a gift guide curated by Antwaun Sargent, we needed to have a way to make that happen. We decided to call these things "collections," a reasonable name for a collection of artworks. In order to create them, we developed a service called KAWS, named after the artist (whose works we wanted to put in several of these collections). Now, 4 years later, we've taken down the service and folded its functionality into Artsy's main database and API, Gravity. Let's talk about why and what we learned along the way. A little context KAWS has a somewhat unusual design. It's a server, a Node.js app with its own Mongo database, and it serves up a GraphQL API. It also relies on TypeORM to map TypeScript models to database records and TypeGraphQL to keep TS and GraphQL types in sync. This makes it a bit different from most services Artsy maintains. Most of our APIs are Ruby on Rails apps, and we don't have any other uses of TypeORM and TypeGraphQL. When it was created, it was a cool experiment with a possible direction for future APIs - one we decided not to pursue for the time being. KAWS doesn't store any artworks - or even any artwork IDs. Instead, it just stores a "query", a set of Elasticsearch criteria. This could be a list of artist IDs or gene IDs, a tag ID, a keyword, or any combination of those things. In other words, a KAWS artwork collection could be defined in human-readable terms as something like "artworks with the 'Black and White' gene by the artist Bridget Riley" or "artworks by Auguste Rodin with the keyword 'bronze' and the gene 'Sculpture'." This approach results in a somewhat odd flow

## Stepping Out Of The Knowledge Zone

DevFeed: [Stepping Out Of The Knowledge Zone](<https://devfeed.tech/articles/stepping-out-of-the-knowledge-zone-19159.md>)

Original publisher: [Read original article](<https://artsy.github.io/blog/2022/04/13/stepping-out-of-the-knowledge-zone/>)

Published: 2022-04-13T00:00:00Z

Content type: opinion

Language: en

Sources: [Artsy](<https://devfeed.tech/sources/artsy.md>)

Topics: [Elixir](<https://devfeed.tech/topics/elixir.md>), [Learning](<https://devfeed.tech/topics/learning.md>), [Ruby](<https://devfeed.tech/topics/ruby.md>), [Rails](<https://devfeed.tech/topics/rails.md>)

Tags: [backend](<https://devfeed.tech/tags/backend.md>), [blog](<https://devfeed.tech/tags/blog.md>), [blog-post](<https://devfeed.tech/tags/blog-post.md>), [cypress](<https://devfeed.tech/tags/cypress.md>), [elixir](<https://devfeed.tech/tags/elixir.md>), [forque](<https://devfeed.tech/tags/forque.md>), [front-end](<https://devfeed.tech/tags/front-end.md>), [horizon](<https://devfeed.tech/tags/horizon.md>), [integrity](<https://devfeed.tech/tags/integrity.md>), [learning](<https://devfeed.tech/tags/learning.md>), [ruby](<https://devfeed.tech/tags/ruby.md>), [ruby-on-rails](<https://devfeed.tech/tags/ruby-on-rails.md>), [teams](<https://devfeed.tech/tags/teams.md>), [velocity](<https://devfeed.tech/tags/velocity.md>)

### AI overview

A first-person reflection on moving beyond familiar Ruby on Rails work and embracing the challenge of learning Elixir. The author connects this transition to Artsy shipping work and a broader willingness to remain open to being a beginner.

### Source excerpt

As I am writing my first blog post for Artsy, here is a short introduction on who I am: My name is Kaja and I am an engineer in our Berlin entity. As a Ruby-born programmer I am calling myself a backend engineer, but that also may change and is more about emotional identification and less about what I actually do (as you will see in this blog post). My background is not in engineering at all. In university I graduated in philosophy and historical linguistics, both the most impractical but most beautifully theoretical subjects I can think of. I really love being in the world of ideas and thought experiments that challenge the current status of what is, as opposed to what is thinkable. At Artsy I am currently working in the PX (Partner Experience) Team and since I joined 1 year ago, most of my time in the PX team has been dedicated to the implementation of the Artsy Shipping feature. In the backend I helped tying the ties between the external ARTA-API (a white glove shipping company) and our own service that is managing the shipping and order statuses of the artworks that are ordered online. In the front end I implemented some forms for that feature and some so called hooks. I felt like a fish in the water with these tasks, because the company that I had worked at before was a shipping company and I did the same thing from the other side of the API relationship. In the same language (Ruby on Rails). Here is another fact about me that is a premises for what comes next: I enjoy to be a learner of new things much more than being an expert about things that I already know. Of course being an expert is also flattering the ego, but after a while it can feel repetitive and make your soul feel old and tired. While the experience of being new to something and not an expert at all can give you a rejuvenating prickle. On the other side it can be scary to admit not knowing something and also the ego will feel small and hurt. But I learned that overcoming the hurt ego is my way to

## Using Context to Simplify a VERY Large React Form

DevFeed: [Using Context to Simplify a VERY Large React Form](<https://devfeed.tech/articles/using-context-to-simplify-a-very-large-react-form-19158.md>)

Original publisher: [Read original article](<https://artsy.github.io/blog/2022/02/01/using-context-to-simplify-a-react-form/>)

Published: 2022-02-01T00:00:00Z

Content type: article

Language: en

Sources: [Artsy](<https://devfeed.tech/sources/artsy.md>)

Topics: [React](<https://devfeed.tech/topics/react.md>), [Refactoring](<https://devfeed.tech/topics/refactoring.md>), [Tech Debt](<https://devfeed.tech/topics/tech-debt.md>), [Development](<https://devfeed.tech/topics/development.md>)

Tags: [context](<https://devfeed.tech/tags/context.md>), [developer](<https://devfeed.tech/tags/developer.md>), [react](<https://devfeed.tech/tags/react.md>), [refactoring](<https://devfeed.tech/tags/refactoring.md>), [software-development](<https://devfeed.tech/tags/software-development.md>), [tech-debt](<https://devfeed.tech/tags/tech-debt.md>), [typescript](<https://devfeed.tech/tags/typescript.md>)

### AI overview

Artsy describes the incremental refactoring and ongoing maintenance of its large Artwork Form, which evolved from Ruby and Haml through JavaScript, jQuery, and React. The article discusses the tradeoffs involved in addressing legacy code and technical debt, including developer experience, user experience, release lead time, and stakeholder support.

### Source excerpt

For those unfamiliar, Artsy is a fine art marketplace. Knowing that, it follows logically to say that the form via which our partners list artworks for sale is an integral part of Artsy's core systems. This form, known only as "The Artwork Form," is whispered about in the halls of Arty's New York headquarters. It is legendary. It is a colossus. It is old enough not only to predate React v16.8 hooks and context APIs, but Artsy's use of React entirely. The first version of the Artwork Form was built in 2014 using ruby and haml, and began its refactoring into JS/JQuery/React a full 2 years later, after having expanded considerably from the original implementation. That process (at least what we've gleaned from our git excavation) was incremental, experimental, and passed through many hands before it landed in the lap of the current Partner Experience (PX) team. PX has since been tasked with the maintenance of this unwieldy kaiju, spending endless amounts of time on seemingly insignificant changes to behavior or UI, all while watching its performance degrade. Many of the people reading this are already familiar with the story we're telling. Many have worked in their very own version of the tale, and borne witness to the fact that legacy code of this scale becomes a living, breathing entity. The developers that tend these beasts learn their patterns and idiosyncrasies, their little moans and groans, and for the sake of expediency work within those constraints to accomplish their tasks. But when is enough, enough? When does the developer time expended working within the constraints of an obsolete design begin to outweigh the time it would take to simply fix the code? First, let's be honest: there is no single right answer to this question. When working in software development we have to deal with certain realities: user experience vs. developer experience, lead time to the next release, buy-in from stakeholders, etc. These factors may weigh more or less depending on the s