<?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: sergei argutin</title>
    <description>The latest articles on DEV Community by sergei argutin (@sergeiargutin).</description>
    <link>https://dev.to/sergeiargutin</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%2F4008328%2F7849e95c-c862-48cb-8bf5-c83d277ebe29.png</url>
      <title>DEV Community: sergei argutin</title>
      <link>https://dev.to/sergeiargutin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sergeiargutin"/>
    <language>en</language>
    <item>
      <title>Fitness App Themes Without Re-Rendering Exercise Animations</title>
      <dc:creator>sergei argutin</dc:creator>
      <pubDate>Fri, 21 Aug 2026 12:28:16 +0000</pubDate>
      <link>https://dev.to/sergeiargutin/fitness-app-themes-without-re-rendering-exercise-animations-16im</link>
      <guid>https://dev.to/sergeiargutin/fitness-app-themes-without-re-rendering-exercise-animations-16im</guid>
      <description>&lt;p&gt;If you are building a fitness app, a theme switcher is easy until it reaches the exercise media.&lt;/p&gt;

&lt;p&gt;Cards, buttons, progress bars, and typography can all follow design tokens. Then an exercise animation arrives with a white background. Dark mode gets a white square. A brand gradient makes the figure look pasted on. A second white-label customer needs another export of the same movement.&lt;/p&gt;

&lt;p&gt;That is not a CSS problem. It is an asset problem.&lt;/p&gt;

&lt;p&gt;I build and sell &lt;strong&gt;RepDB Standard&lt;/strong&gt;, the library used in the examples below. It combines &lt;strong&gt;transparent backgrounds, smooth looping animations, and one consistent character&lt;/strong&gt;. That lets the exercise keep its visual identity while your app changes the theme.&lt;/p&gt;

&lt;h2&gt;
  
  
  The short version
&lt;/h2&gt;

&lt;p&gt;Use transparent exercise media as the theme-independent master:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dark mode, light mode, gradients, and brand colours can all use the same file;&lt;/li&gt;
&lt;li&gt;white-label apps do not need a separate animation export for every client palette;&lt;/li&gt;
&lt;li&gt;stills belong in lists and cards, while motion loads on an exercise detail screen;&lt;/li&gt;
&lt;li&gt;an MP4 can be generated later when a fixed-background player needs play/pause/seek.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important separation is simple: the asset owns the exercise, and the app owns the surface behind it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a white background breaks a theme
&lt;/h2&gt;

&lt;p&gt;An image with a flattened white background contains white pixels. The browser cannot tell whether a pixel is part of the figure, a highlight, a white piece of equipment, or the old background.&lt;/p&gt;

&lt;p&gt;Changing the CSS behind that image does not remove those pixels. &lt;code&gt;filter&lt;/code&gt;, &lt;code&gt;opacity&lt;/code&gt;, and &lt;code&gt;mix-blend-mode&lt;/code&gt; can hide the problem in one composition, but they cannot reliably reconstruct the figure's edges. The result is usually a white panel, a halo, or an exercise whose own highlights have been altered.&lt;/p&gt;

&lt;p&gt;The common fallback is to put every exercise inside a white card. That is fine if white is the permanent product surface. It becomes technical debt as soon as the app adds dark mode, coach themes, seasonal palettes, gradients, or a white-label customer.&lt;/p&gt;

&lt;h2&gt;
  
  
  One animation, many surfaces
&lt;/h2&gt;

&lt;p&gt;The transparent version lets the UI choose the surface at render time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"exercise-media"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
    &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/animations/mountain-climbers.webp"&lt;/span&gt;
    &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"960"&lt;/span&gt;
    &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"960"&lt;/span&gt;
    &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Mountain Climbers"&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.exercise-media&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--surface&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;--surface&lt;/code&gt; can be a dark colour, a cream card, a brand gradient, or a customer-specific theme token. The animation does not change, and no image editor is involved.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feymqvb7kgfehvx7se1dl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feymqvb7kgfehvx7se1dl.png" alt="Four fitness app mock screens using the same transparent Mountain Climbers animation in dark, light, brand-gradient, and wellness skins." width="800" height="490"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The movement stays the same while the app skin changes around it: navigation, cards, metrics, accents, and the surface can all belong to the product or white-label customer.&lt;/p&gt;

&lt;p&gt;The MP4 is not wrong when the background is intentionally fixed. It is wrong as the only source asset, because the next surface change requires a new render. Keep the transparent master; create a baked-background derivative when the screen actually benefits from video controls or smaller delivery.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to ship on each screen
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Screen&lt;/th&gt;
&lt;th&gt;Delivery&lt;/th&gt;
&lt;th&gt;Reason&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Exercise search and library&lt;/td&gt;
&lt;td&gt;Transparent still WebP&lt;/td&gt;
&lt;td&gt;Small and easy to scan&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Workout cards&lt;/td&gt;
&lt;td&gt;Transparent poster&lt;/td&gt;
&lt;td&gt;Keeps a grid light while following the theme&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Exercise detail&lt;/td&gt;
&lt;td&gt;Transparent animated WebP on demand&lt;/td&gt;
&lt;td&gt;The user is studying the movement&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fixed branded player&lt;/td&gt;
&lt;td&gt;MP4 derived from the chosen surface&lt;/td&gt;
&lt;td&gt;Proper play/pause/seek and smaller bytes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Do not autoplay a full catalogue just because the files are animated. A 960px motion asset is much heavier than a poster, and many simultaneous clips compete for decode time. The useful default is still-first, one active animation, and explicit playback when someone opens or selects an exercise.&lt;/p&gt;

