Work / ViewForge — YMM Search & Filter

Fitment is a tree, not a table

2026 /

  • Shopify
  • TypeScript
  • Metaobjects
  • React Router

Does this fit my 2021 Ford F-150?

That is the whole question a parts store has to answer, and every merchant I talked to was answering it with a spreadsheet, a compatibility chart in a product description, or a phone number.

My first instinct was a table. Year, make, model, part. Three dropdowns, one lookup, go home early.

Then somebody sells tractors. Now it is brand, series, model, and year does not appear at all. Then somebody sells printer toner, and it is brand, series, SKU. Then bicycles, where the interesting axis is wheel size. Every one of them is the same shape of question and not one of them is the same columns.

So fitment is not a table. It is a tree, and the labels on the levels are the merchant’s business rather than mine. ViewForge stores a template, which says what the levels are called and how they sort, and a node tree underneath it holding the actual values. Eight presets ship with it, automotive through marine through power equipment, and a merchant who does not fit any of the eight defines their own. The storefront gets cascading dropdowns either way.

Here is the part that actually eats the time, though, and it is not the data model. It is that fitment data arrives as a CSV somebody exported from a supplier portal in 2019. Columns in the wrong order. Years as ranges in one row and single values in the next. Makes spelled three ways. Trim levels glued onto model names with a hyphen, sometimes.

You cannot ask a merchant to clean thirty thousand rows by hand before they can use your app. They will close the tab, and they will be right to. So a good chunk of ViewForge is a parser that takes the mess as given and works out what each column is trying to be.

Was that fun? Honestly, yes, for about the first week. After that it is a long grind of real files doing something you did not expect, which is why the repo currently has 303 tests in it. Every one of those is a file that surprised me once.

The storage sits on native Shopify metaobjects rather than an external database I keep on the merchant’s behalf, which is its own decision and its own write up. The short version is that their data should still be theirs after they uninstall me.

It is in production and it is the piece of my own work I would point at first.