How to work on coding challenges
Our goal is to develop a fun and clear interactive learning experience.
Designing interactive coding challenges is difficult. It would be much easier to write a lengthy explanation or to create a video tutorial. But for our core curriculum, we’re sticking with what works best for most people - a fully interactive, video game-like experience.
We want campers to achieve a flow state. We want them to build momentum and blast through our curriculum with as few snags as possible. We want them to go into the projects with confidence and gain wide exposure to programming concepts.
We are currently in version 9 of the curriculum, which includes theory lessons, workshops, labs, review pages and quizzes.
The content for each challenge is stored in its markdown file. This markdown file is later converted to HTML using our tools to create interactive web pages.
You can find all of freeCodeCamp.org’s curricular content in the /curriculum/challenges directory.
Breakdown of the Core Curriculum
Section titled “Breakdown of the Core Curriculum”The core curriculum teaches full stack development and is broken down into the following certifications:
- Responsive Web Design Certification
- JavaScript Certification
- Front-End Development Libraries Certification
- Python Certification
- Relational Databases Certification
- Back-End Development and APIs Certification
- Certified Full-Stack Developer
Version 9 certifications are organized into chapters, modules, blocks and challenges. Chapters contain modules, modules contain blocks, and blocks contain individual challenge files. See the curriculum file structure for details.
Each module contains blocks. A block contains one or more challenge files and is labeled according to its content, such as lecture, workshop, lab, review or quiz.
Theory lessons are short text based lectures with interactive examples that teach the theory behind concepts including common data structures, CSS Grid and SQL.
Workshops are guided, step-based projects that introduce or reinforce concepts.
Labs are campers’ opportunity to test their problem-solving skills and build out projects reviewing the concepts learned in the theory lessons and workshops.
Review pages summarize concepts covered in the module.
Quizzes test campers’ knowledge of the module material.
Each core curriculum component has its own tooling and style guide. Refer to the guide for the content you are working on:
- How to Work on Theory Lessons
- How to Work on Workshops
- How to Work on Labs
- How to Work on Review Pages
- How to Work on Quizzes
Language Curricula
Section titled “Language Curricula”Language curricula are separate from the core curriculum and have their own content structure and challenge formats. Refer to How to Work on Language Curricula for specific guidance.
Set up the tooling for the Curriculum
Section titled “Set up the tooling for the Curriculum”Before you work on the curriculum, you would need to set up some tooling to help you test your changes. You can use any option from the below:
-
You can set up freeCodeCamp locally. This is highly recommended for regular/repeat contributions. This setup allows you to work and test your changes.
-
Use GitHub Codespaces, a free online dev environment. Clicking the button below will start a ready-to-code dev environment for freeCodeCamp in your browser. It only takes a few minutes.
Challenge descriptions/instructions
Section titled “Challenge descriptions/instructions”Sentences should be clear and concise with minimal jargon. If used, jargon should be immediately defined in plain English.
Keep paragraphs short (around 1-4 sentences). People are more likely to read several short paragraphs than a wall of text.
Use American English, e.g., use labeled instead of labelled.
Challenge text should use the second person (“you”) to help to give it a conversational tone. This way the text and instructions seem to speak directly to the camper working through the challenge. Try to avoid using the first person (“I”, “we”, “let’s”, and “us”).
Don’t use outbound links in challenge instructions. Include the information campers need in the challenge text or teach it in a preceding lesson.
You can add diagrams if necessary.
Don’t use emojis or emoticons in challenges. freeCodeCamp has a global community, and the cultural meaning of an emoji or emoticon may be different around the world. Also, emojis can render differently on different systems.
Proper nouns should use correct capitalization when possible. Below is a list of words as they should appear in the challenges.
- JavaScript (capital letters in “J” and “S” and no abbreviations)
- Node.js
- When referring to front-end, back-end, or full-stack, use the hyphenated form.
The 2-minute rule for short challenges
Section titled “The 2-minute rule for short challenges”Each workshop step or other short coding exercise should be solvable within 120 seconds by a native English speaker who has completed the preceding challenges. This includes the time needed to read the instructions, understand the seed code, write the solution and pass the tests. This rule does not apply to an entire lab or certification project.
If it takes longer than two minutes to complete the challenge, you have two options:
- Simplify the challenge, or
- Split the challenge into two challenges.
The 2-minute rule keeps instructions concise, seed code clear and tests straightforward.
We track how long it takes for campers to solve short challenges and use this information to identify challenges that need to be simplified or split.
Modularity
Section titled “Modularity”Each short instructional challenge or workshop step should teach one concept. For challenges with descriptive titles, the concept should be apparent from the title.
We can reinforce previously covered concepts through repetition and variations, for example, introducing <h1> elements in one challenge, then <h3> elements a few challenges later.
Short challenges can flow together and reinforce previously covered concepts.
Formatting challenge text
Section titled “Formatting challenge text”In addition to the rules contained in the Writing Style Guide, here are specific formatting guidelines for challenge text and examples:
- Language keywords go in ``` backticks. For example, HTML tag names or CSS property names.
- References to code parts (i.e. function, method, or variable names) should be wrapped in ``` backticks. See example below:
Use `parseInt` to convert the variable `realNumber` into an integer.- References to file names and path directories (e.g.
package.json,src/components) should be wrapped in ``` backticks. - Multi-line code blocks must be preceded by an empty line. The next line must start with three backticks followed immediately by one of the supported languages. To complete the code block, you must start a new line that only has three backticks and another empty line. See example below:
- Whitespace matters in Markdown, so we recommend that you make it visible in your editor.
The following is an example of code:
```{language}[YOUR CODE HERE]```- Additional information in the form of a note should be surrounded by blank lines, and formatted:
**Note:** Rest of note text... - If multiple notes are needed, then list all of the notes in separate sentences using the format:
**Notes:** First note text. Second note text. - Use Markdown instead of HTML tags when Markdown provides equivalent formatting.
Writing tests
Section titled “Writing tests”Tests should cover the stated requirements without enforcing unrelated implementation details. Use the minimum number needed to verify those requirements.
Challenge tests can use the Node.js assert API and the Chai assert API. If needed, user-generated code can be accessed through the code variable. The __helpers object also exposes functions for inspecting code. These functions are defined in the curriculum-helpers repository.
Guidelines for assertions
Section titled “Guidelines for assertions”If a method exists in Chai.js that expresses what is being tested for, its use is preferred.
Example one
assert(Array.isArray([]), 'empty arrays are arrays');Example two
assert.isArray([]);In the first example, what the test means isn’t immediately clear. The main thing that explains the test is the assertion message.
Meanwhile in example two, the test spells out its purpose; to determine if something is an array.
Prefer the specific assertion method.
Formatting Seed Code
Section titled “Formatting Seed Code”Here are specific formatting guidelines for the challenge seed code:
- Use two spaces to indent for HTML, CSS, and JavaScript
- Use four spaces to indent for Python
- JavaScript statements end with a semicolon
- Use double quotes where applicable for HTML, CSS, and JavaScript
- Use single quotes where applicable for Python
Seed Code Comments
Section titled “Seed Code Comments”The curriculum has two English dictionaries for seed-code comments. The comments.json file contains comments that are translated for localized curricula. The comments-to-not-translate.json file is used for seed-code comments that must remain unchanged in every language.
Every comment in curriculum seed code must match an entry in one of these files, including its case and spacing. Do not add entries without prior discussion with the development team.
Comments should have a space between the comment marker and the comment text. In general, comments should be used sparingly. Always consider rewriting a challenge’s description or instructions if it could avoid using a seed code comment.
Workshop steps use --fcc-editable-region-- markers to show campers where to change code. Do not use seed comments as a substitute for those markers.
Example of a valid single-line JavaScript comment:
// Only change code below this lineExample of a valid CSS comment:
/* Only change code above this line */A dictionary comment can also be part of the seed code that a camper needs to change:
// TODO: use a different type of loopfor (let i = 1; i <= count; i++) { rows.push(padRow(i, count));}Translation of Seed Code Comments
Section titled “Translation of Seed Code Comments”There are separate translated comment dictionaries for each language. The English comments.json file is their source. The translated dictionaries are located in the i18n-curriculum submodule at curriculum/dictionaries/{language}/comments.json (for example, curriculum/dictionaries/chinese/comments.json). Each dictionary is a JSON object whose keys are comment IDs and whose values are the comment text.
Some comments may contain a word/phrase that should not be translated. For example, variable names or proper library names like “React” should not be translated. See the comment below as an example. The word myGlobal should not be translated.
Declare the myGlobal variable below this lineThe i18n-curriculum submodule is synchronized through the translation workflow. Do not edit its files directly.
Testing Challenges
Section titled “Testing Challenges”Before you create a pull request for your changes, you need to validate that the changes you have made do not inadvertently cause problems with the challenge.
Run the following commands from the root of the freeCodeCamp repository.
-
Install the browser that the tests drive. Do this once:
Terminal window pnpm -F=@freecodecamp/curriculum install-puppeteer -
To test a single challenge, use its challenge id:
Terminal window FCC_CHALLENGE_ID=6823ac607bfdbc46331b2559 pnpm run test-curriculum-content -
You can also test a block or a superblock of challenges with these commands:
Terminal window FCC_BLOCK='workshop-curriculum-outline' pnpm run test-curriculum-contentUse the block’s
dashedName(the folder’s name) for theFCC_BLOCKvalue.Terminal window FCC_SUPERBLOCK='responsive-web-design-v9' pnpm run test-curriculum-content
Proposing a Pull Request (PR)
Section titled “Proposing a Pull Request (PR)”After you’ve committed your changes, check here for how to open a Pull Request.
Useful Links
Section titled “Useful Links”- Challenge types - what the numeric challenge type values mean.
Helper Scripts
Section titled “Helper Scripts”Creating a New Project
Section titled “Creating a New Project”To create a new lecture block, workshop, lab, review page or quiz, you can run pnpm run create-new-project in the root directory. This opens up a command line UI that guides you through the process.
The script creates the block directory and its initial challenge file. For example, a block named test-project in the Responsive Web Design certification would be created at curriculum/challenges/english/blocks/test-project.
There are a few other helper scripts that can be used to manage the challenges in a block. Note that these commands should all be run in the block directory. For example:
cd curriculum/challenges/english/blocks/lecture-understanding-html-attributesAdd New Challenge
Section titled “Add New Challenge”To add a new challenge at the end of a block, call the script:
pnpm run create-next-challengeThis will prompt you for the challenge information and create the challenge file, updating the block’s JSON structure file with the new challenge information.
Delete a Challenge
Section titled “Delete a Challenge”To delete a challenge, call the script:
pnpm run delete-challengeThis will prompt you to select which challenge should be deleted, then delete the file and update the block’s JSON structure file to remove the challenge from the order.
Insert a Challenge
Section titled “Insert a Challenge”To insert a challenge before an existing challenge, call the script:
pnpm run insert-challengeThis will prompt you for the challenge information, then for the challenge to insert before. For example, if your choices are:
abcIf you choose b, your new order will be:
anew challengebcUpdate Challenge Order
Section titled “Update Challenge Order”If you need to manually re-order the challenges, call the script:
pnpm run update-challenge-orderThis will take you through an interactive process to select the order of the challenges.
Troubleshooting
Section titled “Troubleshooting”Infinite Loop Detected
Section titled “Infinite Loop Detected”If you see the following error in the console while previewing a challenge:
Potential infinite loop detected on line <number>...This means that the loop-protect plugin has found a long-running loop or recursive function. If your challenge needs to do that (e.g. it contains an event loop that is supposed to run indefinitely), then you can prevent the plugin from being used in the preview. To do so, add disableLoopProtectPreview: true to the block’s JSON structure file in curriculum/structure/blocks/.
If your tests are computationally intensive, then you may see this error when they run. If this happens then you can add disableLoopProtectTests: true to the block’s JSON structure file.
It’s not typically necessary to have both set to true, so only set them as needed.