---
title: "Curriculum File Structure"
---

> Documentation Index
> Fetch the complete documentation index at: https://contribute.freecodecamp.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Curriculum File Structure

Our core instructional content is located within the conveniently named `curriculum` directory. This page will break down how these files are organized.

## Terminology

There are a few terms we use when discussing our curriculum content.

- `certification` : When referring to a certification in this instance, it is talking about the actual certificate that users claim. Which is separate from the name of the superBlock.
- `superBlock` : A superblock is a top level collection of challenges. Some superblocks correspond to certifications (e.g. Responsive Web Design), while others contain courses or additional practice.
- `chapter` : A chapter is a grouping of modules within a superblock. Not all superblocks use chapters; legacy superblocks organize blocks in a flat list instead.
- `module` : A module is a grouping of blocks within a chapter.
- `block` : A block is a section within a superblock. A block corresponds to a group of challenges in a given certification (e.g. Basic HTML and HTML5)
- `challenge` : A challenge is a single lesson within the curriculum (e.g. Say Hello to HTML Elements)

## File Tree

Using those terms, here is how the file structure would be defined:

```md
curriculum/
├─ challenges/
│ ├─ english/
│ │ ├─ blocks/
│ │ │ ├─ <block>/
│ │ │ │ ├─ <challenge>.md
│ │ ├─ certifications/
│ │ │ ├─ <certification>.yml
├─ i18n-curriculum/ (git submodule)
│ ├─ curriculum/
│ │ ├─ challenges/
│ │ │ ├─ <language>/
│ │ │ │ ├─ blocks/
│ │ │ │ │ ├─ <block>/
│ │ │ │ │ │ ├─ <challenge>.md
├─ structure/
│ ├─ curriculum.json
│ ├─ superblocks/
│ │ ├─ <superblock>.json
│ ├─ blocks/
│ │ ├─ <block>.json
```

## The Structure Directory

The `structure` directory contains JSON files that define the curriculum organization and are used to determine which superBlock a block belongs to, and the order of the challenges within that block.

### curriculum.json

The main `curriculum.json` file contains two arrays:

- `superblocks`: An ordered list of all superblocks in the curriculum
- `certifications`: A list of all available certifications

### superblocks/&lt;superblock&gt;.json

Each superblock has its own JSON file that defines which blocks belong to it. Simple superblocks only contain a `blocks` array:

```json
{
  "blocks": ["basic-html-and-html5", "basic-css", "applied-visual-design"]
}
```

More complex superblocks can organize blocks into chapters and modules for better structure:

```json
{
  "chapters": [
    {
      "dashedName": "html",
      "modules": [
        {
          "dashedName": "basic-html",
          "blocks": [
            "workshop-curriculum-outline",
            "lecture-welcome-to-freecodecamp",
            "lab-debug-camperbots-profile-page",
            "lecture-understanding-html-attributes"
          ]
        },
        {
          "dashedName": "semantic-html",
          "blocks": [
            "lecture-importance-of-semantic-html",
            "lecture-understanding-nuanced-semantic-elements",
            "workshop-blog-page"
          ]
        }
      ]
    },
    {
      "dashedName": "css",
      "modules": [
        {
          "dashedName": "basic-css",
          "blocks": [
            "lecture-what-is-css",
            "workshop-cafe-menu",
            "lab-business-card"
          ]
        }
      ]
    }
  ]
}
```

Modules and chapters can have additional properties that affect how they are treated:

- **`moduleType: "cert-project"`**: A module containing a single certification project block.
- **`moduleType: "review"`**: A module containing a review block.
- **`comingSoon: true`**: Marks a chapter or module as not yet available to campers.
- **`chapterType: "exam"`**: Marks a chapter as containing the certification exam.

### blocks/&lt;block&gt;.json

Each block has its own JSON file that contains metadata and the order of challenges:

```json
{
  "dashedName": "workshop-greeting-bot",
  "blockLabel": "workshop",
  "blockLayout": "challenge-grid",
  "helpCategory": "JavaScript",
  "isUpcomingChange": false,
  "usesMultifileEditor": true,
  "hasEditableBoundaries": true,
  "challengeOrder": [
    {
      "id": "66ad8294a0ad902f1b31b612",
      "title": "Step 1"
    }
  ]
}
```

