Snapy
arrow_back Blog

Putting a thrift store's inventory online with a $2 microcontroller

A field report from getting Snapy running at North Shore Sports Swap

S
Sven Jensen

I'm Sven Jensen, a 21 year old Canadian computer scientist and geographer, and in this blog I will explain how my friend Elijah and I built Snapy, a system to solve the secondhand inventory online problem. But first some background information and why this matters for everyone.

I worked at a bike shop in 2020. Demand for bikes and parts was soaring, but supply chain problems meant there were shortages. We had to collect used bikes for resale or to scavenge for parts. Customers went online rather than in stores, so I started posting Craigslist and Facebook ads. It took me two hours to post ten. This is when I discovered the problem of syncing a secondhand storefront's inventory online, and 6 years later I have finally found the right solution.

Why does this matter for everyone? Snapy leaves more money in local communities and less carbon dioxide in the atmosphere, here's why. There are thousands of storefronts with secondhand goods sitting on their shelves un-digitized. Syncing this unique inventory online allows shoppers to search through the higher quality cheaper options. Secondhand storefronts that use the Snapy system see higher turnover, putting more money into the local resale / consignment mom & pop shops, and less into big enterprise retailers. The environmental benefits of buying used goods over new is well documented[1]. Buying something used skips the most resource-hungry stage of a product's life, its manufacturing, which avoids the raw material extraction, water, and carbon that a brand new alternative would burn, and keeps a perfectly good item out of the landfill.

TL;DR — We built an app that lists secondhand inventory in 20 seconds and a $4 hardware box that delists items when they sell in store. Deployed at a consignment sports shop, sales went up 10% in three weeks, and climbing.

This problem is hard. Secondhand storefronts have high volumes of unique products, and have no idea what their inventory will look like next week. Their supply chain consists mainly of donors and consignors dropping off what they found in their garage. Consistently digitizing and uploading each product is costly. The brute force solution; manually take photos and build listings for each product, then cross-list them on Google Local Inventory, Facebook Marketplace, Craigslist, eBay, a Shopify site, SidelineSwap, and so on. This process takes upwards of 15 minutes to get a single listing across the various online platforms. The moment a product sells in store, a staff member needs to delist that product from the various online platforms. This brute force method is too slow and complex for a local shop to maintain live inventory synced across multiple platforms. 15 minutes to list a $40 pair of hockey skates is too much.

So what are stores doing now? Some stores will selectively list their best items on a couple of platforms, while leaving out the vast majority of their inventory.

This leaves the growing number of secondhand storefronts and secondhand shoppers missing out on the benefits of syncing the inventory online. This blog post describes the birth of Snapy, the prototype system that my friend Elijah and I built to solve it, and how we got it working at North Shore Sports Swap.

A two part solution

This is a two part solution. Part #1 is a way to intake product data fast and easy. Part #2 is a way to detect sales in store and pull those products from online. For the first part we built a PWA where staff snap photos of a product, review the Gemini generated title, description, and specs, then confirm and push the product online. This drops the time to list from 15 to 20 minutes down to about 15 or 20 seconds per product. For the second part Elijah built the Snapy Box in his garage in one day. It is a simple box made from two microcontrollers that sits in between the barcode scanner and the POS system. It intercepts any product barcode scanned at checkout and sends it up to our Snapy server, where some code then delists it from the online channels.

The capture flow is built to feel like an assembly line. A staff member opens the Snapy app, snaps a set of photos of an item with its barcode somewhere in frame, and hits Add. Then they move straight to the next item and start snapping again, while the previous set is already being processed in the background. A Gemini call reads the photos, pulls out the brand, model, condition, and category, and writes the title and description. One person just keeps photographing down the rack, and the finished listings show up behind them.

Snap product pics
Create the listing in seconds
Review the listing and go live
Appears on Google Search for locals

The barcode in the shot is not optional. Every submission needs one, because that barcode becomes the item's identity across every platform. It is how a sale at the register later maps back to the right listing to pull down.

Now to the box

The Snapy Box opened up, showing two ESP32-S3 boards on perfboard in a 3D-printed case
The Snapy Box opened up — two ESP32-S3 boards on perfboard.
The two ESP32-S3 boards wired up on a solderless breadboard during prototyping
The two boards prototyped on a breadboard.

The Snapy Box sits inline between the barcode scanner and the store computer. The scanner plugs into the box, and the box plugs into the computer. Inside there are two ESP32-S3 boards, about $2 each from AliExpress, with three connections: one to the scanner, one to the computer, and one for extra power. One board acts as a USB host and reads the scanner. The other emulates a keyboard to the computer. A retail barcode scanner is really just a keyboard that types numbers very fast, so as far as the POS is concerned, nothing unusual is happening.

Here is the actual flow when something sells:

  1. The item gets scanned at the register.
  2. The box reads the barcode off the scanner.
  3. It fires a POST /the/endpoint with {sku, the_shop_id} up to our server over wifi.
  4. Then it forwards the keystrokes on to the computer so the sale rings through.
  5. The server delists that SKU everywhere it was live.

If that POST fails, the event drops into a local queue and retries later, so a flaky wifi connection does not mean a lost sale event.

Now the honest part. The box is not transparent yet. By transparent I mean invisible to the register: the scan should pass straight through to the computer as if the box were not there at all. Right now it is not, because it POSTs before forwarding, which adds a small delay to every scan, and if it loses power or hangs, the register stops scanning entirely. That is a real failure mode, and not one I would ship to a hundred stores. The fix is true passthrough, where the scan reaches the computer instantly and the server call happens in parallel. Making it transparent is the next hardware job.

