Blog/Why Checkpoints Belong Between Lessons and Projects

Why Checkpoints Belong Between Lessons and Projects

JavaScript checkpoints belong between lessons and projects because they answer a question lessons cannot fully answer: can the learner combine the parts before the project adds too much surface area?

A lesson can teach querySelector(). Another can teach arrays. Another can teach click events. A project asks all three to show up at the same time, along with naming, layout, validation, state, rendering, and the strange little pressure of a blank editor.

That jump is where many learners lose signal. They do not only need more explanation. They need a bridge.

Lessons Teach Parts. Projects Test Systems.

Guided lessons are good at isolating one idea. That is the point. If a learner is meeting functions for the first time, the lesson should not also ask them to design a form, choose data attributes, and debug event bubbling. One clean target is enough.

Projects are different. A project is not a row of separate skills. It is a small system:

  1. Store data somewhere predictable.
  2. Render the interface from that data.
  3. Listen for user actions.
  4. Update the data.
  5. Render again.
  6. Handle the annoying path where the user types nothing, clicks twice, or changes their mind.

That is real JavaScript work. It is also noisy.

This is why the advice to build projects is only useful when the learner has enough preparation to read the project when it breaks. A checkpoint gives them that preparation without pretending they are already ready for the whole app.

A Checkpoint Is Integration Practice

A checkpoint is not a quiz with nicer branding. It is not a tiny capstone pretending to be a project. It is integration practice with the walls still close enough to touch.

The task should combine two or three known ideas and make the learner decide how they connect:

Lesson piecesCheckpoint pressureProject pressure
Arrays and objectsCreate, update, and read recordsModel habit data or a game board
DOM selection and renderingPut data on the page intentionallyRender cards, cells, totals, and messages
Events and stateConnect a click to the right data objectToggle habits, drop discs, apply tip presets
Forms and validationReject empty input without losing stateAdd records, recover from errors, keep UI current
Derived dataCount, total, or summarize from source dataShow progress, split totals, detect game outcomes

The important word is "combine." Not memorize. Not repeat. Combine.

In Foundations Exercises, that means moving from separate lessons on loops, functions, arrays, and objects into tasks that require more than one of them at once. In DOM Exercises, it means selecting elements, responding to events, building lists, handling forms, using localStorage, and reading event targets without a new concept arriving every stage.

The learner is still in a structured environment, but the training wheels are not doing quite as much work.

The Bug A Project Hides

Here is the kind of mistake a project can hide for too long:

const habits = [
  { id: "water", name: "Drink water", completedToday: false },
  { id: "read", name: "Read one page", completedToday: false },
];

function markDone(id) {
  const item = document.querySelector(`[data-id="${id}"]`);
  item.classList.add("is-done");
}

function countCompleted(items) {
  return items.filter((habit) => habit.completedToday).length;
}

markDone("water");

console.log(countCompleted(habits)); // 0

The page changed, so the learner may think the feature worked. But the data did not change. The next feature that depends on the data, maybe a progress summary, a save step, or a filter, will disagree with the DOM.

That is not a CSS problem. It is not a selector problem. It is a source-of-truth problem:

function markDone(id) {
  const habit = habits.find((item) => item.id === id);
  if (!habit) return;

  habit.completedToday = true;
  renderHabits(habits);
}

This is exactly the kind of gap a checkpoint should reveal before a larger project buries it under markup, styling, edge cases, and a dozen buttons.

The learner does not merely need to know that objects have properties. They need to know that the object is the state, the DOM is the display, and the event handler is the bridge between them.

This Is Different From A Boring First Project

A boring first project controls the domain. It keeps the app familiar enough that the learner can focus on the code.

A checkpoint controls the handoff.

Those are related, but not the same. A habit tracker can be a good beginner project because the rules are understandable. But if the learner has never practiced the pattern "click a button, find the matching object, update state, render from state," the project still becomes a fog machine with nicer labels.

The checkpoint asks for that pattern directly.

Not the whole habit tracker. Just enough to prove the learner can make the connection:

When this button is clicked:
1. Read the id from the DOM.
2. Find the matching object in the array.
3. Change the object.
4. Render the list from the array.

That is project prep. It is smaller than the project, but it is not less serious.

What The Bridge Looks Like In Practice

The projects on JS Exercises are staged because project work has layers. A learner might start a tip splitter by formatting money, then calculate totals from state, then render results, then read form inputs, then wire live updates and validation. That order matters.

The same pattern shows up in a habit tracker:

  1. Model habit records.
  2. Render the records.
  3. Store ids on DOM elements.
  4. Connect click events back to records.
  5. Validate form input.
  6. Add new records to the array.
  7. Derive progress from the array.

And in a board game:

  1. Model the board as data.
  2. Render cells from the board.
  3. Store row and column information on each cell.
  4. Turn a click into a move.
  5. Update the board.
  6. Render again.
  7. Check rules that depend on the new state.

Those are not random stages. They are the same project prep pattern wearing different clothes: data, DOM, events, state, derived output.

Checkpoints belong before projects because they let the learner practice that pattern in a smaller frame. By the time they reach the project, the project is still challenging, but it is challenging for the right reason. They are combining familiar moves, not discovering every move at once.

A Good Checkpoint Has Sharp Edges

Weak checkpoints are just review sheets. Strong checkpoints make assumptions visible.

They should ask for behavior, not trivia:

Bad: What does addEventListener do?
Good: Add one listener to the list so existing and newly added items both respond to clicks.

They should include at least one common failure:

Bad: Render these three items.
Good: Render these three items, then re-render after the array changes without duplicating old items.

They should make feedback concrete:

Bad: Build a form.
Good: Submitting an empty value shows an error, does not add an item, and does not reload the page.

That last phrase matters. "Does not reload the page" catches missing event.preventDefault(). "Does not add an item" catches sloppy validation. "Shows an error" catches whether the learner can turn state into visible feedback.

One checkpoint can teach more than five vocabulary questions because it tests the relationship between ideas.

When A Learner Is Ready For The Project

The checkpoint is doing its job when it can answer a few practical questions:

  1. Can the learner explain where the source of truth lives?
  2. Can they predict which value changes after an event?
  3. Can they repair one broken path without rewriting everything?
  4. Can they name which lesson concept they are using?
  5. Can they carry the pattern into a slightly larger feature?

That does not mean the project will be easy. It should not be. Projects are supposed to create productive friction.

But the friction should come from integration, not from mystery. If the learner can already handle a small DOM event, update state, and render the result, then the project can ask a better question: can you keep doing that as the app grows?

That is the bridge checkpoints provide.

Key Takeaways

  • Checkpoints test whether learners can combine ideas before a project adds too much surface area.
  • Good checkpoints are integration practice, not trivia and not miniature projects with vague requirements.
  • DOM, state, events, and data should meet in checkpoints before they collide in project work.
  • A checkpoint reveals source-of-truth bugs while the code is still small enough to inspect.
  • Projects teach more when learners arrive with a few reusable patterns already in their hands.
Share this post: