Photo for From an Interview to a Side Project

From an Interview to a Side Project

Aug 20, 2025

Interviews can provide some important learnings, if we're willing to listen.

In a recent interview, I was asked to walk through how I would design the frontend for a new search result app that combined the results from multiple APIs and de-duped responses. While my response was not the most polished, it got me thinking about all of the things that need to be considered when creating such an application. Some of the questions that came to mind included:

  • Do we need to combine data from the APIs into a single result or is one API the source of truth?
  • How do we deal with caching?
  • Will the UI input fields autocomplete?
  • Is there a 'Submit' button to fetch results or are the results fetched dynamically as the user types?
  • What type of frontend framework would be optimal to use?
  • How many responses do we load at once? Do we include lazy loading?
  • Do we hit the APIs from the client or hook it up to a backend?
  • When de-duping responses, do we hit the APIs synchronously or wait until one has been exhausted before hitting the next?
  • Will there be sorting options? If so, how do we optimize results if we aren't able to customize how the APIs return data (alphabetically, geographically, etc)?

These are just a few of the questions that not only arose as the interview went along, but also that entered my mind once the call ended. Architecting solutions involves many considerations, questions to ask, and pros/cons to weigh. While a 45-minute interview provides a glimpse into someone's thought process, real-world solutions often require deeper conversations amongst developers, designers, and stakeholders.

Although I left the call replaying the 'I should have said' moments over and over, I decided to use the experience as a learning opportunity. Upon reflecting on my interview experience, I was inspired to translate my ideas into an actual app.

Let's Build A Search App

Like many developers, I learn by doing. So I decided to actually build out a search application. But I didn't want to just solve for the problem posed in the interview, I also wanted to learn new technologies and challenge myself.

The Data

The first hurdle was determining where I was going to get data from. I knew I wanted to use Google, but explored other options like Trip Advisor, Yelp, and Foursquare. While I would have liked to use all four sources, I realized that I was limited due to cost. I ended up using Google Places and Foursquare and determined the following fields were most pertinent to the user experience:

  • Name
  • Address
  • Phone Number
  • Website url
  • Ratings
  • Total Rating Count

Google Places returned all of the info above, so I decided to use it as my source of truth. Google Places API returns 20 results per page, with up to 60 results max. I initially planned to exhaust all Google results before calling Foursquare. Foursquare's free tier doesn't provide ratings, so those results were returned after Google.

Once I got data back from Foursquare, I checked the results against the Google results. I chose to compare phone number, assuming each result has a unique phone number. If the phone number already existed in the Google results, I used the Google result and discarded the Foursquare response.

The Gotcha!

When I pushed the application to my web hosting provider in late July, I started to see quite a few unexpected charges. Google Places API updated its pricing earlier this year and officially ended support for their Legacy Places API, which offered a bit more flexibility. To keep costs low, I decided to return 10 results from Google before hitting the Foursquare API, which has a larger free tier rate limit. I learned it's critical to check pricing and updates so you don't incur unexpected charges!

The Tech Stack

Below is a list of my tech decisions and the reasoning behind them:

The Language: TypeScript

I was not thrilled when my previous job moved to TypeScript, but I can now fully see the benefits of using a strictly typed language. It not only prevents errors before they happen in production, but it also serves as a form of self-documentation. Most frameworks already support TypeScript, and many companies already integrate it into their development processes, so I chose to go this route.

The Framework: Tanstack Start

I built the application in Tanstack Start, which is a full-stack React framework (still in beta) that works seamlessly with other Tanstack libraries, like Tanstack Query, Tanstack Form, and Tanstack Table. While certainly not widely used like Next or Nuxt, it offers both client-side and server-side rendering. Most importantly, I specifically wanted to incorporate Tanstack Query (previously React Query) to understand how it works and caches data.

While Tanstack Query can be integrated with most other JavaScript frameworks, I wanted to not only stick with React for this application, but go with a full-stack framework and dabble in some new technology. This allowed me to move outside of comfort zone a bit and explore something completely new.

The Styles: Tailwind

This was a no-brainer for me. I've been working in Tailwind for more than 3 years so developing the frontend styles was relatively quick. Tailwind documentatin is clear and, like Tanstack Start, most frameworks include instructions on how to easily integrate it. While I don't love how it can clutter my class names in JSX, I do find it easy to customize and get up and running in a short amount of time.

Bundler: Vite

Tanstack Start uses Vite by default, so I didn't need to think about bundling. Vite’s minimal configuration and simplicity make it easy to run locally, especially compared to Webpack, which may require hours of tweaking to get things “just right.”

Tests: Vitest/React Testing Library

I've started writing tests using React Testing Library combined with Vitest as the test runner. Some challenges arose with third-party packages like Font Awesome, but a bit of conditional logic when running tests fixed the setup. This is still a work in progress.

The User Experience

While architecting the functionality of the app was the first priority, considering the look and feel of the app was my second concern. Key focuses included:

  • Responsiveness — ensuring a seamless experience on mobile, tablet or desktop is a must for any app
  • Accessibility — using the WAVE extension, I was able to ensure proper color contrast, appropriate roles and labels, hierarchy, and keyboard navigation
  • Skeletons —  loading skeletons give users a visual indicator while data is fetched, improving perceived performance and reducing layout shift
  • Light/Dark Mode — this is something I've wanted to test out for a while as many sites provide offer this option. It was easy to implement using Tailwind and gives users control over color choice.
  • Gradients — I've seen many websites use gradients and wanted to emulate a modern look. Gradients helped accomplish that up-to-date design and add some depth to the page.
  • Button States — disabling buttons until inputs were completed or data was loaded prevented unnecessary interactions
  • Views — I chose to have both a card view and a table view, giving users more options 

Performance

The main performance optimizations I focused on were:

  • Caching – TanStack Query has built-in caching mechanisms and I learned there are a variety of options to set expiration times and limit background refreshes. I chose a longer caching time since it wasn't necessary to check for new businesses very frequently
  • React Hooks – I was intentional about using React hooks like useMemo and useCallback to reduce unnecessary re-renders. 
  • Debouncing — this was important to ensure that the cache wasn't being invalidated with every keystroke and that the UI wasn't immediately cleared until one of the two inputs fields were completely empty 

I also checked Lighthouse reports to get a glimpse of other areas that could be optimized.

Maintainability and Scalability

For my purposes, I built this as a client-side only application. However, if this were a larger application, I would hook it up to a backend for maintainability and scalability:

  • API Call Limits — a backed would be able to track the total number of API calls and prevent any further calls if it exceeded a certain limit.
  • Caching — a backend would be able to cache results across sessions, which would help reduce API calls for the same search terms and improve performance.
  • Sorting and Filtering — to minimize API usage and associated costs, these options are limited without a backend. However, because of this, my options to add any sorting and filtering features were limited. A backedn would allow for easier sorting by name, ratings and other fields.

The Takeaways

This proved to be a fun learning experience while exploring new technologies and thinking through frontend system design. I used ChatGPT and CoPilot to improve development speed, debug issues, and help with test coverage. While I didn't vibe code this application, I did incorporate AI tools as part of my workflow. 

Interviews are often stressful — even when well-prepared — but there is always something to learn from them. For me, it inspired me to build an app from scratch and use my design creativity!

Check out "Scout it Out" here!