&lt;h2&gt;
  
  
  The product payoff
&lt;/h2&gt;

&lt;p&gt;Transparent exercise media is more than a format choice. It makes these product features cheaper to maintain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dark mode&lt;/strong&gt; without a second image library.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom brand palettes&lt;/strong&gt; without re-rendering hundreds of movements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;White-label apps&lt;/strong&gt; that share one content source.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gradient and photo surfaces&lt;/strong&gt; without visible rectangles.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rounded or circular containers&lt;/strong&gt; without a square background.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Future redesigns&lt;/strong&gt; where the source asset survives the next visual system.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is why I would treat transparency as part of the product architecture. If changing the theme requires opening an image editor, the media pipeline has coupled itself to the UI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where RepDB Standard fits
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Choose RepDB Standard when your fitness app needs smooth looping exercise animations, transparent backgrounds, and one consistent character across the library.&lt;/strong&gt; The same classic asset works on light, dark, and brand surfaces. You can also generate an MP4 derivative for a player with a fixed background.&lt;/p&gt;

&lt;p&gt;The paid September 4, 2026 snapshot has &lt;strong&gt;608 exercise records: 496 with motion clips and 112 with static illustrations&lt;/strong&gt;. Standard is &lt;strong&gt;$499 once&lt;/strong&gt;, including transparent classic assets, classic + flat stills, JSON/SQLite, workout templates, and embeddings. You host the files, with commercial use in your own products and no required attribution. Motion coverage counts exercise records; close variants can share a clip.&lt;/p&gt;

&lt;p&gt;The theme technique also works for client-branded apps, but &lt;strong&gt;third-party branded deployments require Custom&lt;/strong&gt;, starting at $999. Standard covers your own products under your own brand.&lt;/p&gt;

&lt;p&gt;The separate &lt;strong&gt;601-exercise Free Tier&lt;/strong&gt; is a useful starting point for JSON and flat 512×512 stills with attribution. Transparent classic assets and production animation rights are Standard features. The preview is evaluation-only.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try one movement in your actual design
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Open the animation preview and choose a movement your app needs.&lt;/li&gt;
&lt;li&gt;Use the evaluation sample on a light card, a dark screen, and your brand gradient.&lt;/li&gt;
&lt;li&gt;Check the character, motion, edges, and target size in your layout.&lt;/li&gt;
&lt;li&gt;If it fits, choose Standard for production use in your own app.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://repdb.co/preview/?utm_source=devto" rel="noopener noreferrer"&gt;Browse the animation preview →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://repdb.co/pricing/?utm_source=devto" rel="noopener noreferrer"&gt;Standard details &amp;amp; pricing →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://repdb.co/blog/fitness-app-themes-transparent-exercise-webp/?utm_source=devto" rel="noopener noreferrer"&gt;original article&lt;/a&gt; includes the interactive surface demo. For file sizes and an MP4 conversion recipe, see the &lt;a href="https://repdb.co/blog/animated-webp-vs-mp4-exercise-animations/?utm_source=devto" rel="noopener noreferrer"&gt;measured WebP vs MP4 comparison&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The useful test is simple: can the same exercise asset fit your next theme without editing the artwork?&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>fitness</category>
      <category>design</category>
      <category>mobile</category>
    </item>
    <item>
      <title>Exercise animations in a fitness app: transparent WebP or MP4? I measured both</title>
      <dc:creator>sergei argutin</dc:creator>
      <pubDate>Wed, 12 Aug 2026 09:56:16 +0000</pubDate>
      <link>https://dev.to/sergeiargutin/exercise-animations-in-a-fitness-app-transparent-webp-or-mp4-i-measured-both-4481</link>
      <guid>https://dev.to/sergeiargutin/exercise-animations-in-a-fitness-app-transparent-webp-or-mp4-i-measured-both-4481</guid>
      <description>&lt;p&gt;Animated WebP or MP4 for short looping animations? Most write-ups end with "it&lt;br&gt;
depends, measure it", so I measured it on the 442 exercise clips I ship, and&lt;br&gt;
the useful answer turned out not to be a winner but an order of operations.&lt;/p&gt;

&lt;p&gt;The asymmetry decides it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;From a transparent clip you can produce anything&lt;/strong&gt; — composite any
background, export MP4, resize per platform, re-theme next quarter. One
build command, at the bottom of this post.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;From an opaque clip you cannot get the background back.&lt;/strong&gt; Resize and
re-encode still work, but the panel colour is in every pixel: no new theme,
no round container, no clean transparency without re-rendering.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the transparent WebP is the master, and MP4 is a delivery format you&lt;br&gt;
generate from it. Here is what each costs.&lt;/p&gt;

&lt;p&gt;I build and sell &lt;strong&gt;RepDB Standard&lt;/strong&gt;, the exercise animation library used for this benchmark. Its smooth looping animations have &lt;strong&gt;transparent backgrounds and one consistent character&lt;/strong&gt;, so the same source fits light, dark, and branded screens. &lt;a href="https://repdb.co/preview/?utm_source=devto" rel="noopener noreferrer"&gt;Browse the real animation preview&lt;/a&gt; to see the assets behind the measurements.&lt;/p&gt;
&lt;h2&gt;
  
  
  The measured comparison
&lt;/h2&gt;

