How to Build a Workout Generator Using the Exercises Dataset

Build a workout generator by loading the exercises.json file, filtering exercises by category, equipment, and target muscles, randomly selecting a subset, and assembling them into a structured workout with multilingual instructions and media assets.

The hasaneyldrm/exercises-dataset repository provides a ready-to-use collection of 1,324 exercises stored as a plain JSON array, making it accessible to any programming language that can parse JSON. Each exercise record contains comprehensive metadata including equipment requirements, targeted muscle groups, multilingual instructions, and URLs to thumbnail images and animated GIFs. This structure allows you to build a workout generator using the dataset by implementing a simple pipeline: ingestion, filtering, selection, and assembly.

Understanding the Dataset Structure

The core data resides in [data/exercises.json](https://github.com/hasaneyldrm/exercises-dataset/blob/main/data/exercises.json), which contains an array of exercise objects. Each object follows the schema defined in [data/exercises.schema.json](https://github.com/hasaneyldrm/exercises-dataset/blob/main/data/exercises.schema.json) (Draft 2020-12), ensuring predictable structure for validation.

Key fields available for filtering and display include:

  • category – Body region classification (e.g., "chest", "upper legs", "back")
  • equipment – Required gear (e.g., "dumbbell", "barbell", "body weight")
  • target – Primary muscle group targeted (e.g., "biceps", "glutes", "abs")
  • instructions – Multilingual object with keys like "en", "es", "fr"
  • image – URL to the exercise thumbnail
  • gif_url – URL to the animated demonstration

Step-by-Step Implementation Architecture

When you build a workout generator using the dataset, implement these four logical layers:

Data Ingestion and Validation

Load the JSON file into memory at application startup. For production systems, validate against [data/exercises.schema.json](https://github.com/hasaneyldrm/exercises-dataset/blob/main/data/exercises.schema.json) to ensure schema compliance before processing.

Filtering by User Criteria

Construct predicate functions that accept parameters such as category, equipment, and target. Apply these filters sequentially to narrow the pool of available exercises based on user constraints or equipment availability.

Selection and Diversity Logic

From the filtered subset, implement selection strategies. Use random sampling for variety, or apply weighted probability and difficulty-based ordering for progressive overload. Enforce diversity rules—such as limiting exercises per muscle group—to ensure balanced workouts.

Workout Assembly and Export

Map the selected exercise objects into a client-ready format including id, name, category, equipment, target, localized instructions, and media URLs. Serialize as JSON for API responses or direct browser consumption.

Code Implementation Examples

Python Workout Generator

This implementation loads the dataset once, provides flexible filtering, and returns workout objects ready for API serialization:

import json
import random
import pathlib

DATA_PATH = pathlib.Path(__file__).parent / "data" / "exercises.json"

with DATA_PATH.open(encoding="utf-8") as f:
    EXERCISES = json.load(f)

def filter_exercises(category=None, equipment=None, target=None):
    result = EXERCISES
    if category:
        result = [e for e in result if e["category"] == category]
    if equipment:
        result = [e for e in result if e["equipment"] == equipment]
    if target:
        result = [e for e in result if e["target"] == target]
    return result

def generate_workout(count=6, **filters):
    pool = filter_exercises(**filters)
    chosen = random.sample(pool, min(count, len(pool)))
    return [
        {
            "id": ex["id"],
            "name": ex["name"],
            "category": ex["category"],
            "equipment": ex["equipment"],
            "target": ex["target"],
            "instruction": ex["instructions"]["en"],
            "image": ex["image"],
            "gif": ex["gif_url"],
        }
        for ex in chosen
    ]

# Generate 6 body-weight chest exercises

workout = generate_workout(count=6, equipment="body weight", category="chest")
print(json.dumps(workout, indent=2))

Node.js REST API Endpoint

Use this pattern for an Express-based backend that serves filtered workouts via HTTP:

const path = require("path");
const fs = require("fs");

const EXERCISES = JSON.parse(
  fs.readFileSync(path.join(__dirname, "data", "exercises.json"), "utf-8")
);

function filterExercises({ category, equipment, target } = {}) {
  return EXERCISES.filter((e) => {
    return (
      (!category || e.category === category) &&
      (!equipment || e.equipment === equipment) &&
      (!target || e.target === target)
    );
  });
}

function generateWorkout({ count = 6, language = "en", ...filters } = {}) {
  const pool = filterExercises(filters);
  const shuffled = pool.sort(() => 0.5 - Math.random());
  const chosen = shuffled.slice(0, Math.min(count, pool.length));
  return chosen.map((ex) => ({
    id: ex.id,
    name: ex.name,
    category: ex.category,
    equipment: ex.equipment,
    target: ex.target,
    instruction: ex.instructions[language],
    image: ex.image,
    gif: ex.gif_url,
  }));
}

// Example Express route implementation:
// app.get("/api/workout", (req, res) => {
//   const { count, lang, category, equipment, target } = req.query;
//   const workout = generateWorkout({
//     count: Number(count) || 6,
//     language: lang || "en",
//     category,
//     equipment,
//     target,
//   });
//   res.json(workout);
// });

Browser-Based Generator

You can also build a pure-client generator without a backend. The repository includes [index.html](https://github.com/hasaneyldrm/exercises-dataset/blob/main/index.html) demonstrating live search and filtering. Load the JSON via import and run the selection logic directly:

<script type="module">
import exercises from "./data/exercises.json";

function randomWorkout({ count = 6, language = "en", filters = {} } = {}) {
  const pool = Object.values(exercises).filter((ex) => {
    return Object.entries(filters).every(
      ([k, v]) => v === undefined || ex[k] === v
    );
  });
  const chosen = [];
  while (chosen.length < count && pool.length) {
    const idx = Math.floor(Math.random() * pool.length);
    chosen.push(pool.splice(idx, 1)[0]);
  }
  return chosen.map((ex) => ({
    name: ex.name,
    instruction: ex.instructions[language],
    gif: ex.gif_url,
    img: ex.image,
  }));
}

// Generate 4 barbell upper-leg exercises
const workout = randomWorkout({
  count: 4,
  language: "en",
  filters: { equipment: "barbell", category: "upper legs" },
});
console.table(workout);
</script>

For additional setup guidance, reference [setup.html](https://github.com/hasaneyldrm/exercises-dataset/blob/main/setup.html) in the repository, which provides database import instructions and LLM-generated backend templates.

Summary

  • The exercises dataset contains 1,324 structured records with multilingual instructions and media assets located in data/exercises.json.
  • Validation against data/exercises.schema.json ensures data integrity before processing.
  • Build filtering logic around category, equipment, and target fields to match user constraints.
  • Implement random sampling or weighted selection from filtered pools to generate varied workouts.
  • Assemble final output with instructions, image, and gif_url for complete UI rendering.
  • Deploy as Python scripts, Node.js APIs, or browser-only solutions using the provided index.html reference.

Frequently Asked Questions

What data structure does the exercises dataset use?

The dataset uses a flat JSON array where each element is an exercise object containing string fields for name, category, equipment, and target, plus nested objects for multilingual instructions and URLs for media assets. This structure is formally defined in data/exercises.schema.json using JSON Schema Draft 2020-12.

How do I validate the exercises.json file before processing?

Validate the file against the provided schema using any JSON Schema validator library. In Python, use jsonschema.validate() against data/exercises.schema.json. In JavaScript, use ajv (Another JSON Schema Validator) to check compliance before loading the data into your application memory.

Can I filter exercises by multiple criteria simultaneously?

Yes. Apply filters sequentially or combine them with logical AND operations. For example, filter first by equipment: "dumbbell", then by category: "chest" to return only dumbbell chest exercises. The filtered subset can then be sampled to create equipment-specific workout splits.

How do I access the exercise animations and images?

Each exercise record includes image (thumbnail URL) and gif_url (animation URL) fields. These assets are publicly accessible and can be rendered directly in web UIs or mobile applications. Check NOTICE.md in the repository for attribution requirements and usage terms regarding the media files.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →