A curriculum is only useful if you can find your way around it. 33 JS Concepts is exactly that — a curated, opinionated list of the 33 ideas every working JavaScript developer is expected to understand, from the call stack at the bottom to web workers at the top. The repository pairs each concept with a written explainer (docs/concepts/<concept>.mdx), an executable test suite (tests/...), and a growing set of "Beyond" topics (docs/beyond/concepts/) for readers who want to go deeper than the original 33.
This guide explains how to use the curriculum: how to start reading today, how to run the test suites locally if you want to learn by failing tests, how to navigate the concept index, how to study for an interview with it, and how to contribute back to it. There is nothing to install in the conventional sense — the project's primary deliverable is reading material — but the test suites and the local Mintlify documentation site are also yours to run if you want to.
1. Quick Start
The lowest-friction way to use this project is to read it on GitHub or on the project's documentation site. Clone is optional. There is no binary to download, no service to register for, no API key to obtain.
1. Open https://github.com/leonardomso/33-js-concepts in a browser.
2. Scroll to the table of 33 concepts in the README.
3. Click any concept link — that opens the concept's `docs/concepts/<concept>.mdx` page.
4. Read the explanation, work through any code examples, then move to the next concept.
If you prefer browsing rendered documentation rather than raw .mdx files, the repository ships a Mintlify documentation site under docs/ that is published as a public website. The docs/index.mdx file is the home page and docs/concepts/<concept>.mdx is each concept's dedicated page.
Tip
You do not have to read all 33 in order. Each concept page is self-contained. If you only need one topic — say you have a closures interview tomorrow — open
docs/concepts/scope-and-closures.mdxand ignore the rest.
What you get
- 33 core concept explainers in
docs/concepts/— the canonical list every developer is expected to know. - 29 "Beyond" topics in
docs/beyond/concepts/— advanced material (Proxy/Reflect, Observer APIs, browser storage, memory and performance) for readers who want to go past the original 33. - A complete Vitest test suite under
tests/— over 60 spec files exercising the same concepts in runnable code. - A getting-started track in
docs/getting-started/covering prerequisites, learning paths, and how to learn JavaScript effectively. - A
package.jsonwithtest,test:watch,test:coverage,docs, anddocs:buildscripts if you want to run anything locally. - An MIT licence — fork it, translate it, embed it in your own learning materials.
Prerequisites for reading
A web browser. That is the entire prerequisite for the primary mode of use.
Note
The repository's
package.jsondeclaresname: "33-js-concepts",version: "1.0.0",license: "MIT", with Leonardo Maldonado as the named author. OnlydevDependenciesexist —vitest,@vitest/coverage-v8, andjsdom. There are no production dependencies because the repository ships no runtime code.
A 60-second example
A typical concept page in docs/concepts/ is structured as a short prose explainer followed by curated outbound links to articles and videos by other authors. The accompanying test file in tests/.../<concept>.test.js exercises the same ideas in runnable code. For example, the closures concept lives at docs/concepts/scope-and-closures.mdx and is matched by tests/fundamentals/scope-and-closures/scope-and-closures.test.js.
# Optional — only if you want to run the tests yourself.
git clone https://github.com/leonardomso/33-js-concepts.git
cd 33-js-concepts
npm install
npm test
> 33-js-concepts@1.0.0 test
> vitest run
RUN v4.x.x
Test Files XX passed (XX)
Tests XXX passed (XXX)
Tip
If you want to read first and run later, skip the clone entirely. Reading the
.mdxfiles on GitHub or on the project website is the intended primary path.
What to try next
- Jump to Section 4. Core Usage for the full table of all 33 concepts and direct links to each.
- Jump to Section 5. Common Tasks for end-to-end recipes — finishing the curriculum, prepping for an interview, contributing a translation.
- If you specifically want the test suites running locally, jump to Section 2. Installation.
2. Installation
There is nothing to install for the primary use case (reading the curriculum). This section covers the optional secondary paths: running the Vitest test suites locally, or running the Mintlify documentation site locally.
Path A — Read it (no install)
| Method | Steps |
|---|---|
| Read on GitHub | Open https://github.com/leonardomso/33-js-concepts and click the concept links in the table of contents. |
| Read on the docs site | Visit the project's published Mintlify site. Each concept lives at /concepts/<concept> and each Beyond topic at /beyond/concepts/<concept>. |
| Read locally (rendered) | git clone then npm install then npm run docs to start a local Mintlify dev server (see Path C). |
| Read locally (raw) | git clone and open the .mdx files in any editor or markdown viewer. |
Important
The project is licensed MIT. You are free to clone, fork, mirror, translate, or embed the content in your own learning material — see Common Tasks for translation and contribution recipes.
Path B — Run the tests locally
If you want to learn by reading green-and-red specs, run the Vitest suite. The repository ships a fully wired vitest.config.js:
// vitest.config.js
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
include: ['tests/**/*.test.js'],
globals: false,
environment: 'node'
}
})
Requirements
- Node.js — the dev dependencies (
vitest@^4.0.16,@vitest/coverage-v8@^4.0.16,jsdom@^27.4.0) target Node 18+. Use the latest LTS release if you can. - npm (or any other Node package manager —
pnpm,yarn, andbunwill all work for installing the dev deps). - A working terminal. No native toolchain is required.
Steps
git clone https://github.com/leonardomso/33-js-concepts.git
cd 33-js-concepts
npm install
npm test
> 33-js-concepts@1.0.0 test
> vitest run
The default test script runs all suites in one pass. To run a single concept:
npx vitest run tests/fundamentals/scope-and-closures/scope-and-closures.test.js
To run in watch mode (Vitest re-runs when you save):
npm run test:watch
To produce a coverage report (uses @vitest/coverage-v8):
npm run test:coverage
Note
Tests whose filename ends in
.dom.test.jsrely on a DOM. Vitest is configured withenvironment: 'node'by default, so DOM-flavoured tests use thejsdomdev dependency — Vitest auto-detects per-file environment via the file naming convention. If you fork the project and rename a DOM-using file without the.dom.test.jssuffix, those tests will fail withdocument is not defined.
Path C — Run the docs site locally
The repository ships a Mintlify documentation site under docs/. The package.json exposes two scripts:
| Script | Command | Purpose |
|---|---|---|
npm run docs |
cd docs && npx mintlify dev |
Start a local hot-reloading docs server. |
npm run docs:build |
cd docs && npx mintlify build |
Produce a production build of the docs site. |
npm run docs
[mintlify] Starting development server...
[mintlify] Local: http://localhost:3000
Warning
npx mintlify devwill download the Mintlify CLI on first run. If you are on a corporate network that blocksnpmregistry access, the docs site will not start. Runnpm install -g mintlifyfrom a network that allows registry access, then re-try.
Verifying the install
After npm install, run a quick health check:
node --version
npm --version
npx vitest --version
A successful install will print three version numbers without errors. If any of them errors, see Section 6. Troubleshooting.
3. Configuration
This is a documentation and curriculum repository, not an application. There is no config.yaml, no .env, no command-line flags to learn, no environment variables to set. The only configuration files in the repo are:
| File | Purpose |
|---|---|
package.json |
npm scripts (test, test:watch, test:coverage, docs, docs:build) and dev dependencies. |
package-lock.json |
Locked dependency tree for reproducible installs. |
vitest.config.js |
Tells Vitest to find tests under tests/**/*.test.js, run in Node, with no global APIs. |
opencode.jsonc |
Project-level opencode tooling configuration (editor/agent integration). |
.gitignore |
Standard Node ignore list. |
docs/docs.json |
Mintlify documentation site configuration (navigation, theming). |
docs/robots.txt |
Search engine crawl directives for the published docs site. |
Note
If you fork the project and want to change Vitest behaviour — for example to enable globals so you do not have to import
describe/it/expectin every file — editvitest.config.jsand setglobals: true. The current config opts out of globals deliberately so the test files clearly show what they import.
Configuration in scope for end users: nothing
You do not configure the curriculum. You read it. The "configuration" knobs above are only relevant if you are running the tests or the docs site locally; for the primary read-the-content use case they have no effect.
If you want to change the published docs site for your own fork, edit docs/docs.json (Mintlify navigation, theme, logo, social links) and docs/schema-inject.js (the JSON-LD structured-data injector that emits Schema.org WebSite, TechArticle, BreadcrumbList, FAQPage, and ItemList payloads to the rendered pages).
4. Core Usage
The 33 concepts are the spine of the project. Each row in the table below points to its concept page (docs/concepts/<slug>.mdx) and, where applicable, to the matching test directory (tests/.../<slug>/).
The 33 concepts
| # | Concept | Concept page |
|---|---|---|
| 1 | call-stack |
docs/concepts/call-stack.mdx |
| 2 | primitive-types |
docs/concepts/primitive-types.mdx |
| 3 | primitives-objects (Value Types vs Reference Types) |
docs/concepts/primitives-objects.mdx |
| 4 | type-coercion (Implicit, Explicit, Nominal, Structural, Duck Typing) |
docs/concepts/type-coercion.mdx |
| 5 | equality-operators (== vs === vs typeof) |
docs/concepts/equality-operators.mdx |
| 6 | scope-and-closures (Function/Block/Lexical scope, closures) |
docs/concepts/scope-and-closures.mdx |
| 7 | javascript-engines (How JS works under the hood) |
docs/concepts/javascript-engines.mdx |
| 8 | event-loop (Plus setTimeout, setInterval, requestAnimationFrame) |
docs/concepts/event-loop.mdx |
| 9 | factories-classes (Expressions vs Statements, factories) |
docs/concepts/factories-classes.mdx |
| 10 | this-call-apply-bind |
docs/concepts/this-call-apply-bind.mdx |
| 11 | object-creation-prototypes (new, Constructor, instanceof) |
docs/concepts/object-creation-prototypes.mdx |
| 12 | inheritance-polymorphism (Prototype inheritance and prototype chain) |
docs/concepts/inheritance-polymorphism.mdx |
| 13 | iife-modules (IIFEs, Modules, Namespaces) |
docs/concepts/iife-modules.mdx |
| 14 | es-modules (CommonJS vs ESM) |
docs/concepts/es-modules.mdx |
| 15 | http-fetch (XHR, Fetch, AJAX) |
docs/concepts/http-fetch.mdx |
| 16 | callbacks |
docs/concepts/callbacks.mdx |
| 17 | promises |
docs/concepts/promises.mdx |
| 18 | async-await |
docs/concepts/async-await.mdx |
| 19 | higher-order-functions |
docs/concepts/higher-order-functions.mdx |
| 20 | map-reduce-filter |
docs/concepts/map-reduce-filter.mdx |
| 21 | pure-functions (Side effects, state mutation) |
docs/concepts/pure-functions.mdx |
| 22 | currying-composition (Partial application, currying, compose, pipe) |
docs/concepts/currying-composition.mdx |
| 23 | recursion |
docs/concepts/recursion.mdx |
| 24 | data-structures (Collections, generators) |
docs/concepts/data-structures.mdx |
| 25 | algorithms-big-o (Expensive operation and Big-O notation) |
docs/concepts/algorithms-big-o.mdx |
| 26 | dom (DOM and layout trees) |
docs/concepts/dom.mdx |
| 27 | design-patterns (Factory, Singleton, Observer, Strategy…) |
docs/concepts/design-patterns.mdx |
| 28 | modern-js-syntax (let/const/template literals/destructuring/spread) |
docs/concepts/modern-js-syntax.mdx |
| 29 | error-handling |
docs/concepts/error-handling.mdx |
| 30 | regular-expressions |
docs/concepts/regular-expressions.mdx |
| 31 | clean-code |
docs/concepts/clean-code.mdx |
| 32 | generators-iterators |
docs/concepts/generators-iterators.mdx |
| 33 | web-workers |
docs/concepts/web-workers.mdx |
Note
The concept slugs above are taken verbatim from the directory
docs/concepts/. If you have read older versions of this curriculum elsewhere on the web, the topic groupings will look familiar but the exact names may differ —docs/concepts/is the canonical naming.
Reading a concept page
Each concept page is a short, focused explainer in MDX (Markdown plus inline JSX). The structure is consistent across all 33 pages:
- A title and a one-paragraph definition.
- A "What it is / How it works" section in plain prose with code blocks.
- Worked examples — usually two or three short snippets demonstrating the idea in isolation.
- A "Further reading" section linking to articles by other authors (the curated reading list that gave the project its early reputation).
- A "Videos" section linking to talks and screencasts.
- Cross-links to related concepts in the curriculum (e.g.
event-loopcross-links topromises,async-await,callbacks).
Tip
The curated outbound links are the project's secret weapon. Even if you skim the in-house explainer, follow at least one of the linked articles per concept — the original authors are usually the people who first popularised the idea.
Running the matching test suite
Every concept that has matching tests lives under a parallel directory in tests/. The directory layout groups concepts by theme rather than by number:
| Theme directory | Concepts covered |
|---|---|
tests/fundamentals/ |
call-stack, equality-operators, javascript-engines, primitive-types, primitives-objects, scope-and-closures, type-coercion |
tests/functions-execution/ |
async-await, event-loop, generators-iterators, iife-modules, promises |
tests/functional-programming/ |
currying-composition, higher-order-functions, map-reduce-filter, pure-functions, recursion |
tests/object-oriented/ |
factories-classes, inheritance-polymorphism, object-creation-prototypes, this-call-apply-bind |
tests/advanced-topics/ |
algorithms-big-o, data-structures, design-patterns, error-handling, es-modules, modern-js-syntax, regular-expressions |
tests/async-javascript/ |
callbacks |
tests/web-platform/ |
dom, http-fetch |
tests/beyond/ |
All 29 Beyond topics, grouped under sub-themes (browser-storage, events, language-mechanics, memory-performance, objects-properties, observer-apis, data-handling, modern-syntax-operators, type-system) |
# Run every spec for the fundamentals theme.
npx vitest run tests/fundamentals
✓ tests/fundamentals/call-stack/call-stack.test.js
✓ tests/fundamentals/equality-operators/equality-operators.test.js
... (all 7 concept files)
Tip
Read the concept page first, then read the test file second. The test file is a precise, machine-checked statement of the same rules — if the prose left you uncertain, the test will pin down the exact behaviour.
The "Beyond" track (29 advanced topics)
The repository's docs/beyond/ directory adds 29 advanced topics that go past the original 33. They live at docs/beyond/concepts/<slug>.mdx, with matching specs at tests/beyond/.../<slug>.test.js. The Beyond topics are grouped by sub-theme:
| Sub-theme | Slugs |
|---|---|
browser-storage |
cookies, indexeddb, localstorage-sessionstorage |
data-handling |
blob-file-api, json-deep-dive, requestanimationframe, typed-arrays-arraybuffers |
events |
custom-events, event-bubbling-capturing, event-delegation |
language-mechanics |
hoisting, strict-mode, temporal-dead-zone |
memory-performance |
debouncing-throttling, garbage-collection, memoization, memory-management |
modern-syntax-operators |
computed-property-names, tagged-template-literals |
objects-properties |
getters-setters, object-methods, property-descriptors, proxy-reflect, weakmap-weakset |
observer-apis |
intersection-observer, mutation-observer, performance-observer, resize-observer |
type-system |
javascript-type-nuances |
These are not part of the canonical "33" — they are an opinionated extension. Treat them the same way: read the page, then read the test.
5. Common Tasks
Recipe 1 — Work through the entire curriculum, in order
Goal: finish all 33 concepts as a deliberate study plan, in roughly the order they build on each other.
Steps:
- Open
docs/getting-started/about.mdxanddocs/getting-started/how-to-learn.mdxfor the project's recommended approach. - Read
docs/getting-started/learning-paths.mdxand pick a path. The default path follows the directory ordering: fundamentals → functions/execution → functional programming → object-oriented → async → web platform → advanced topics. - For each concept on the path, read the
docs/concepts/<slug>.mdxpage, follow at least one outbound link, then runnpx vitest run tests/<theme>/<slug>to step through the executable spec. - Track your own progress with a checklist in your notes (the repo does not track progress for you).
Verify: You can produce a one-paragraph explanation of every concept without re-reading the page.
If it fails: A concept that will not click on first reading is normal. Star the linked articles for that concept, sleep on it, and revisit in a day or two — JavaScript's prototype chain in particular has a famously steep ramp.
Tip
Pair the read with the test. The concept page tells you what the idea is; the test pins down the exact behaviour the language guarantees.
Recipe 2 — Drill a specific weak area
Goal: focus only on the topic you keep getting wrong (closures, this, prototype chains, async).
Steps:
- Identify the slug. For example, "closures" lives at
docs/concepts/scope-and-closures.mdx. - Read only that page, top to bottom. Do not skip the outbound links.
- Run only the matching test directory in watch mode:
npx vitest tests/fundamentals/scope-and-closures— the file watches itself, and you can edit the spec to test your own variations. - Once green-with-confidence, look at neighbouring concepts in the same theme (
fundamentalsneighbours:call-stack,javascript-engines).
Verify: You can write a closure that captures a counter, returns a getter and a setter, and explain why each captured variable lives where it lives.
Tip
The
tests/<theme>/<slug>/<slug>.test.jsfiles are deliberately written to read like a study guide. Read them top-to-bottom — the order ofdescribeblocks builds up complexity.
Recipe 3 — Use the curriculum as interview prep
Goal: prepare for a JavaScript-heavy front-end or full-stack interview.
Steps:
- Read
docs/getting-started/learning-paths.mdxand pick the "Interview prep" path if one is offered, or fall back to the curriculum order in Section 4. - For each concept, write your own one-paragraph definition in your notes before reading the page. Then compare.
- After reading, write three would-be interview questions for that concept. Check your answers against the test file.
- The Beyond topics with the highest interview-question density tend to be
event-bubbling-capturing,debouncing-throttling,memoization,proxy-reflect,hoisting,temporal-dead-zone, andevent-delegation— drill those in addition to the 33.
Verify: A peer can ask you any of the 33 concept names and you can deliver a 60-second explainer plus a code snippet.
Tip
Issue #544 (closed) was an early request to add a dedicated topic for
thisin functions and objects — that material now lives indocs/concepts/this-call-apply-bind.mdx. If you find yourself uncertain aboutthis, that page is the single best landing pad.
Recipe 4 — Contribute a translation
Goal: translate the curriculum into a new language so it is accessible to readers in your locale.
Steps:
- Read
CONTRIBUTING.mdfor the project's contribution flow andTRANSLATIONS.mdfor the current list of accepted translations. - Open an issue on GitHub announcing the language you intend to translate. This avoids two contributors duplicating the same work.
- Fork the repository, then create a
translations/<lang-code>/directory at the root or follow the structure documented inTRANSLATIONS.md. The original 33-js-concepts curriculum has been translated into many languages historically; the structure for new translations is documented inTRANSLATIONS.md. - Translate the README and each concept page in
docs/concepts/. Keep the slug filenames identical so cross-links continue to resolve. - Open a pull request with the translated tree. The maintainer reviews translations on a best-effort basis.
Verify: A native speaker of your target language can read the translated curriculum end-to-end without consulting the English original.
Important
Read
CODE_OF_CONDUCT.mdbefore opening a pull request. The project follows the Contributor Covenant and the maintainer enforces it.
Recipe 5 — Contribute a missing or improved resource
Goal: add a high-quality article or video to a concept's curated reading list.
Steps:
- Identify the concept page (
docs/concepts/<slug>.mdx) where you want to add the link. - Verify the link points to original, free, and currently-live content — broken or paywalled links are routinely rejected. The repository has had quality issues raised in the past (see issue #481, closed) about misleading content; the bar for new resources is high.
- Edit the page locally, add the link in the appropriate section (Articles / Videos / Books), and include the author and publication year if available.
- Run
npm run docsand verify the page still renders without Mintlify errors. - Open a pull request. Describe why the link is worth adding — one or two sentences is enough.
Verify: The new link renders in npm run docs preview and your PR description explains the contribution.
Caution
Do not add links to your own blog posts unless the post genuinely advances the concept. Self-promotional PRs are routinely closed without merge.
Recipe 6 — Fork it for a private study repo
Goal: keep your own annotations alongside the curriculum.
Steps:
- Fork the repository to your own GitHub account.
- Add a
notes/directory at the root, and per-concept files likenotes/scope-and-closures.md. - Sync upstream periodically (
git remote add upstream https://github.com/leonardomso/33-js-concepts.git && git fetch upstream && git merge upstream/main) so you pick up new outbound links and fixes. - Treat each concept page as the canonical reference and your
notes/file as the personal annotation layer.
Verify: Your fork builds with npm run docs:build and your annotations stay separate from the upstream content.
Note
Because the project is MIT-licensed, you may publish your annotated fork as long as you preserve the original copyright notice in
LICENSEand credit Leonardo Maldonado as the original author.
6. Troubleshooting
This is a documentation repository — most "errors" are encountered while running the optional test suite or the optional docs site, not while reading the curriculum.
Error: Cannot find module 'vitest'
Cause: You ran npm test or npx vitest without first running npm install. Vitest is declared in devDependencies and is not bundled with the repository.
Solution:
- From the repository root, run
npm install. - Re-run
npm test.
Prevention: Always run npm install after a fresh clone or after pulling a commit that changes package.json.
Error: document is not defined in a .dom.test.js file
Cause: The Vitest config sets environment: 'node' as the default. Tests that need a DOM rely on Vitest's per-file environment override via the .dom.test.js filename suffix, which switches to a jsdom environment.
Solution:
- Confirm the failing file ends with
.dom.test.js(not.test.js). - Confirm
jsdomis installed:npm ls jsdom. - If the file does not have the
.dom.test.jssuffix but legitimately needs the DOM, rename it.
Prevention: Keep the .dom.test.js suffix on any new test that touches document, window, localStorage, sessionStorage, cookies, or any browser-only API. The repository follows this convention rigorously — every test under tests/beyond/browser-storage/, tests/beyond/events/, tests/beyond/observer-apis/, and tests/web-platform/dom/ uses it.
Error: npx mintlify dev hangs or times out
Cause: Mintlify's CLI is downloaded on demand. A slow npm registry mirror, a corporate proxy, or an offline machine will all cause npx to wait on the registry.
Solution:
- Verify network access:
curl -I https://registry.npmjs.org. - If you are behind a corporate proxy, set
npm config set proxy http://<proxy>:<port>andnpm config set https-proxy http://<proxy>:<port>. - Pre-install the CLI globally:
npm install -g mintlify. After that,npm run docswill not need to download anything.
Prevention: Install mintlify globally on the workstations you actually develop on — npx's on-demand download is convenient but fragile on flaky networks.
Error: A curated outbound link returns 404
Cause: The curated reading lists in docs/concepts/<slug>.mdx link to articles and videos hosted by other authors. Over time some of those URLs go away — domain expiration, blog migrations, deleted YouTube videos.
Solution:
- Search for the article title — many authors migrate to a new domain and the archive lives at the Wayback Machine (
https://web.archive.org). - If the original is gone, propose a replacement that covers the same material at similar quality. Open a pull request as described in Recipe 5.
- If you cannot find a replacement, open an issue — the maintainer prefers a removed link to a 404 link.
Prevention: Run a periodic link check on your fork if you maintain one — e.g. a CI job that runs lychee or markdown-link-check against docs/concepts/. The upstream project does not currently run an automated link checker.
Error: Issue #481 — "Question 3 'Value Types and Reference Types' is wrong"
Cause: Issue #481 (closed) flagged that an early version of the value-types-vs-reference-types content was misleading. It has since been revised.
Solution: If you find a similar quality issue, open an issue with a concrete proposed correction and a reference to the language specification or to the matching test file. Vague "this is wrong" reports without a proposed fix are the slowest to triage.
Prevention: When reading, compare the prose against the matching test file — the test is the executable, machine-checked statement of the rule.
Error: npm install fails with EACCES or permission errors
Cause: Running npm install against a global Node prefix you do not own.
Solution:
- Use a Node version manager (nvm, fnm, volta) so your
nodeandnpminstall into your home directory. - Re-clone into a directory you own.
Prevention: Avoid sudo npm install. Always install Node into a per-user prefix.
Diagnostic decision tree
Is something wrong?
├── Reading on GitHub — broken link?
│ └── Recipe 5 (propose replacement) or open an issue.
├── npm test fails?
│ ├── ENOENT or "cannot find module" → npm install
│ ├── document is not defined → check .dom.test.js suffix
│ └── any other error → check Node version (>= 18 LTS)
├── npm run docs hangs?
│ └── Mintlify CLI download — check proxy/registry, pre-install globally
└── Concept content seems wrong?
└── Cross-reference the matching test in tests/<theme>/<slug>; if the test agrees with the page, the page is right.
Warning
Do not "fix" an error by changing a test to pass. The tests under
tests/are pinned statements of how the language behaves — if a test fails on your machine but passes on CI, the difference is in your environment (Node version, jsdom version), not in the test.
7. FAQ
Q: Do I need to know all 33 concepts to call myself a JavaScript developer?
The curriculum's stance is "yes, eventually." The 33 are deliberately the topics that come up in interviews, in pair programming, and in code review for any JS-heavy codebase. Junior developers are expected to know roughly the first half (call stack through prototypes, plus this); mid-level developers should be fluent in the async track (callbacks → promises → async/await → event loop); senior developers should also have a working grasp of the entire list, including clean-code, data-structures, algorithms-big-o, and the design patterns.
Q: What is the difference between the "33" and the "Beyond" topics?
The original 33 are listed in docs/concepts/ and are the canonical curriculum. The Beyond topics in docs/beyond/concepts/ are an opinionated extension covering material that has become standard in modern web development since the original curriculum was written — Proxy/Reflect, observer APIs, browser storage, debounce/throttle, memoization, garbage collection, and so on. The Beyond track is recommended once you have finished the 33.
Q: How do I track my progress through the curriculum?
The repository does not track progress for you. The simplest approach: copy the table in Section 4 into your own notes file, and tick a box per concept as you finish reading the page and running its test. A more elaborate approach: fork the repo, add a progress.md file, and commit a tick per session.
Q: Why are some concept slugs hyphenated and grouped (e.g. scope-and-closures) instead of being listed separately?
The original curriculum treated some closely related ideas as a single chapter — scope and closures, primitives and objects, currying and composition, factories and classes. The current docs/concepts/ directory preserves those groupings rather than splitting them into 40+ separate pages.
Q: Can I read the curriculum offline?
Yes. Clone the repo and read the .mdx files in any markdown-aware editor (VS Code, Obsidian, MarkText). The Mintlify dev server is convenient for rendered pages, but the raw .mdx is fully readable.
Q: How do I run only the tests for a single concept?
Use Vitest's filename filter:
npx vitest run tests/fundamentals/scope-and-closures
Or filter by test name:
npx vitest run -t "closure"
Q: What versions of Node does this support?
The devDependencies (vitest@^4.0.16, @vitest/coverage-v8@^4.0.16, jsdom@^27.4.0) target Node 18 and newer. Use the latest LTS where possible. Older versions (Node 14, 16) will not work — Vitest 4 requires Node 18+.
Q: Is there a published mobile or print version?
The project ships markdown sources and a Mintlify-rendered website. There is no official PDF, no e-book, no print edition. You are free to generate one from the .mdx sources for personal use under the MIT licence.
Q: How do I propose a new concept?
Open an issue describing the proposed concept, why it deserves to be in the canonical 33 (or the Beyond list), and which existing concept it would either replace or sit alongside. The bar for adding to the 33 is high — the list has been stable for years on purpose. The Beyond list has more flexibility.
Q: Is the project actively maintained?
The repository accepts pull requests for translations, broken links, content fixes, and Beyond additions. Feature-flagged additions to the canonical 33 are rarer. Check the GitHub issues and recent commit log to gauge current activity before opening a substantial PR.
Q: Can I use this material in my own course or training?
Yes — the project is MIT-licensed. You may copy, modify, distribute, and embed the content commercially or non-commercially as long as you preserve the copyright notice in LICENSE and credit Leonardo Maldonado as the original author.
Q: Where do I report content errors?
Open a GitHub issue at https://github.com/leonardomso/33-js-concepts/issues with a concrete proposed correction and a reference (spec, MDN, or the matching test file under tests/). Issues with proposed fixes are triaged faster than vague "this is wrong" reports — see issue #481 for the pattern of a productive correction-request.
Q: I just want a checklist, not a course. Is there one?
Yes — the table in Section 4 of this guide is the checklist. Copy it, paste it into your notes, tick boxes as you go.