# 33 JS Concepts User Guide

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.

```text
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.mdx` and 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.json` with `test`, `test:watch`, `test:coverage`, `docs`, and `docs:build` scripts** 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.json` declares `name: "33-js-concepts"`, `version: "1.0.0"`, `license: "MIT"`, with Leonardo Maldonado as the named author. Only `devDependencies` exist — `vitest`, `@vitest/coverage-v8`, and `jsdom`. 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`.

```bash
# 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
```

```text
> 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 `.mdx` files 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`:

```javascript
// 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`, and `bun` will all work for installing the dev deps).
- A working terminal. No native toolchain is required.

#### Steps

```bash
git clone https://github.com/leonardomso/33-js-concepts.git
cd 33-js-concepts
npm install
npm test
```

```text
> 33-js-concepts@1.0.0 test
> vitest run
```

The default test script runs **all** suites in one pass. To run a single concept:

```bash
npx vitest run tests/fundamentals/scope-and-closures/scope-and-closures.test.js
```

To run in watch mode (Vitest re-runs when you save):

```bash
npm run test:watch
```

To produce a coverage report (uses `@vitest/coverage-v8`):

```bash
npm run test:coverage
```

> [!NOTE]
> Tests whose filename ends in `.dom.test.js` rely on a DOM. Vitest is configured with `environment: 'node'` by default, so DOM-flavoured tests use the `jsdom` dev 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.js` suffix, those tests will fail with `document 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. |

```bash
npm run docs
```

```text
[mintlify] Starting development server...
[mintlify] Local: http://localhost:3000
```

> [!WARNING]
> `npx mintlify dev` will download the Mintlify CLI on first run. If you are on a corporate network that blocks `npm` registry access, the docs site will not start. Run `npm install -g mintlify` from a network that allows registry access, then re-try.

### Verifying the install

After `npm install`, run a quick health check:

```bash
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`/`expect` in every file — edit `vitest.config.js` and set `globals: 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:

1. A title and a one-paragraph definition.
2. A "What it is / How it works" section in plain prose with code blocks.
3. Worked examples — usually two or three short snippets demonstrating the idea in isolation.
4. A "Further reading" section linking to articles by other authors (the curated reading list that gave the project its early reputation).
5. A "Videos" section linking to talks and screencasts.
6. Cross-links to related concepts in the curriculum (e.g. `event-loop` cross-links to `promises`, `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`) |

```bash
# Run every spec for the fundamentals theme.
npx vitest run tests/fundamentals
```

```text
✓ 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:**

1. Open `docs/getting-started/about.mdx` and `docs/getting-started/how-to-learn.mdx` for the project's recommended approach.
2. Read `docs/getting-started/learning-paths.mdx` and pick a path. The default path follows the directory ordering: fundamentals → functions/execution → functional programming → object-oriented → async → web platform → advanced topics.
3. For each concept on the path, read the `docs/concepts/<slug>.mdx` page, follow at least one outbound link, then run `npx vitest run tests/<theme>/<slug>` to step through the executable spec.
4. 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:**

1. Identify the slug. For example, "closures" lives at `docs/concepts/scope-and-closures.mdx`.
2. Read only that page, top to bottom. Do not skip the outbound links.
3. 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.
4. Once green-with-confidence, look at neighbouring concepts in the same theme (`fundamentals` neighbours: `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.js` files are deliberately written to read like a study guide. Read them top-to-bottom — the order of `describe` blocks builds up complexity.

### Recipe 3 — Use the curriculum as interview prep

**Goal:** prepare for a JavaScript-heavy front-end or full-stack interview.

**Steps:**

1. Read `docs/getting-started/learning-paths.mdx` and pick the "Interview prep" path if one is offered, or fall back to the curriculum order in Section 4.
2. For each concept, write your own one-paragraph definition in your notes **before** reading the page. Then compare.
3. After reading, write three would-be interview questions for that concept. Check your answers against the test file.
4. The Beyond topics with the highest interview-question density tend to be `event-bubbling-capturing`, `debouncing-throttling`, `memoization`, `proxy-reflect`, `hoisting`, `temporal-dead-zone`, and `event-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](https://github.com/leonardomso/33-js-concepts/issues/544) (closed) was an early request to add a dedicated topic for `this` in functions and objects — that material now lives in `docs/concepts/this-call-apply-bind.mdx`. If you find yourself uncertain about `this`, 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:**

1. Read `CONTRIBUTING.md` for the project's contribution flow and `TRANSLATIONS.md` for the current list of accepted translations.
2. Open an issue on GitHub announcing the language you intend to translate. This avoids two contributors duplicating the same work.
3. Fork the repository, then create a `translations/<lang-code>/` directory at the root or follow the structure documented in `TRANSLATIONS.md`. The original 33-js-concepts curriculum has been translated into many languages historically; the structure for new translations is documented in `TRANSLATIONS.md`.
4. Translate the README and each concept page in `docs/concepts/`. Keep the slug filenames identical so cross-links continue to resolve.
5. 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.md` before 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:**

1. Identify the concept page (`docs/concepts/<slug>.mdx`) where you want to add the link.
2. 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](https://github.com/leonardomso/33-js-concepts/issues/481), closed) about misleading content; the bar for new resources is high.
3. Edit the page locally, add the link in the appropriate section (Articles / Videos / Books), and include the author and publication year if available.
4. Run `npm run docs` and verify the page still renders without Mintlify errors.
5. 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:**

1. Fork the repository to your own GitHub account.
2. Add a `notes/` directory at the root, and per-concept files like `notes/scope-and-closures.md`.
3. 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.
4. 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 `LICENSE` and 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:**

1. From the repository root, run `npm install`.
2. 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:**

1. Confirm the failing file ends with `.dom.test.js` (not `.test.js`).
2. Confirm `jsdom` is installed: `npm ls jsdom`.
3. If the file does not have the `.dom.test.js` suffix 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:**

1. Verify network access: `curl -I https://registry.npmjs.org`.
2. If you are behind a corporate proxy, set `npm config set proxy http://<proxy>:<port>` and `npm config set https-proxy http://<proxy>:<port>`.
3. Pre-install the CLI globally: `npm install -g mintlify`. After that, `npm run docs` will 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:**

1. Search for the article title — many authors migrate to a new domain and the archive lives at the Wayback Machine (`https://web.archive.org`).
2. 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.
3. 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](https://github.com/leonardomso/33-js-concepts/issues/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:**

1. Use a Node version manager (nvm, fnm, volta) so your `node` and `npm` install into your home directory.
2. Re-clone into a directory you own.

**Prevention:** Avoid `sudo npm install`. Always install Node into a per-user prefix.

### Diagnostic decision tree

```text
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:

```bash
npx vitest run tests/fundamentals/scope-and-closures
```

Or filter by test name:

```bash
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](https://github.com/leonardomso/33-js-concepts/issues/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.

---

_Generated April 2026 from leonardomso/33-js-concepts at 60f9337. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