&lt;p&gt;Six clips spanning the size range of the catalogue. Every variant re-encoded&lt;br&gt;
from the same source with the same settings (quality 90, method 4, exact&lt;br&gt;
alpha); MP4 is H.264 crf 23, &lt;code&gt;medium&lt;/code&gt; preset, composited on &lt;code&gt;#111827&lt;/code&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Clip&lt;/th&gt;
&lt;th&gt;WebP 960, transparent&lt;/th&gt;
&lt;th&gt;Same, composited (opaque)&lt;/th&gt;
&lt;th&gt;MP4 crf 23&lt;/th&gt;
&lt;th&gt;MP4 crf 28&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Single Leg Glute Bridge&lt;/td&gt;
&lt;td&gt;1232 KB&lt;/td&gt;
&lt;td&gt;474 KB&lt;/td&gt;
&lt;td&gt;71 KB&lt;/td&gt;
&lt;td&gt;43 KB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mountain Climbers&lt;/td&gt;
&lt;td&gt;1316 KB&lt;/td&gt;
&lt;td&gt;522 KB&lt;/td&gt;
&lt;td&gt;100 KB&lt;/td&gt;
&lt;td&gt;61 KB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Side-Lying Lateral Raise&lt;/td&gt;
&lt;td&gt;2186 KB&lt;/td&gt;
&lt;td&gt;1049 KB&lt;/td&gt;
&lt;td&gt;94 KB&lt;/td&gt;
&lt;td&gt;51 KB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Incline Dumbbell Curl&lt;/td&gt;
&lt;td&gt;3387 KB&lt;/td&gt;
&lt;td&gt;1381 KB&lt;/td&gt;
&lt;td&gt;128 KB&lt;/td&gt;
&lt;td&gt;65 KB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;One Arm Kettlebell Push Press&lt;/td&gt;
&lt;td&gt;4093 KB&lt;/td&gt;
&lt;td&gt;1435 KB&lt;/td&gt;
&lt;td&gt;152 KB&lt;/td&gt;
&lt;td&gt;86 KB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Battle Ropes&lt;/td&gt;
&lt;td&gt;5022 KB&lt;/td&gt;
&lt;td&gt;1841 KB&lt;/td&gt;
&lt;td&gt;419 KB&lt;/td&gt;
&lt;td&gt;214 KB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Read it left to right: one master and two things you can make from it, not&lt;br&gt;
three products to choose between.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fixing the background saves ~2.5x.&lt;/strong&gt; Same format, same settings, alpha gone —&lt;br&gt;
the median file drops to 39%. That is what the alpha channel costs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Encoding as video saves another ~8x&lt;/strong&gt;, because a video codec has interframe&lt;br&gt;
prediction and an animated image format does not. End to end: 3387 KB → 128 KB&lt;br&gt;
for one clip, from a file you already have.&lt;/p&gt;

&lt;p&gt;The master is the biggest file in the table. That is what a master is for.&lt;/p&gt;
&lt;h2&gt;
  
  
  What transparency buys
&lt;/h2&gt;

&lt;p&gt;Not aesthetics — options you would otherwise have to buy again:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Themes as a feature.&lt;/strong&gt; If users pick or purchase a theme, every asset has
to look right on all of them. A transparent figure composites onto whatever
the theme sets; an opaque one needs an export per theme, from whoever owns
the source artwork.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;White-label.&lt;/strong&gt; The same catalogue in a client's palette, without re-cutting
a file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dark mode&lt;/strong&gt;, which is the same problem and catches most teams after launch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Any container&lt;/strong&gt; — round avatars, rounded cards, overlays on a photo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MP4 on demand.&lt;/strong&gt; Pick the background, run the recipe below, ship video
where it helps, regenerate it at the next redesign.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Same movement, both ways, on two surfaces:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3p3045ccgg3vkkw1y8gk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3p3045ccgg3vkkw1y8gk.png" alt="The same animation as a transparent WebP and as an MP4 with a dark panel baked in, each shown on a dark panel and a light card. The MP4 is a hard dark rectangle on the light card." width="760" height="876"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The video is a fraction of the bytes and completely correct — on the panel it&lt;br&gt;
was exported for. Move it to a light card and it is simply wrong. Fine, as long&lt;br&gt;
as it is a derivative you can regenerate rather than the only copy you own.&lt;/p&gt;
&lt;h2&gt;
  
  
  What MP4 costs you back
&lt;/h2&gt;

&lt;p&gt;A twelve-card grid, three ways, every tile at 240 CSS px, Chrome on a desktop&lt;br&gt;
over localhost:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Grid of 12&lt;/th&gt;
&lt;th&gt;Bytes&lt;/th&gt;
&lt;th&gt;Load&lt;/th&gt;
&lt;th&gt;Sustained frame rate&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;480px stills&lt;/td&gt;
&lt;td&gt;0.26 MB&lt;/td&gt;
&lt;td&gt;54 ms&lt;/td&gt;
&lt;td&gt;56 fps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;960px animated WebP&lt;/td&gt;
&lt;td&gt;37.92 MB&lt;/td&gt;
&lt;td&gt;83 ms&lt;/td&gt;
&lt;td&gt;56 fps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MP4, background baked in&lt;/td&gt;
&lt;td&gt;1.97 MB&lt;/td&gt;
&lt;td&gt;296 ms&lt;/td&gt;
&lt;td&gt;28 fps&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The MP4 grid moved 20x fewer bytes and ran at half the frame rate: twelve&lt;br&gt;
&lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; elements decoding and compositing at once is real work. Pausing&lt;br&gt;
eleven put it back to 56 fps; resuming them dropped it to 28 again.&lt;/p&gt;
&lt;h3&gt;
  
  
  The WebP row needs a warning label
&lt;/h3&gt;

&lt;p&gt;That 56 fps is the &lt;em&gt;page's&lt;/em&gt; frame rate from &lt;code&gt;requestAnimationFrame&lt;/code&gt;. An&lt;br&gt;
animated image decodes and rasters outside the page's animation loop, so a clip&lt;br&gt;
can drop half its frames while the page reports a calm 56 — and no browser API&lt;br&gt;
exposes an image's real playback rate. Drawing it to a canvas returns a frozen&lt;br&gt;
frame, not the current one.&lt;/p&gt;

&lt;p&gt;The decode work can be measured, with the browser's own &lt;code&gt;ImageDecoder&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;buf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;arrayBuffer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ImageDecoder&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;image/webp&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;dec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tracks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ready&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;dec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;completed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;frames&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tracks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;selectedTrack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;frameCount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;t0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;frames&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;dec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;frameIndex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;t0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;frames&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ms per frame&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Four clips, every frame, best of three passes:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Clip&lt;/th&gt;
&lt;th&gt;Frames&lt;/th&gt;
&lt;th&gt;960 px&lt;/th&gt;
&lt;th&gt;480 px&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Mountain Climbers&lt;/td&gt;
&lt;td&gt;34&lt;/td&gt;
&lt;td&gt;4.48 ms/frame&lt;/td&gt;
&lt;td&gt;0.82 ms/frame&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Battle Ropes&lt;/td&gt;
&lt;td&gt;99&lt;/td&gt;
&lt;td&gt;4.61 ms/frame&lt;/td&gt;
&lt;td&gt;0.95 ms/frame&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Incline Dumbbell Curl&lt;/td&gt;
&lt;td&gt;60&lt;/td&gt;
&lt;td&gt;5.16 ms/frame&lt;/td&gt;
&lt;td&gt;1.09 ms/frame&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Side-Lying Lateral Raise&lt;/td&gt;
&lt;td&gt;41&lt;/td&gt;
&lt;td&gt;5.41 ms/frame&lt;/td&gt;
&lt;td&gt;1.07 ms/frame&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;At the clips' own 20 fps that is &lt;strong&gt;90–108 ms of decode per second of playback&lt;/strong&gt;&lt;br&gt;
for a 960px clip — a tenth of a core, per clip, on a fast desktop. At 480px,&lt;br&gt;
16–22 ms.&lt;/p&gt;

&lt;p&gt;Twelve of them need ~1.1 s of decode per second of wall clock. Nothing plays&lt;br&gt;
correctly under that. The page stayed at 56 fps because the animations, not the&lt;br&gt;
page, absorbed the shortfall — where the metric could not see it.&lt;/p&gt;

&lt;p&gt;So:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MP4&lt;/strong&gt; is far cheaper to download, rides the video pipeline, and gets
expensive in bulk — visibly, in the page's frame rate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Animated WebP&lt;/strong&gt; is heavier to download, costs ~10% of a core per master
clip to play, and degrades &lt;em&gt;invisibly&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A still&lt;/strong&gt; beats both wherever nobody is studying the motion.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whatever you pick, play one clip at a time. That single rule outperforms the&lt;br&gt;
format choice.&lt;/p&gt;
&lt;h2&gt;
  
  
  Converting: the recipe that actually works
&lt;/h2&gt;

&lt;p&gt;This is where the standard advice fails. The obvious command —&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# does NOT work on these clips&lt;/span&gt;
ffmpeg &lt;span class="nt"&gt;-i&lt;/span&gt; animation.webp ... output.mp4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;— fails on FFmpeg 8.1 with &lt;code&gt;image data not found&lt;/code&gt;. FFmpeg only learned to&lt;br&gt;
decode animated WebP in 7.1, and its decoder still chokes on clips whose frames&lt;br&gt;
are stored as blended sub-rectangles rather than full canvases, which is what a&lt;br&gt;
size-optimised encoder produces. Every clip I tried failed the same way.&lt;/p&gt;

&lt;p&gt;Extract the frames with libwebp's &lt;code&gt;anim_dump&lt;/code&gt; first — it composites each frame&lt;br&gt;
onto the full canvas — then encode the PNG sequence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;CLIP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;animation.webp

&lt;span class="c"&gt;# 1. frames out (libwebp ships anim_dump alongside cwebp)&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; frames
anim_dump &lt;span class="nt"&gt;-folder&lt;/span&gt; frames &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CLIP&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# 2. the clip's own rate rather than a guess: frames / total duration&lt;/span&gt;
&lt;span class="nv"&gt;FPS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;webpinfo &lt;span class="nt"&gt;-summary&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CLIP&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'/Duration/ {n++; ms += $2} END {printf "%.0f", n / (ms / 1000)}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# 3. composite on the panel colour and encode&lt;/span&gt;
ffmpeg &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-framerate&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$FPS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"frames/dump_%04d.png"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-f&lt;/span&gt; lavfi &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"color=c=#111827:s=960x960:r=&lt;/span&gt;&lt;span class="nv"&gt;$FPS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-filter_complex&lt;/span&gt; &lt;span class="s2"&gt;"[1:v][0:v]overlay=shortest=1:format=auto,format=yuv420p[v]"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-map&lt;/span&gt; &lt;span class="s2"&gt;"[v]"&lt;/span&gt; &lt;span class="nt"&gt;-an&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-c&lt;/span&gt;:v libx264 &lt;span class="nt"&gt;-crf&lt;/span&gt; 23 &lt;span class="nt"&gt;-preset&lt;/span&gt; medium &lt;span class="nt"&gt;-movflags&lt;/span&gt; +faststart &lt;span class="se"&gt;\&lt;/span&gt;
  output.mp4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three things that bite:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frame rate.&lt;/strong&gt; The colour source dictates the output rate through the
overlay, so both &lt;code&gt;-framerate&lt;/code&gt; and &lt;code&gt;r=&lt;/code&gt; must match the clip. Assume 25 and you
ship duplicated frames.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Alpha edges.&lt;/strong&gt; Check the result on a light &lt;em&gt;and&lt;/em&gt; a dark background.
Incorrect compositing shows up as a pale fringe around thin objects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;crf.&lt;/strong&gt; 23 is a safe default; 28 roughly halved the files again with no
obvious loss at card size — flat illustration compresses well.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Choosing between them
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Requirement&lt;/th&gt;
&lt;th&gt;Choice&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Asset must sit on light, dark, and brand surfaces&lt;/td&gt;
&lt;td&gt;Animated WebP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;One fixed background across the product&lt;/td&gt;
&lt;td&gt;MP4 derivative&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Display with a plain &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Animated WebP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Play, pause, seek, visibility control&lt;/td&gt;
&lt;td&gt;MP4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Several clips visible at once&lt;/td&gt;
&lt;td&gt;Neither — stills, one active clip&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bandwidth-critical, single active clip&lt;/td&gt;
&lt;td&gt;MP4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A master you can re-theme without a transcode step&lt;/td&gt;
&lt;td&gt;Animated WebP&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Method
&lt;/h2&gt;

&lt;p&gt;Six clips from the August 2026 build, 1.3–5.1 MB, covering the size range of 442&lt;br&gt;
shipped animations. WebP variants re-encoded at quality 90, method 4,&lt;br&gt;
&lt;code&gt;exact=True&lt;/code&gt;, disposal 2. MP4 encoded with FFmpeg 8.1, libx264, crf 23/28,&lt;br&gt;
&lt;code&gt;medium&lt;/code&gt; preset. Grid test: Chrome on a desktop, twelve cards at 240 CSS px in&lt;br&gt;
a four-column grid, served over localhost, frame rate sampled over three&lt;br&gt;
seconds via &lt;code&gt;requestAnimationFrame&lt;/code&gt;. Localhost removes the network, which is&lt;br&gt;
why the byte column deserves more weight than the load column. Decode cost:&lt;br&gt;
Chrome's &lt;code&gt;ImageDecoder&lt;/code&gt;, file already in memory, so it isolates decode from&lt;br&gt;
network and layout.&lt;/p&gt;

&lt;p&gt;Reading an animated image's &lt;em&gt;actual&lt;/em&gt; on-screen frame rate is not possible from&lt;br&gt;
page JavaScript. Where this post says an animation stutters, that is an&lt;br&gt;
observation; the decode budget is the measurement that explains it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try the assets in your own app
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;RepDB Standard is a good fit when you want smooth exercise animations, transparent backgrounds, and one consistent character without producing an animation library yourself.&lt;/strong&gt; Use transparent stills in lists, load one motion clip on the detail screen, and generate MP4 derivatives for fixed-background players.&lt;/p&gt;

&lt;p&gt;The paid September 4, 2026 snapshot contains &lt;strong&gt;608 exercise records: 496 with motion clips and 112 with static illustrations&lt;/strong&gt;. Those are current product counts; the 442-clip catalogue described in the benchmark is the earlier August snapshot, and the measurements above have not been rerun. Motion coverage counts exercise records; close variants can share a clip.&lt;/p&gt;

&lt;p&gt;Standard costs &lt;strong&gt;$499 once&lt;/strong&gt;, with transparent classic assets, classic + flat stills, JSON/SQLite, workout templates, and embeddings. You host the files and can use them in your own commercial products without required attribution or a runtime API subscription. Third-party branded client deployments require Custom.&lt;/p&gt;

&lt;p&gt;There is also a separate &lt;strong&gt;601-exercise Free Tier&lt;/strong&gt; with flat 512×512 stills and JSON for commercial in-app use with attribution. &lt;strong&gt;The animation preview is for evaluation; production use of those clips requires a paid license.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://repdb.co/preview/?utm_source=devto" rel="noopener noreferrer"&gt;Browse the animation preview →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://repdb.co/pricing/?utm_source=devto" rel="noopener noreferrer"&gt;Standard details &amp;amp; pricing →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://repdb.co/blog/animated-webp-vs-mp4-exercise-animations/?utm_source=devto" rel="noopener noreferrer"&gt;original article&lt;/a&gt; has the live figures. If you are choosing a supplier as well as a format, see the &lt;a href="https://repdb.co/blog/best-exercise-datasets-with-animations/?utm_source=devto" rel="noopener noreferrer"&gt;exercise animation library comparison&lt;/a&gt; for RepDB, Vital Animations, GymVisual, and Movekit.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>performance</category>
      <category>javascript</category>
      <category>fitness</category>
    </item>
    <item>
      <title>ExerciseDB vs WorkoutX vs free-exercise-db vs RepDB (2026)</title>
      <dc:creator>sergei argutin</dc:creator>
      <pubDate>Sat, 18 Jul 2026 19:17:16 +0000</pubDate>
      <link>https://dev.to/sergeiargutin/exercisedb-vs-workoutx-vs-free-exercise-db-vs-repdb-2026-3aj3</link>
      <guid>https://dev.to/sergeiargutin/exercisedb-vs-workoutx-vs-free-exercise-db-vs-repdb-2026-3aj3</guid>
      <description>&lt;p&gt;An exercise dataset supplies more than names and instructions. Its images become part of almost every screen in your fitness app. A large catalogue can still leave you with mismatched artwork, opaque backgrounds, or an API dependency you did not want.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If your priority is smooth exercise animations, transparent backgrounds, and one consistent character, RepDB Standard is the option I would shortlist from these four.&lt;/strong&gt; ExerciseDB is worth comparing for its larger advertised entry count; WorkoutX for hosted delivery; free-exercise-db for a free collection with gym photography.&lt;/p&gt;

&lt;p&gt;I build and sell RepDB. This is a disclosed comparison based on public product information and the samples I inspected, with the tradeoffs spelled out so you can decide for your app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compare the product you would actually ship
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;ExerciseDB&lt;/th&gt;
&lt;th&gt;WorkoutX&lt;/th&gt;
&lt;th&gt;free-exercise-db&lt;/th&gt;
&lt;th&gt;RepDB&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Delivery&lt;/td&gt;
&lt;td&gt;Downloadable files&lt;/td&gt;
&lt;td&gt;Hosted API&lt;/td&gt;
&lt;td&gt;GitHub files&lt;/td&gt;
&lt;td&gt;Downloadable files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Visuals&lt;/td&gt;
&lt;td&gt;Animated GIFs&lt;/td&gt;
&lt;td&gt;Hosted GIFs&lt;/td&gt;
&lt;td&gt;Gym photographs&lt;/td&gt;
&lt;td&gt;Consistent classic + flat WebP styles&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Background in inspected media&lt;/td&gt;
&lt;td&gt;Opaque, near-white&lt;/td&gt;
&lt;td&gt;Opaque, near-white&lt;/td&gt;
&lt;td&gt;Gym surroundings&lt;/td&gt;
&lt;td&gt;Transparent classic assets on Standard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Motion&lt;/td&gt;
&lt;td&gt;GIF animations&lt;/td&gt;
&lt;td&gt;GIF animations via API&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Standard: 496 exercises with motion clips; 112 use static illustrations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Offline use&lt;/td&gt;
&lt;td&gt;Self-host the files&lt;/td&gt;
&lt;td&gt;Depends on API terms and caching limits&lt;/td&gt;
&lt;td&gt;Local files&lt;/td&gt;
&lt;td&gt;Self-host or bundle the files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Price&lt;/td&gt;
&lt;td&gt;$199 Starter / $599 Pro, once&lt;/td&gt;
&lt;td&gt;Free plan; $9.99–24.99/month paid plans&lt;/td&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;td&gt;Free snapshot; $299 Starter / $499 Standard, once&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Prices and advertised delivery formats checked September 8, 2026. Competitor image observations refer to the July 2026 samples, not every asset in their paid catalogues. Sources are listed at the end.&lt;/p&gt;

&lt;h2&gt;
  
  
  Look at the artwork before choosing the schema
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv9g211me6fo2eq6lnqny.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv9g211me6fo2eq6lnqny.png" alt="ExerciseDB and WorkoutX, free-exercise-db, RepDB classic, and RepDB flat compared side by side" width="800" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The visual decision is easier to make with examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ExerciseDB / the WorkoutX sample:&lt;/strong&gt; an illustrated figure on an opaque near-white panel.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;free-exercise-db:&lt;/strong&gt; real gym photography with varying framing, backgrounds, and dimensions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RepDB classic:&lt;/strong&gt; one consistent character, with transparent assets on Standard.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RepDB flat:&lt;/strong&gt; a consistent illustrated style, also available in the free snapshot.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a light card, an opaque panel may be fine. On dark mode, a gradient, or a circular container, the panel becomes part of your design whether you want it or not. Transparent media lets your UI choose the background.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs8r8flyw6vg8vks8mf79.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs8r8flyw6vg8vks8mf79.png" alt="The same transparent RepDB classic image on dark, light, gradient, and circular UI surfaces" width="800" height="265"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Still frames cannot show animation quality. Watch the movement, character, and background together in the &lt;strong&gt;&lt;a href="https://repdb.co/preview/?utm_source=devto" rel="noopener noreferrer"&gt;RepDB animation preview&lt;/a&gt;&lt;/strong&gt;. The &lt;a href="https://repdb.co/blog/exercisedb-alternatives-2026/?utm_source=devto#the-images-decide-it" rel="noopener noreferrer"&gt;original comparison has a live motion example&lt;/a&gt;; DEV's image proxy does not reliably preserve that transparent animated WebP.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where each dataset fits
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ExerciseDB: a larger advertised catalogue
&lt;/h3&gt;

&lt;p&gt;ExerciseDB lists 1,394 entries. Starter provides self-hosted data and 180px/360px GIFs for $199; Pro adds 720px/1080px GIFs, taxonomy, and relationships for $599. Those are raw entry counts; I have not deduplicated the catalogue.&lt;/p&gt;

&lt;p&gt;It is worth shortlisting if coverage breadth and a one-time file download are your priorities. Check the actual exercises you need and whether the opaque GIF style fits your product.&lt;/p&gt;

