# How to Add Custom Exercises to the Dataset While Maintaining Schema Compliance

> Easily add custom exercises to the dataset while ensuring schema compliance. Learn how to structure your JSON, include multilingual fields, and validate your entries.

- Repository: [Hasan Emir Yıldırım/exercises-dataset](https://github.com/hasaneyldrm/exercises-dataset)
- Tags: how-to-guide
- Published: 2026-07-30

---

**You add custom exercises to the dataset by appending a properly structured JSON object to [`data/exercises.json`](https://github.com/hasaneyldrm/exercises-dataset/blob/main/data/exercises.json) that conforms to the JSON-Schema defined in [`data/exercises.schema.json`](https://github.com/hasaneyldrm/exercises-dataset/blob/main/data/exercises.schema.json), including required multilingual fields, media references, and running validation with tools like `jsonschema` or `ajv` before committing.**

The **hasaneyldrm/exercises-dataset** repository provides a self-contained, client-side data layer powering fitness applications with 1,324 structured exercise records. When extending this dataset, maintaining strict **schema compliance** ensures that downstream tools—including the interactive HTML browsers and validation scripts—continue to function without errors.

## Understanding the Schema Architecture

The schema is defined in [`data/exercises.schema.json`](https://github.com/hasaneyldrm/exercises-dataset/blob/main/data/exercises.schema.json) using **JSON-Schema Draft 2020-12**, which serves as the single source of truth for all record validation. According to the source code, every exercise object must include specific property types, required fields, and allowed enumerations to be considered valid.

Key schema requirements include:

- **String identifiers**: `id`, `name`, `category`, `body_part`, `equipment`
- **Multilingual content**: `instructions` and `instruction_steps` objects containing keys for `en`, `es`, `it`, `tr`, `ru`, `zh`, `hi`, `pl`, `ko`, and `fr`
- **Media references**: `image` (path to 180×180 thumbnail) and `gif_url` (path to animation)
- **Taxonomy fields**: `muscle_group`, `secondary_muscles` (array), `target`
- **Metadata**: `media_id`, `attribution`, `created_at` (ISO 8601)

## Preparing Media Assets

Before modifying the JSON file, prepare the visual assets following the repository's strict specifications. The dataset expects specific dimensions and formats to render correctly in [`index.html`](https://github.com/hasaneyldrm/exercises-dataset/blob/main/index.html).

Place assets in the correct directories:

- **Images**: Store 180×180 pixel thumbnails in `images/` using the naming convention `{id}-{media_id}.jpg`
- **Videos**: Store animation GIFs in `videos/` using the naming convention `{id}-{media_id}.gif`

For example, an exercise with `id: "9999"` and `media_id: "myJumpSquat"` requires:

- `images/9999-myJumpSquat.jpg`
- `videos/9999-myJumpSquat.gif`

## Step-by-Step Schema-Compliant Addition

Follow this sequence to ensure your custom exercise passes validation.

### Construct the JSON Object

Create a new exercise object that includes all required fields. The `instructions` and `instruction_steps` objects must contain all nine supported language keys, even if you duplicate English text or use empty strings for missing translations.

```json
{
  "id": "9999",
  "name": "Custom Jump Squat",
  "category": "upper legs",
  "body_part": "upper legs",
  "equipment": "body weight",
  "instructions": {
    "en": "Begin standing, dip into a squat, then explode upward.",
    "es": "...",
    "it": "...",
    "tr": "...",
    "ru": "...",
    "zh": "...",
    "hi": "...",
    "pl": "...",
    "ko": "...",
    "fr": "..."
  },
  "instruction_steps": {
    "en": ["Stand", "Squat", "Jump"]
  },
  "muscle_group": "quadriceps",
  "secondary_muscles": ["glutes", "calves"],
  "target": "quads",
  "media_id": "myJumpSquat",
  "image": "images/9999-myJumpSquat.jpg",
  "gif_url": "videos/9999-myJumpSquat.gif",
  "attribution": "© Gym visual — https://gymvisual.com/",
  "created_at": "2024-01-15T10:00:00Z"
}

```

### Validate Before Committing

Run schema validation using Python's `jsonschema` library or Node's `ajv` to catch structural errors before adding to the dataset.

**Python Validation**:

```python
import json, jsonschema

with open("data/exercises.json", encoding="utf-8") as f:
    exercises = json.load(f)
with open("data/exercises.schema.json", encoding="utf-8") as f:
    schema = json.load(f)

# Validate the new entry (last element)

jsonschema.validate(exercises[-1], schema)
print("Schema validation passed")

```

**Node.js Validation**:

```javascript
const Ajv = require("ajv");
const ajv = new Ajv({strict: false});
const schema = require("./data/exercises.schema.json");
const exercises = require("./data/exercises.json");

const validate = ajv.compile(schema);
const valid = validate(exercises[exercises.length - 1]);
if (!valid) console.log(validate.errors);

```

### Append to the Dataset

Open [`data/exercises.json`](https://github.com/hasaneyldrm/exercises-dataset/blob/main/data/exercises.json) and append your new object to the array, ensuring proper JSON syntax with comma separators between entries. The file contains 1,324 existing records as of the latest commit.

### Verify in the Browser

Open [`index.html`](https://github.com/hasaneyldrm/exercises-dataset/blob/main/index.html) in a web browser to verify the new exercise renders correctly with its thumbnail and animation. The client-side browser reads [`exercises.json`](https://github.com/hasaneyldrm/exercises-dataset/blob/main/exercises.json) directly and applies the same schema constraints for filtering and display.

## Automating Custom Exercise Addition

For bulk additions or automated workflows, use programmatic scripts to maintain consistency.

### Node.js CLI Script

This script from the source code safely appends a new exercise while preserving JSON formatting:

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

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

const newExercise = {
  id: "9999",
  name: "Custom Jump Squat",
  category: "upper legs",
  body_part: "upper legs",
  equipment: "body weight",
  instructions: {
    en: "Begin standing, dip into a squat, then explode upward.",
    es: "...", it: "...", tr: "...", ru: "...", zh: "...", hi: "...", pl: "...", ko: "...", fr: "..."
  },
  instruction_steps: { en: ["Stand", "Squat", "Jump"] },
  muscle_group: "quadriceps",
  secondary_muscles: ["glutes", "calves"],
  target: "quads",
  media_id: "myJumpSquat",
  image: "images/9999-myJumpSquat.jpg",
  gif_url: "videos/9999-myJumpSquat.gif",
  attribution: "© Gym visual — https://gymvisual.com/",
  created_at: new Date().toISOString()
};

exercises.push(newExercise);
fs.writeFileSync(dataPath, JSON.stringify(exercises, null, 2));
console.log("Custom exercise added.");

```

### TypeScript Interface for Development

When building TypeScript applications that consume this dataset, use this interface to ensure compile-time schema compliance:

```typescript
interface Exercise {
  id: string;
  name: string;
  category: string;
  body_part: string;
  equipment: string;
  instructions: { [lang: string]: string };
  instruction_steps: { [lang: string]: string[] };
  muscle_group: string;
  secondary_muscles: string[];
  target: string;
  media_id: string;
  image: string;
  gif_url: string;
  attribution: string;
  created_at: string;
}

```

## Summary

- **Schema compliance** is mandatory: every custom exercise must validate against [`data/exercises.schema.json`](https://github.com/hasaneyldrm/exercises-dataset/blob/main/data/exercises.schema.json) using standard JSON-Schema Draft 2020-12 validators.
- **Multilingual support** is required: include all nine language keys (`en`, `es`, `it`, `tr`, `ru`, `zh`, `hi`, `pl`, `ko`, `fr`) in `instructions` and `instruction_steps` fields.
- **Media constraints**: supply 180×180 thumbnails in `images/` and GIF animations in `videos/`, referencing them with the `{id}-{media_id}` naming convention.
- **Validation workflow**: test new entries with Python's `jsonschema` or Node's `ajv` before committing to ensure downstream tools like [`index.html`](https://github.com/hasaneyldrm/exercises-dataset/blob/main/index.html) remain functional.
- **File locations**: modify only [`data/exercises.json`](https://github.com/hasaneyldrm/exercises-dataset/blob/main/data/exercises.json), placing assets in their respective media directories.

## Frequently Asked Questions

### What happens if I skip schema validation when adding custom exercises?

If you append an exercise that lacks required fields or contains incorrect data types, the [`index.html`](https://github.com/hasaneyldrm/exercises-dataset/blob/main/index.html) browser may fail to render the entry, and filtering functionality will break. Additionally, any Python or JavaScript code consuming the dataset will encounter parsing errors when expecting specific properties like `secondary_muscles` (array) or `created_at` (ISO 8601 string).

### Can I add exercises without media files?

Technically the JSON schema does not enforce file existence, but the `image` and `gif_url` fields are mandatory strings that must point to valid paths. If you omit the actual files in `images/` and `videos/`, the HTML browser will display broken links and missing thumbnails. Always provide 180×180 thumbnails and corresponding GIFs for complete functionality.

### Which programming languages support validating this dataset?

Any language with a JSON-Schema implementation works. According to the source code, **Python** users should use the `jsonschema` library, while **Node.js** developers can use `ajv`. Both libraries support Draft 2020-12 and can validate individual records or the entire array before you commit changes.

### How do I ensure my custom exercise IDs don't conflict with existing entries?

The existing dataset contains 1,324 exercises with numeric string IDs. When adding custom entries, use IDs outside the current range (e.g., "9000" series) or implement a UUID strategy, ensuring uniqueness within the [`data/exercises.json`](https://github.com/hasaneyldrm/exercises-dataset/blob/main/data/exercises.json) array. The schema requires `id` to be a unique string.