DEV Community

Custom Dirt Bike Graphics
Custom Dirt Bike Graphics

Posted on

I made a tiny open dataset of which dirt bikes share plastics

I like dirt bikes and I like small data projects, so this one was bound to happen.

The question behind it is simple. You find a graphics kit you like, the listing says "2024 KX450", and your bike is a 2025 KX250. Will it fit? Often it does, because manufacturers keep the same plastic panels for a few model years and share them between the 250 and the 450. I couldn't find that written down in one place, so I started a repo for it: dirt-bike-graphics on GitHub. It now covers 175 model years from 76 models and 11 brands.

Groups, not "compatible with" lists

If every bike carries its own list of compatible bikes, each fact is stored twice, and sooner or later the two copies disagree. So I went with groups. Each group has one reference bike, the one a kit would actually be designed on, plus every model year that shares its panels. Seventeen groups cover everything so far.

The rule that keeps this honest is that a model year can sit in only one group. I check it with a few lines of JS before every update:

const seen = new Map();
for (const bike of data.bikes) {
  for (const name of bike.fits) {
    if (seen.has(name)) console.warn(`${name}: ${seen.get(name)} and ${bike.id}`);
    seen.set(name, bike.id);
  }
}
Enter fullscreen mode Exit fullscreen mode

Right now it prints nothing, which is the whole point.

(Model names were their own headache. KTM calls a bike one thing in its marketing and another in its parts lists. I wrote about that in my last post, so I'll skip it here.)

Two files, one for people and one for code

Most people who land on the repo just want an answer, so FITMENT.md is a plain table, one reference bike per row. fitment.json holds the same data for anyone who wants to build on it.

I didn't want to run a server for a file this small. GitHub Pages turned out to be enough: it serves the JSON with Access-Control-Allow-Origin: *, so any page can fetch it directly:

const res = await fetch("https://dirt-bike-graphics.github.io/fitment.json");
const { bikes, updated } = await res.json();

const kitFor = new Map();
for (const bike of bikes) {
  for (const name of bike.fits) {
    kitFor.set(name, `${bike.brand} ${bike.model} (${bike.reference_year})`);
  }
}

kitFor.get("2025 KXF250"); // "Kawasaki KX450 (2024)"
Enter fullscreen mode Exit fullscreen mode

There's an updated date at the top of the file, so a cached copy knows when it's old.

Translations without a build step

A lot of riders don't search in English, so I added the README in German, French, Italian, Polish and Japanese. Each translation is just another Markdown file in the repo. Pages turns each one into its own page, and a row of language links at the top ties them together. No i18n setup at all.

What I haven't solved

Aftermarket plastics are the big gap. They mostly follow the stock shape, but not always, and I don't have a reliable source for the exceptions. Panels that change partway through a model year aren't tracked either.

If you ride one of these bikes and spot a fitment I got wrong, please open an issue with the model, the years and where you saw it.

Top comments (0)