<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Custom Dirt Bike Graphics</title>
    <description>The latest articles on DEV Community by Custom Dirt Bike Graphics (@customdirtbikegraphics).</description>
    <link>https://dev.to/customdirtbikegraphics</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4182364%2F2437de69-678b-4cae-b9e7-63a45a034a29.png</url>
      <title>DEV Community: Custom Dirt Bike Graphics</title>
      <link>https://dev.to/customdirtbikegraphics</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/customdirtbikegraphics"/>
    <language>en</language>
    <item>
      <title>One graphics kit, eleven bikes: storing dirt bike fitment as data</title>
      <dc:creator>Custom Dirt Bike Graphics</dc:creator>
      <pubDate>Sun, 18 Oct 2026 07:46:31 +0000</pubDate>
      <link>https://dev.to/customdirtbikegraphics/one-graphics-kit-eleven-bikes-storing-dirt-bike-fitment-as-data-3a9j</link>
      <guid>https://dev.to/customdirtbikegraphics/one-graphics-kit-eleven-bikes-storing-dirt-bike-fitment-as-data-3a9j</guid>
      <description>&lt;p&gt;When I started building a graphics kit designer for dirt bikes, I assumed every bike needed its own kit. It doesn't. Manufacturers reuse plastics across years and engine sizes, so a kit cut for one bike often lines up on several others. The 2023 Yamaha YZ450F kit, for example, also fits the YZ450FX, the YZ250F and the YZ250FX across 2024 to 2026. That is eleven model and year combinations from one set of panel shapes.&lt;/p&gt;

&lt;p&gt;So the useful unit of data is a reference bike plus the list of everything that shares its plastics.&lt;/p&gt;

&lt;h2&gt;
  
  
  The shape I ended up with
&lt;/h2&gt;

&lt;p&gt;Each entry is one reference bike, and fitment is a flat list of strings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"honda-crf450r-2025"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"brand"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Honda"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CRF450R"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"reference_year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MX"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"fits"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"2025 CRF450R"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026 CRF450R"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025 CRF250R"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026 CRF250R"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A flat list is easy to search and easy to show under a bike in the UI. Grouping by model can happen at render time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Things that broke my assumptions
&lt;/h2&gt;

&lt;p&gt;Names are not consistent. The bike is the KTM 450 SX-F, but its fitment entries read SXF450, SXF350 and so on. Kawasaki's KX450 shows up as KXF450. I store the display name on the reference bike and keep the fitment strings as they are, so the two never have to match.&lt;/p&gt;

&lt;p&gt;Electric bikes have no model year. The Stark Varg fits by version instead, "1.0 VARG MX" and "1.5 VARG MX", so &lt;code&gt;reference_year&lt;/code&gt; had to be nullable.&lt;/p&gt;

&lt;p&gt;Fitment also runs forward. The KTM 450 EXC-F kit is built on 2025 plastics, and its list already includes 2027 models. A field that only tracked past years would not have held that.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is still missing
&lt;/h2&gt;

&lt;p&gt;Aftermarket plastics. Brands like Acerbis and Polisport often follow the stock shape, but not always, and I have no clean source for the exceptions yet. If you have tracked this kind of data before, I would like to hear how.&lt;/p&gt;

&lt;p&gt;I use this list in the designer I am building at &lt;a href="https://customdirtbikegraphics.com" rel="noopener noreferrer"&gt;customdirtbikegraphics.com&lt;/a&gt;, where the fitment shows up next to each bike.&lt;/p&gt;

</description>
      <category>data</category>
      <category>sideprojects</category>
      <category>json</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