&lt;h3&gt;
  
  
  WorkoutX: a hosted exercise API
&lt;/h3&gt;

&lt;p&gt;WorkoutX supplies exercise metadata and GIFs through an API. Its free plan lists 500 requests per month; paid monthly plans range from $9.99 to $24.99.&lt;/p&gt;

&lt;p&gt;It fits developers who prefer hosted delivery to managing a local bundle. Check request quotas and caching terms against your expected traffic and offline requirements.&lt;/p&gt;

&lt;h3&gt;
  
  
  free-exercise-db: a free start with real photographs
&lt;/h3&gt;

&lt;p&gt;free-exercise-db is easy to clone and useful for prototypes that suit gym photography. The code and JSON are published under the Unlicense. For commercial use, review the photographs' provenance as well as the repository license.&lt;/p&gt;

&lt;p&gt;The UI tradeoff is visible in the examples: framing, backgrounds, and image dimensions vary. Choose it if the free starting point and photography suit your app.&lt;/p&gt;

&lt;h3&gt;
  
  
  RepDB Standard: a consistent animated exercise library
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;RepDB Standard is built for fitness apps that need smooth looping animations, transparent backgrounds, and one consistent character.&lt;/strong&gt; You can use the same classic assets across light mode, dark mode, and brand surfaces, then host them yourself or bundle them for offline use.&lt;/p&gt;

&lt;p&gt;The September 4, 2026 paid snapshot contains &lt;strong&gt;608 exercise records: 496 with motion clips and 112 with static illustrations&lt;/strong&gt;. Standard costs &lt;strong&gt;$499 once&lt;/strong&gt; and includes classic + flat stills, transparent classic assets, JSON/SQLite, exercise relations, workout templates, and embeddings. Instructions in EN/DE/ES are also included.&lt;/p&gt;

&lt;p&gt;Starter is $299 for the same paid exercise list with classic + flat stills and JSON. &lt;strong&gt;Animations and transparent classic assets are Standard features.&lt;/strong&gt; Both paid tiers cover commercial use in your own products without required attribution; client deployments under another company's brand require Custom.&lt;/p&gt;

&lt;p&gt;The practical reason to pay for Standard is the visual system: your exercise screens keep the same character and style while your app controls the surface. Inspect the movements that matter to your product before choosing a library.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://repdb.co/preview/?utm_source=devto" rel="noopener noreferrer"&gt;Browse the animation preview →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://repdb.co/pricing/?utm_source=devto" rel="noopener noreferrer"&gt;Standard details &amp;amp; pricing →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Can I start with RepDB for free?
&lt;/h2&gt;

&lt;p&gt;Yes. The separate &lt;strong&gt;601-exercise public snapshot&lt;/strong&gt; has JSON, flat 512×512 WebP images, instructions, muscles, equipment, MET values, goals, and tags. It permits commercial in-app use with visible attribution. It can lag behind the paid catalogue and does not include a production license for the animation samples.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://exercise-dataset.com/" rel="noopener noreferrer"&gt;Browse the free viewer&lt;/a&gt; or &lt;a href="https://github.com/RepDB/exercise-dataset" rel="noopener noreferrer"&gt;download the GitHub dataset&lt;/a&gt;. Free fits apps that need still illustrations; Standard is the upgrade when you need transparent animations and the consistent classic character.&lt;/p&gt;

&lt;h2&gt;
  
  
  My recommendation by use case
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A fitness app with animated demonstrations, dark mode, and a consistent character:&lt;/strong&gt; evaluate RepDB Standard.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A larger advertised entry count with self-hosted GIFs:&lt;/strong&gt; compare ExerciseDB's coverage with your exercise list.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A hosted API instead of local files:&lt;/strong&gt; evaluate WorkoutX's quotas and delivery terms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A free prototype built around gym photographs:&lt;/strong&gt; consider free-exercise-db.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A free app using consistent flat illustrations:&lt;/strong&gt; start with RepDB Free Tier.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are also considering Vital Animations, GymVisual, or Movekit, I compared their visual approaches and public previews in &lt;strong&gt;&lt;a href="https://repdb.co/blog/best-exercise-datasets-with-animations/?utm_source=devto" rel="noopener noreferrer"&gt;this exercise animation library comparison&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources and scope
&lt;/h2&gt;

&lt;p&gt;Public pricing and delivery information checked September 8, 2026:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ExerciseDB: &lt;code&gt;exercisedb.io/pricing&lt;/code&gt; and &lt;code&gt;exercisedb.io/terms&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;WorkoutX: &lt;code&gt;workoutxapp.com&lt;/code&gt; and &lt;code&gt;workoutxapp.com/terms.html&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;free-exercise-db: &lt;code&gt;github.com/yuhonas/free-exercise-db&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;RepDB: &lt;a href="https://repdb.co/pricing/?utm_source=devto" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;, &lt;a href="https://repdb.co/license/?utm_source=devto" rel="noopener noreferrer"&gt;license&lt;/a&gt;, and the September 4 shipping snapshot.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;File-level competitor observations date to July 2026. RepDB's motion count refers to exercise records, not necessarily unique clips; close variants can share an animation. The public Free count was checked September 8. I build and sell RepDB; third-party names and sample imagery are used for identification and comparison.&lt;/p&gt;

</description>
      <category>data</category>
      <category>webdev</category>
      <category>api</category>
      <category>fitness</category>
    </item>
    <item>
      <title>Free exercise dataset for fitness apps: JSON + images, with a path to animations</title>
      <dc:creator>sergei argutin</dc:creator>
      <pubDate>Mon, 29 Jun 2026 14:43:40 +0000</pubDate>
      <link>https://dev.to/sergeiargutin/free-exercise-data-for-your-fitness-app-json-images-endees-5d9f</link>
      <guid>https://dev.to/sergeiargutin/free-exercise-data-for-your-fitness-app-json-images-endees-5d9f</guid>
      <description>&lt;p&gt;Building an exercise search, workout planner, or fitness app? &lt;strong&gt;RepDB Free Tier gives you 601 exercises with JSON metadata and flat 512×512 WebP images&lt;/strong&gt;, ready to use inside a commercial app with attribution. There is no account, API key, or monthly request quota.&lt;/p&gt;

&lt;p&gt;When the app needs animated demonstrations, &lt;strong&gt;RepDB Standard adds smooth looping animations with transparent backgrounds and one consistent character&lt;/strong&gt;. That is the upgrade: exercise media that fits your product's design, alongside the data you already need.&lt;/p&gt;

&lt;p&gt;I build and sell RepDB. Here is what you can use for free, how to load it, and when Standard makes sense.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with the free dataset
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;601 exercise records:&lt;/strong&gt; names, target muscles, equipment, categories, MET values, goals, and tags.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flat illustrations at 512×512:&lt;/strong&gt; WebP start/peak poses, or one image where appropriate.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Instructions in English, German, and Spanish.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Files you can host yourself:&lt;/strong&gt; bundle the JSON and images with your app or serve them from your own infrastructure.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://exercise-dataset.com/" rel="noopener noreferrer"&gt;Browse the free exercise viewer&lt;/a&gt; or &lt;a href="https://github.com/RepDB/exercise-dataset" rel="noopener noreferrer"&gt;get the files on GitHub&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://exercise-dataset.com/exercises.json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Dataset request failed: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dataset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// The downloaded snapshot's own count.&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exercises&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;images&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;flat&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use that to inspect the data, then keep your own copy for production and offline access. &lt;a href="https://repdb.co/examples/?utm_source=devto" rel="noopener noreferrer"&gt;Next.js, React Native, and Flutter examples&lt;/a&gt; show how to build an exercise browser around the files.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/RepDB/exercise-dataset/blob/main/LICENSE-DATA.md" rel="noopener noreferrer"&gt;Free Tier License&lt;/a&gt; allows personal and commercial in-app use with a visible RepDB credit. It does not allow republishing the data as a dataset or API. Paid animation samples in &lt;code&gt;premium-samples/&lt;/code&gt; are evaluation-only; the free commercial-use permission does not cover those clips.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to choose RepDB Standard
&lt;/h2&gt;

&lt;p&gt;Choose &lt;strong&gt;Standard&lt;/strong&gt; when the exercise screen needs to look like part of your app:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Transparent backgrounds:&lt;/strong&gt; put the same classic asset on light cards, dark mode, or brand gradients.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smooth looping animations:&lt;/strong&gt; let users watch the movement on the exercise detail screen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One consistent character:&lt;/strong&gt; keep a coherent visual identity across the animation library.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs8r8flyw6vg8vks8mf79.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs8r8flyw6vg8vks8mf79.png" alt="The same RepDB classic exercise illustration on dark, light, gradient, and circular UI surfaces" width="800" height="265"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://repdb.co/preview/?utm_source=devto" rel="noopener noreferrer"&gt;Browse the animation preview →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Free&lt;/th&gt;
&lt;th&gt;Starter&lt;/th&gt;
&lt;th&gt;Standard&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Price&lt;/td&gt;
&lt;td&gt;Free with attribution&lt;/td&gt;
&lt;td&gt;$299 once&lt;/td&gt;
&lt;td&gt;$499 once&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Exercise records&lt;/td&gt;
&lt;td&gt;601 public snapshot&lt;/td&gt;
&lt;td&gt;608&lt;/td&gt;
&lt;td&gt;608&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stills&lt;/td&gt;
&lt;td&gt;Flat, 512×512&lt;/td&gt;
&lt;td&gt;Classic + flat, 1024×1024&lt;/td&gt;
&lt;td&gt;Classic + flat, 1024×1024&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transparent classic assets&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Motion coverage&lt;/td&gt;
&lt;td&gt;Evaluation samples only&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;496 exercises with motion clips; 112 use static illustrations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Commercial use in your own app&lt;/td&gt;
&lt;td&gt;With attribution&lt;/td&gt;
&lt;td&gt;Without required attribution&lt;/td&gt;
&lt;td&gt;Without required attribution&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Standard also includes JSON/SQLite, exercise relations, workout templates, and embeddings for search. You host the files and keep using the version you buy; there is no runtime API subscription. Third-party branded client deployments require Custom.&lt;/p&gt;

&lt;p&gt;Free is a separate public snapshot, so its exercise count can lag behind the paid bundle. Counts above were checked September 8, 2026; paid coverage is from the September 4 shipping snapshot. Motion coverage counts exercise records; close variants can share a clip.&lt;/p&gt;

&lt;p&gt;If still illustrations fit your app, start with Free. If transparent animations and a consistent character are part of the product you want to ship, evaluate Standard's real files in your UI before buying.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://repdb.co/pricing/?utm_source=devto" rel="noopener noreferrer"&gt;Standard details &amp;amp; pricing →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>data</category>
      <category>webdev</category>
      <category>fitness</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