Key fields:

- **`dashedName`**: URL-friendly slug for the block. The display name of the block is defined in [`intro.json`](#the-introjson-file) under the block's `title` field.
- **`blockLabel`**: The label shown on the block card. Common values are `workshop`, `lab`, `lecture`, `review`, `quiz`, `exam`, `warm-up`, `learn`, and `practice`. Legacy blocks do not have this field.
- **`blockLayout`**: Controls how the block is displayed. Common values include `challenge-grid`, `challenge-list`, and `legacy-challenge-list`.
- **`helpCategory`**: Determines which forum subforum is used when a camper requests help via the help button (e.g. `JavaScript`, `HTML-CSS`, `Python`).
- **`isUpcomingChange`**: When `true`, hides the block from campers until it is ready.
- **`usesMultifileEditor`**: When `true`, the challenge editor shows multiple files.
- **`hasEditableBoundaries`**: When `true`, part of the code is highlighted to indicate where changes should be made.
- **`challengeOrder`**: Ordered list of `{ id, title }` objects defining the sequence of challenges in the block. Challenge files in `curriculum/challenges/english/blocks/<block>/` are named after their `id` (e.g. `66ad8294a0ad902f1b31b612.md`).

## Superblock Classification

Superblocks are classified in [`packages/shared/src/config/curriculum.ts`](https://github.com/freeCodeCamp/freeCodeCamp/blob/main/packages/shared/src/config/curriculum.ts):

- `SuperBlocks` maps superblock enum members to their URL slugs.
- `SuperBlockStage` defines the categories: `Core`, `English`, `Spanish`, `Chinese`, `Professional`, `Extra`, `Legacy`, `Upcoming`, `Next`, and `Catalog`.
- `superBlockStages` lists the superblocks assigned to each category.

These categories map to the groupings on the [Learn page](https://www.freecodecamp.org/learn). `Legacy` superblocks appear on the [Archive page](https://www.freecodecamp.org/learn/archive), and `Catalog` superblocks appear in the [Catalog](https://www.freecodecamp.org/catalog). `Upcoming` superblocks are hidden.

To find a superblock's category, look up its slug in `SuperBlocks`, then find the corresponding enum member in `superBlockStages`. For example, `javascript-v9` maps to `SuperBlocks.JsV9`, which appears in `superBlockStages[SuperBlockStage.Core]`.

Use `superBlockStages` to find category membership, the files in `curriculum/structure/superblocks/` to find chapters, modules, and blocks, and [`intro.json`](#the-introjson-file) to find display titles and introductory text.

### Catalog Topics and Difficulty

Catalog metadata is defined in [`packages/shared/src/config/catalog.ts`](https://github.com/freeCodeCamp/freeCodeCamp/blob/main/packages/shared/src/config/catalog.ts). The `Topic` enum defines the available topics, and the `Levels` enum defines the difficulty levels: `Beginner`, `Intermediate`, and `Advanced`.

The `catalog` array assigns each listed superblock a `topic`, a difficulty `level`, and a duration in `hours`. To find a course's metadata, look for its `SuperBlocks` enum member in an entry's `superBlock` field. For example, the entry for `SuperBlocks.BasicHtml` has `topic: Topic.Html` and `level: Levels.Beginner`.

## The Certifications Directory

The `challenges/english/certifications/` directory contains YAML files that define the certification requirements and project information for each certification.

Each certification YAML file includes the following key properties:

- **`id`**: Unique identifier for the certification
- **`title`**: Display name of the certification
- **`certification`**: Internal name used to reference the certification
- **`tests`**: Array of required projects with their IDs and titles

## The `intro.json` File

The file `client/i18n/locales/english/intro.json` contains the display titles and introductory text shown to campers for each superblock and block. It is organized by superblock, then by block:

```json
{
  "javascript-v9": {
    "title": "JavaScript Certification",
    "intro": ["..."],
    "chapters": {
      "javascript": "JavaScript",
      "javascript-certification-exam": "JavaScript Certification Exam"
    },
    "modules": {
      "javascript-variables-and-strings": "Variables and Strings"
    },
    "module-intros": {
      "data-structures": {
        "note": "Coming Spring 2026",
        "intro": ["..."]
      }
    },
    "blocks": {
      "workshop-greeting-bot": {
        "title": "Build a Greeting Bot",
        "intro": ["..."]
      }
    }
  }
}
```

At the superblock level, `title` is the display name of the superblock, and `intro` is the introductory text shown on the superblock page.

`chapters` and `modules` are only present in new-style superblocks. `module-intros` contains introductory text for modules marked as `comingSoon` in the structure file. Legacy superblocks only have `title`, `intro`, and `blocks`.

## Internationalization Structure

The curriculum content is internationalized using a git submodule located at `curriculum/i18n-curriculum/`. This submodule contains translated versions of curriculum content:

- **English content**: Located directly in `curriculum/challenges/english/`
- **Translated content**: Located in the submodule at `curriculum/i18n-curriculum/curriculum/challenges/<language>/`

The structure within each language directory mirrors the English structure exactly, with the same block folders and challenge files. However, only the Markdown challenge files (`.md`) are translated and stored in the i18n-curriculum submodule. Configuration files such as YAML certification files and JSON structure files remain in English only.

:::caution
The i18n-curriculum submodule is updated automatically. Manual changes to translated content should not be made directly in the submodule.
:::

## Renaming Files

There may be times when you need to rename a certificate, superblock, block, or challenge. This section will outline the steps needed to avoid build errors when doing so.

:::danger
Renaming files within the curriculum structure will often change the path (or URL) of the content on the main webpage. Doing so should be done with care, as redirects have to be set up for each change that is made.
:::

### Setting Up Redirects

When renaming curriculum items that change URLs, you **must** set up redirects to ensure existing links continue to work. This requires updating the file `serve.json` in the [client-config](https://github.com/freeCodeCamp/client-config) repo.

The file contains a `"redirects"` array where you need to add redirect objects. The redirect format follows this pattern:

```json
{
  "source": "/learn/old-name/:param?",
  "destination": "/learn/new-name/:param?"
}
```

**URL Parameters:**

- `:superblock?` - Captures superblock name (optional)
- `:block?` - Captures block name (optional)
- `:challenge?` - Captures challenge name (optional)

**Examples:**

For superblock renaming (e.g., `apis-and-microservices` → `back-end-development-and-apis`):

```json
{
  "source": "/learn/apis-and-microservices/:block?/:challenge?",
  "destination": "/learn/back-end-development-and-apis/:block?/:challenge?"
}
```

For block renaming within a superblock:

```json
{
  "source": "/learn/responsive-web-design/old-block-name/:challenge?",
  "destination": "/learn/responsive-web-design/new-block-name/:challenge?"
}
```

For individual challenge renaming:

```json
{
  "source": "/learn/superblock/block/old-challenge-name",
  "destination": "/learn/superblock/block/new-challenge-name"
}
```

:::caution
**The redirect setup must be done in a PR that gets merged AT THE SAME TIME as the PR that actually renames the curriculum items.** This ensures the redirects go live simultaneously with the URL changes, preventing any broken links.
:::

### Renaming a Certification

When renaming a certification, you will likely want to rename the associated superblock along with it. Do the following to rename only the certificate:

1. Rename the `curriculum/challenges/english/certifications/<certification>.yml` file to the new name.
2. In the YAML file, change the `title` to the new name.
3. Update the `certifications` array in `curriculum/structure/curriculum.json` to use the new certification name.
4. Update the relevant `Certification` enum member and certification arrays in `packages/shared/src/config/certification-settings.ts` when the certification slug changes.
5. Update the matching certification entry in `client/config/cert-and-project-map.ts`, including its `title`, `certSlug`, and project `certSlug` values when applicable.
6. Update any matching certification names and slugs in `client/i18n/locales/<language>/`, `curriculum/src/build-curriculum.ts`, and other references found by searching for the old value.
7. **If you renamed the certification slug**, [add redirects to the `serve.json` file](#setting-up-redirects) to redirect from old certification URLs to new ones:
   ```json
   {
     "source": "/certification/:username/old-cert-slug",
     "destination": "/certification/:username/new-cert-slug"
   }
   ```
8. Update the main `README.md` file to the new name.

:::note
Translated content in the i18n-curriculum submodule will be updated automatically and does not require manual intervention.
:::

### Renaming a Superblock

:::note
When you rename a superBlock, the new folder name is used as the path and should be considered the "correct" name. All other values should be updated to reflect that change.
:::

Also, you will likely want to rename the certificate and the `<superBlock>-projects` block when you rename a superBlock since they all share a name. To rename only a superBlock you need to:

1. Rename the superblock file in `curriculum/structure/superblocks/` from `<old-name>.json` to `<new-name>.json`.
2. Update the `superblocks` array in `curriculum/structure/curriculum.json` to use the new superblock name.
3. Update the corresponding `SuperBlocks` enum member in `packages/shared/src/config/curriculum.ts` and the key in `superBlockNames` in `curriculum/src/build-curriculum.ts`.
4. Update the superblock key in every `client/i18n/locales/<language>/intro.json` file. In English, update the `title` when the display name changes.
5. Update references to the old superblock slug, including certification paths in `client/config/cert-and-project-map.ts`, by searching the repository for the old value.
6. [**Add redirects** to the `serve.json` file](#setting-up-redirects) to redirect from old superblock URLs to new ones:
   ```json
   {
     "source": "/learn/old-superblock-name/:block?/:challenge?",
     "destination": "/learn/new-superblock-name/:block?/:challenge?"
   }
   ```
7. Update the main `README.md` file to the new name.

### Renaming a Block

When renaming a curriculum block, you need to:

1. Change the name of the block folder in the `curriculum/challenges/english/blocks/<block>` directory.
2. Rename the block's JSON file in `curriculum/structure/blocks/` from `<old-name>.json` to `<new-name>.json`.
3. Update the `dashedName` property in the renamed block JSON file.
4. Update the superblock's JSON file in `curriculum/structure/superblocks/` to reference the new block name in its `blocks` array.
5. [**Add redirects** to the `serve.json` file](#setting-up-redirects) to redirect from old block URLs to new ones:
   ```json
   {
     "source": "/learn/superblock-name/old-block-name/:challenge?",
     "destination": "/learn/superblock-name/new-block-name/:challenge?"
   }
   ```
6. In the `client/i18n/locales/<language>/intro.json` files, update the block name to the new name for all the languages. In the English `intro.json` file, update the `title` as well.
7. Update the main `README.md` file to the new name.

:::note
Translated content in the i18n-curriculum submodule will be updated automatically and does not require manual intervention.
:::

### Renaming a Challenge

When renaming a single challenge file, you need to:

1. Change the challenge's `title` and `dashedName` in its frontmatter.
2. Update the challenge title in the relevant block JSON file in `curriculum/structure/blocks/<block>.json`.
3. [**Add redirects** to the `serve.json` file](#setting-up-redirects) to redirect from old challenge URLs to new ones:
   ```json
   {
     "source": "/learn/superblock-name/block-name/old-challenge-name",
     "destination": "/learn/superblock-name/block-name/new-challenge-name"
   }
   ```
4. If the challenge is a certificate project, update the YAML file in `curriculum/challenges/english/certifications/<certification>.yml` to the new name.
5. If the challenge is a certificate project, update the `title` and `link` in `client/config/cert-and-project-map.ts`
6. If the challenge is a certificate project, update the main `README.md` file to the new name.

:::note
Translated content in the i18n-curriculum submodule will be updated automatically and does not require manual intervention.
:::

## The `dashedName` Property

The `dashedName` property is used to generate the URL path for a superblock, block, or challenge. It must contain only lowercase letters, numbers, and hyphens. Choose a descriptive, stable slug and update every reference when it changes.

Source: https://contribute.freecodecamp.org/curriculum-file-structure/index.mdx