A quick word on SidelineSwap, since it is one of the better places to sell used sports gear. We wanted Snapy listing and delisting there too, but their API is under reconstruction until Q4, so right now there is no API to call. So we drive a headless browser instead. A Playwright job runs on our server, logs in, and creates or pulls listings by clicking through the actual site the way a person would. It is exactly as fragile as it sounds, a UI change on their end could break it overnight, but it works today, and it meant we did not have to wait two quarters for an endpoint to ship.

The stack

The stack is boring and cheap on purpose. The frontend is a Next.js PWA on Vercel's free tier, frontend only, and it just calls the API. The backend, database, and the snapy.pro site all run on a single DigitalOcean droplet, a Go service with SQLite. Gemini handles the vision and the writing. I wrote the backend in Go specifically because it is light enough on memory to run the whole thing, API and database and website, on the cheapest droplet DigitalOcean sells.

Deploying it

Now to the deployment. We tested the box at a coffee shop right before heading over, and it worked great. At the store the wifi gave us a bit of trouble. The obvious network had one of those "click Accept to continue" portals that a headless box cannot get past, but a second network without one got us online.

We also hit a barcode snag: the store had not been applying unique codes to everything, so a small blue baseball glove shared the exact same barcode as a large beige one, and our system read them as the same item. The owner is tightening up barcoding from here, and on our end we treat the code as a strong hint rather than gospel.

The Snapy Box deployed at North Shore Sports Swap, inline between the barcode scanner and the POS
The Snapy Box live at the store, inline between the barcode scanner and the POS.

Then three of us listed around 300 items in about an hour and a half. North of $50,000 of inventory, live in one sitting. The bikes take longer because you have to physically move them around to shoot them, but the smaller gear went fast.

Three weeks in

After that we pushed the catalog out wide with various Playwright scripts and API integrations. Bikes to Craigslist, almost everything to Facebook Marketplace, the store's Shopify site, eBay, and SidelineSwap. A few things happened over the next three weeks.

Facebook. The listings pulled more than 22,000 clicks and more than 120 messages. My favorite detail here is that the first line of every Facebook description says "Available at North Shore Sports Swap." So every one of those 22,000 clicks is also free brand exposure for the store, whether or not it turns into a sale.

eBay. Despite seeding the account from scratch, our Snapy listings are already ranking in the top 2 sellers by GMV in the hockey skate and youth wetsuit categories on the Canadian marketplace. Brand new account, already winning categories. One buyer downtown saw a fork listed here, noticed the store was up in North Van, and drove over to grab it in person. That trip, from online listing to in-store pickup, is the entire thesis of Snapy in a single sale. The future of resale is not another peer to peer app. It is making the inventory that already exists on store shelves findable.

SidelineSwap. We did more than 20 hockey gear sales here in the first three weeks, and that is during June, the slowest, worst time of year to sell hockey gear.

Revenue. A 10% lift in the first three weeks, meaning the extra sales we can actually pin on Snapy added about 10% on top of the store's usual. Attribution is the genuinely hard part here, and I want to be straight about it. eBay and SidelineSwap sales we track cleanly. Walk-ins we only catch when someone mentions they saw it online and the owner happens to pass it along, so there are definitely sales we are missing. And none of that counts the spillover from 22,000 Facebook clicks reading the store's name. So 10% is a floor, not a ceiling, and we think it climbs toward 50% in the coming months.

Ski boots stacked all over the bike repair area at North Shore Sports Swap
Ski boots stacked all over the bike repair area — he wouldn't let them be put away until they were Snapy'd first.

The clearest sign it is working is that the owner is paying for Snapy now and is a little obsessed. He picked up a pile of secondhand ski boots recently and would not let the bike mechanic put them away until he had Snapy'd them first. They are stacked all over the bike repair area in the photo above. We have a second eBay store running, Facebook listings going up on their own, and Google Free Local Listings just about ready to switch on. That last one should be interesting.

Update — June 27th. The Google Free Local Listings have been live for 10 days and produced more than 40 product clicks, the inventory is surfacing very well in locals google searches, stoked!

Where this goes

We are seeing promising results at North Shore Sports Swap, and we have two more stores lined up in North Van. We plan on approaching more sporting goods consignment stores soon.

The larger vision is to let all secondhand retail digitize its inventory and actually reap the benefit. There are tens of thousands of these stores, each sitting on a pile of gear that could be found online. 83% of retail purchases happen in store[2], we believe the future of resale lives in storefronts, not peer to peer apps, and the one thing standing in the way has just been the listing tax. Snapy is our shot at deleting it.

If you know a store that could use this, or you want to help us build it, hit me up: sven@snapy.pro

  1. [1] University of British Columbia. (2022). Towards Zero Waste: An Environmental Life Cycle Analysis of New Furniture vs Participation in the Furniture Reuse Program. UBC Sustainability SEEDS Library. Tracking furniture metrics over a 10-year lifespan reveals that selecting used commercial-grade items instead of buying brand new alternatives avoids between 60% and 97% of total lifecycle greenhouse gas emissions.
  2. [2] U.S. Census Bureau. (2026). Quarterly Retail E-Commerce Sales, 1st Quarter 2026. U.S. Department of Commerce.