This guide is for the people who maintain, fork, deploy, translate, or extend the 33-js-concepts repository — not for readers of the curriculum. If you are looking to learn from the curriculum, see the User Guide.
The repository is a deceptively simple thing: 33 canonical concept pages, 29 "Beyond" extension pages, four getting-started pages, around 60 Vitest specs, a Mintlify-built documentation site, and a package.json that ties them together. There is no service to run, no database to back up, no API key to rotate, no production traffic to serve. The entire surface area is static content plus a test runner plus a static-site generator. That makes the operational concerns quite different from a typical software project — and that is what this guide focuses on.
1. Architecture Overview
leonardomso/33-js-concepts is a content + executable specs + static documentation site repository. There is no application binary, no long-running service. The repository's deliverables are:
- The README at the repository root — a curated index of the 33 concepts and outbound links.
- MDX concept pages under
docs/concepts/(33 files) anddocs/beyond/concepts/(29 files). - A getting-started track under
docs/getting-started/(about.mdx,how-to-learn.mdx,learning-paths.mdx,prerequisites.mdx). - A Vitest test suite under
tests/mirroring the concept slugs — around 60 spec files including.test.js(Node) and.dom.test.js(jsdom) variants. - A Mintlify-built documentation site that consumes
docs/and renders to a public URL.
Component inventory
| Component | Path | Role |
|---|---|---|
| Concept pages (canonical 33) | docs/concepts/*.mdx |
Authoritative explainer per concept. Mintlify-rendered. |
| Concept pages (Beyond 29) | docs/beyond/concepts/*.mdx |
Advanced extension topics. |
| Getting started pages | docs/getting-started/*.mdx |
Onboarding: about, how to learn, learning paths, prerequisites. |
| Beyond getting-started | docs/beyond/getting-started/overview.mdx |
Onboarding for the Beyond track. |
| Top-level index | docs/index.mdx |
Mintlify home page. |
| Translations index | docs/translations.mdx |
List of language translations. |
| Contributing index | docs/contributing.mdx |
Contribution flow as rendered on the docs site. |
| Mintlify config | docs/docs.json |
Site navigation, theme, metadata. |
| SEO/structured data | docs/schema-inject.js |
Client-side JSON-LD injector emitting WebSite, TechArticle, BreadcrumbList, FAQPage, ItemList. |
| Robots directives | docs/robots.txt |
Crawler hints. |
| Vitest config | vitest.config.js |
include: tests/**/*.test.js, globals: false, environment: 'node'. |
| Test specs | tests/<theme>/<slug>/<slug>.test.js (and .dom.test.js) |
Executable spec mirroring each concept. |
| Test entry point | index.js |
Comment-only file documenting the project's intent. |
| Package metadata | package.json |
Scripts, dev dependencies, keywords. |
| Lockfile | package-lock.json |
Reproducible installs. |
| OpenCode config | opencode.jsonc |
Editor/agent integration. |
| Translations charter | TRANSLATIONS.md |
Process and standards for new translations. |
| Contribution charter | CONTRIBUTING.md |
Contribution flow, standards, scope. |
| Code of conduct | CODE_OF_CONDUCT.md |
Contributor Covenant. |
| Licence | LICENSE |
MIT. |
| Open Graph image | github-image.png, docs/og-image.png |
Social-card branding. |
Note
The architecture is intentionally minimal. There are no build steps for the concept content — the
.mdxfiles are read by Mintlify at site-build time. The only build step in the repository isvitest run(for tests) andmintlify build(for the docs site). Treat additions to the architecture with extreme scepticism: most "improvements" trade simplicity for marginal gain.
Architecture diagram
┌────────────────────────────────────────────────────────────────────┐
│ leonardomso/33-js-concepts repo │
├────────────────────────────────────────────────────────────────────┤
│ │
│ README.md ─────────► outbound-link curated index (the original) │
│ │
│ docs/ │
│ ├── index.mdx ─────────► Mintlify home page │
│ ├── docs.json ─────────► Mintlify navigation + theme │
│ ├── schema-inject.js ──► JSON-LD structured data (client-side) │
│ ├── getting-started/ [4 pages] │
│ ├── concepts/ [33 canonical pages] ◄──────┐ │
│ └── beyond/ │ │
│ ├── getting-started/[1 page] │ │
│ └── concepts/ [29 Beyond pages] ◄────┐ │ │
│ │ │ │
│ tests/ │ │ │
│ ├── fundamentals/ [7 specs] ───────────►┼──┘ │
│ ├── functions-execution/ [5 specs] ───────────►┘ │
│ ├── functional-programming/ [5 specs] ───────────►(matches concepts)
│ ├── object-oriented/ [4 specs] │
│ ├── advanced-topics/ [7 specs] │
│ ├── async-javascript/ [callbacks] │
│ ├── web-platform/ [dom, http-fetch] │
│ └── beyond/ [29 specs across sub-themes] │
│ │
│ vitest.config.js ──────► test runner config (Node default, │
│ jsdom for *.dom.test.js files) │
│ │
│ package.json ──────────► npm scripts: test, test:watch, │
│ test:coverage, docs, docs:build │
└────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────┐
│ Mintlify-built static site │
│ (docs.json drives navigation) │
└─────────────────────────────────┘
│
▼
┌─────────────────────────────────┐
│ Public documentation URL │
│ (Mintlify-hosted or self- │
│ hosted on a CDN) │
└─────────────────────────────────┘
Technology stack
| Layer | Technology | Pinned version |
|---|---|---|
| Test runner | Vitest | ^4.0.16 |
| Test coverage | @vitest/coverage-v8 |
^4.0.16 |
| DOM emulation | jsdom | ^27.4.0 |
| Documentation site generator | Mintlify | Invoked via npx mintlify (CLI is not pinned in package.json) |
| Content format | MDX | Markdown + JSX |
| Source language | Modern JavaScript (ES Modules) | Node 18+ |
| Licence | MIT | — |
Data flow — typical contributor session
Contributor edits docs/concepts/<slug>.mdx
└─► npm run docs (local Mintlify dev) ─► localhost:3000 preview
└─► npm test (Vitest) verifies the matching tests/<theme>/<slug>/<slug>.test.js
└─► git commit + push + open PR
└─► Maintainer reviews
└─► Merge to main
└─► Mintlify rebuilds and republishes the public site
There is no separate "deploy pipeline" beyond the Mintlify rebuild — content changes propagate to readers as soon as the maintainer merges.
Note
Because the site is read-only and statically generated, there is no traffic spike that would require horizontal scaling. CDN caching at the Mintlify host handles all observable load.
2. System Requirements
The repository targets two contributor workflows: running the test suite, and running the documentation site. Both are local-only. No production server, no database, no message queue, no Redis.
Contributor workstation
| Requirement | Minimum | Notes |
|---|---|---|
| Node.js | 18 LTS | Vitest 4 requires Node 18+. The latest LTS is recommended. |
| npm | Bundled with Node | Any package manager works — npm, pnpm, yarn, bun. |
| Disk space | ~250 MB | node_modules after npm install, dominated by Vitest, esbuild binaries, and jsdom. |
| RAM | 2 GB | Vitest uses parallel workers; comfortable with 4 GB. |
| Network | Outbound to registry.npmjs.org |
Required for npm install and for npx mintlify first-run download. |
| Editor | Any | VS Code, JetBrains, Vim, Sublime — all work. MDX-aware editing is nice-to-have. |
| Git | 2.x | Standard contribution flow (fork, branch, PR). |
Operating system support
The repository is OS-neutral. Linux, macOS, and Windows all work. Continuous integration may run on Ubuntu by default but no test relies on Linux-only features.
Note
The Vitest test suite is split between
*.test.jsfiles (Node-environment, no DOM) and*.dom.test.jsfiles (jsdom-environment). The convention is enforced by Vitest's per-file environment override. There is no Windows-vs-Unix path handling in the suite — all imports use forward slashes.
Hosting / publishing requirements
If you fork the repository and publish your own site:
| Requirement | Detail |
|---|---|
| Mintlify account (managed) | Easiest path. Connect the GitHub fork; Mintlify rebuilds on push. |
| Static host (self-managed) | npm run docs:build produces a static bundle that any static host (Netlify, Vercel, Cloudflare Pages, GitHub Pages, S3+CloudFront) can serve. |
| Custom domain | Configure a CNAME or ALIAS to your host of choice. |
| HTTPS | Required for the JSON-LD structured-data injector to function correctly when rendered via https:// canonical URLs. Most static hosts terminate TLS for free. |
3. Configuration Reference
This is a small project, but every config file matters. Below is the complete set, with every meaningful key documented.
package.json
| Field | Value | Purpose |
|---|---|---|
name |
33-js-concepts |
npm package name (project is not actually published to npm — name is for local use). |
version |
1.0.0 |
Static. Bumping is optional. |
description |
"A curated collection of 33 essential JavaScript concepts every developer should master…" | Repository tagline; used in npm metadata. |
main |
index.js |
Entry point declaration. The file itself is comment-only. |
author.name |
Leonardo Maldonado |
Original author. |
author.url |
https://github.com/leonardomso |
Author's GitHub. |
license |
MIT |
Licence. |
bugs.url |
https://github.com/leonardomso/33-js-concepts/issues |
Issue tracker. |
homepage |
https://github.com/leonardomso/33-js-concepts#readme |
Project home. |
repository.type |
git |
— |
repository.url |
git+https://github.com/leonardomso/33-js-concepts.git |
— |
scripts.test |
vitest run |
Run the entire test suite once. |
scripts.test:watch |
vitest |
Watch mode — re-run on file save. |
scripts.test:coverage |
vitest run --coverage |
Run with coverage instrumentation (@vitest/coverage-v8). |
scripts.docs |
cd docs && npx mintlify dev |
Start a local docs server. |
scripts.docs:build |
cd docs && npx mintlify build |
Produce a production docs build. |
keywords |
27 keywords incl. javascript, closures, promises, async-await, event-loop, prototypes, interview-preparation |
Used in npm and search ranking. |
devDependencies.@vitest/coverage-v8 |
^4.0.16 |
V8 coverage. |
devDependencies.jsdom |
^27.4.0 |
DOM emulation for *.dom.test.js. |
devDependencies.vitest |
^4.0.16 |
Test runner. |
Important
No
dependencies(production) are declared. The repository ships zero runtime code, so there is nothing to depend on. If a future PR proposes adding a runtime dependency, scrutinise the rationale — most plausible additions belong indevDependencies.
vitest.config.js
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
include: ['tests/**/*.test.js'],
globals: false,
environment: 'node'
}
})
| Key | Value | Effect |
|---|---|---|
test.include |
['tests/**/*.test.js'] |
Globs that select files. The pattern matches both <concept>.test.js and <concept>.dom.test.js. |
test.globals |
false |
Test files must import { describe, it, expect } from 'vitest'. Prevents accidental reliance on global APIs. |
test.environment |
'node' |
Default environment. Files ending in .dom.test.js get jsdom via Vitest's per-file inference. |
Important
Do not change
globals: falsetotruewithout updating every test file. The project's deliberate stance is that imports are explicit — this makes the test files readable as standalone study material.
docs/docs.json
The Mintlify configuration file. It declares site navigation (sidebar groups, page order), theme tokens (colours, fonts), site metadata (title, description, social links), and search behaviour. Edit this file when you add a new concept page so it appears in the rendered navigation.
docs/schema-inject.js
A self-contained IIFE that injects JSON-LD structured data into every page on the rendered site. Behaviour:
| Page type | Emitted Schema.org payload |
|---|---|
Home page (/) |
WebSite (with SearchAction), and an ItemList of up to 33 concept links derived from on-page anchors. |
Concept article (/concepts/<slug> or /beyond/concepts/<slug>) |
TechArticle + BreadcrumbList. If a "Frequently Asked Questions" <h2> exists, also a FAQPage. |
| Other pages | WebPage + BreadcrumbList. |
Constants you may want to override in a fork:
var SITE_NAME = "33 JavaScript Concepts";
var SCHEMA_SCRIPT_ID = "structured-data-jsonld";
var AUTHOR = {
"@type": "Person",
name: "Leonardo Maldonado",
url: "https://github.com/leonardomso",
};
var PUBLISHER = {
"@type": "Organization",
name: SITE_NAME,
};
Note
The injector runs on
DOMContentLoaded(or immediately if the DOM is already ready). It is idempotent — repeated calls toinjectSchema()overwrite the same<script id="structured-data-jsonld">element rather than appending duplicates.
docs/robots.txt
Standard search-engine directives. Edit if you fork and want to change indexing behaviour.
opencode.jsonc
Project-level configuration for the opencode editor/agent tooling. Optional — has no effect on tests, docs, or content.
Environment variables
The project does not read any environment variables at test or build time. There is no .env to set up.
4. Deployment & Scaling
The repository is deployed as a static documentation site plus a GitHub-hosted source-of-truth. Operational simplicity is the headline feature.
Deployment surface
| Asset | Where it lives | Refresh trigger |
|---|---|---|
| GitHub repository | github.com/leonardomso/33-js-concepts |
Push to main. |
| Documentation site | Mintlify-hosted (managed) — or any static host you point at docs:build output |
Push to main (Mintlify-managed) or manual rebuild (self-hosted). |
| npm package | Not published. | — |
| Docker image | Not published. | — |
| GitHub Pages | Optional. Build via npm run docs:build and copy the output to a gh-pages branch. |
— |
Mintlify-managed deployment (recommended)
- Connect the repository to Mintlify via Mintlify's GitHub integration.
- Mintlify rebuilds the site on every push to
main. - Configure your custom domain in Mintlify's dashboard.
- The
docs/docs.jsonfile controls the site's structure; commits to that file propagate within minutes of merge.
Self-managed static deployment
# In repository root
npm install
cd docs
npx mintlify build
The build emits a static bundle. Upload the bundle to any static host:
| Host | Notes |
|---|---|
| GitHub Pages | Push the build to a gh-pages branch. Use a CNAME file for a custom domain. |
| Netlify | Connect the repo and set npm run docs:build as the build command, output directory as Mintlify's default. |
| Vercel | Connect the repo. Build command npm run docs:build. |
| Cloudflare Pages | Same pattern as Vercel. Cloudflare's edge cache is excellent for read-heavy static content. |
| S3 + CloudFront | Sync the build output to an S3 bucket; serve via CloudFront with HTTPS. |
Tip
Pre-warm the CDN after each rebuild by hitting at least the home page and a representative concept page. Mintlify-managed deployment handles this for you.
Scaling
Reads scale linearly with the static host's CDN. There is no write side, no database, no rate limit to tune. A traffic spike of 10x or 100x is invisible to the repository — only to the CDN bill.
Continuous integration
The project does not currently ship a CI configuration in the briefing's .github/workflows listing. A typical CI for this repo would:
- Run
npm install. - Run
npm test(Vitest). - Run
npm run docs:build(Mintlify) to verify the docs site builds without errors. - Optionally run a link checker (
lychee,markdown-link-check) againstdocs/to catch decayed outbound links.
Note
If you are setting up CI for a fork, gate
merge to mainon (a) all tests green and (b) docs build green. Outbound-link health checks should report-only (warn, don't fail) — the project links to many third-party sites that occasionally throttle automated checkers.
5. Operations
Runbook — adding a concept to the canonical 33
Adding a new concept to the canonical 33 is a substantial commitment. The list has been deliberately stable. If a concept genuinely deserves inclusion:
- [ ] Open an issue describing the concept, why it deserves canonical status, and which (if any) existing concept it replaces.
- [ ] Wait for maintainer alignment before writing code.
- [ ] Create
docs/concepts/<slug>.mdxmirroring the structure of an existing canonical page. - [ ] Create
tests/<theme>/<slug>/<slug>.test.jsmirroring the structure of an existing test file. Use.dom.test.jsif the concept needs the DOM. - [ ] Update the README's table-of-contents to include the new concept and renumber if needed.
- [ ] Update
docs/docs.jsonso the new page appears in the rendered navigation. - [ ] Update
docs/index.mdxif it references the count "33". - [ ] Run
npm testandnpm run docs:buildlocally. - [ ] Open a PR with a short rationale and link to the issue.
Runbook — adding a Beyond topic
Adding a Beyond topic is lower-stakes. The Beyond list is intended to grow.
- [ ] Pick a sub-theme (
browser-storage,data-handling,events,language-mechanics,memory-performance,modern-syntax-operators,objects-properties,observer-apis,type-system) or open an issue proposing a new sub-theme. - [ ] Create
docs/beyond/concepts/<slug>.mdx. - [ ] Create
tests/beyond/<sub-theme>/<slug>/<slug>.test.js. - [ ] Update
docs/docs.jsonso the new page appears in the Beyond navigation. - [ ] Run tests and docs build.
- [ ] Open a PR.
Runbook — accepting a translation
- [ ] Verify the contributor has read
CONTRIBUTING.mdandTRANSLATIONS.md. - [ ] Verify slugs in the translation match the English originals (so cross-links resolve).
- [ ] Run a basic sanity check on the translated pages — at least one MDX render via
npm run docs. - [ ] Update
docs/translations.mdxandTRANSLATIONS.mdto list the new language. - [ ] Merge.
Runbook — link rot maintenance
Outbound links in docs/concepts/<slug>.mdx decay over time. Periodically:
- [ ] Run an automated link checker against
docs/concepts/anddocs/beyond/concepts/. - [ ] For each 404, search the original article title — many authors have migrated to a new domain.
- [ ] Replace dead links with Wayback Machine archives (
https://web.archive.org/web/*/<original-url>) when no replacement exists. - [ ] Open a single PR per maintenance run, listing every replaced link in the PR body.
Tip
Run link maintenance quarterly. Monthly is overkill; annually is too rare. The project linked to a wide variety of third-party blogs over the years; perhaps 2-5% of links go stale per quarter.
Backups
Source of truth is GitHub. There is no database. The Mintlify-rendered site is regenerable from source, so the only thing to back up is the Git history — and GitHub provides that.
Note
If you are running on a self-managed Mintlify deployment, also back up
docs/docs.jsonand your customdocs/schema-inject.jsoverrides — they are part of the source repo and travel with it automatically.
Monitoring
For the published docs site, the operational signals worth watching:
| Signal | Source | Action threshold |
|---|---|---|
| Site uptime | Mintlify status / your CDN's status page | Investigate any sustained outage. |
| 404 rate | CDN access logs | Spike suggests a navigation regression after a recent merge. |
| Link-check report | Periodic lychee run |
Replace decayed outbound links. |
| Search-engine indexing | Google Search Console / Bing Webmaster | Drop in indexed pages may indicate a robots.txt or canonical-URL regression. |
| Build failures | Mintlify build logs / CI | Fail-fast investigation — usually an MDX syntax error. |
6. Performance
The performance profile is dominated by read latency to the rendered docs site. There is no write path, no database query, no API call.
Static-site performance
Mintlify (and any decent static host) emits HTML, CSS, JavaScript, and images that a CDN can serve in 50-200ms TTFB worldwide. The dominant performance lever is CDN cache hit rate; aim for ≥99%.
docs/schema-inject.js overhead
The structured-data injector runs once per page on DOMContentLoaded. It traverses the DOM to extract a heading, breadcrumbs, and (on concept pages) FAQ items — bounded by the page's own DOM size. The work is O(N) in the number of FAQ <button> elements and O(M) in the number of <a> links on the home page (capped at 33 concepts). On a typical concept page this completes in under 5 ms.
Note
The injector is idempotent — repeated invocations rewrite the same
<script id="structured-data-jsonld">element rather than appending duplicates. SPAs that re-render via client-side routing should re-invokeinjectSchema()after each route change; the current implementation does not subscribe to history events, so re-invocation is the host site's responsibility.
Test suite performance
npm test runs ~60 spec files in parallel. Wall-clock time on a modern laptop is typically 5-15 seconds. With coverage enabled (npm run test:coverage) expect 2-3x. Vitest's default worker pool sizing is appropriate; do not pin --threads unless you have a specific reason.
Tip
If
npm testruns slowly in CI, the most common cause is an under-provisioned runner (1 CPU, 2 GB RAM). Vitest scales well to 4-8 CPUs.
Documentation site build performance
npm run docs:build runs Mintlify's build pipeline, which is dominated by MDX compilation. With ~70 pages, build time is typically 30-90 seconds. This is rarely a bottleneck.
Tip
If a PR slows the docs build noticeably, audit the MDX changes — heavy custom JSX components (interactive widgets, embedded React) can blow up build time disproportionately. Keep concept pages mostly prose and code blocks.
CDN cache strategy
Set aggressive cache headers on built assets (long max-age, immutable for hashed files) and shorter TTLs on the HTML pages so content updates propagate quickly. Most static hosts handle this automatically with sensible defaults.
7. Security
This is a public, read-only, statically generated documentation site that ships no executable code to readers' machines beyond a minor structured-data injector. The threat surface is correspondingly small.
Threats in scope
| Threat | Likelihood | Mitigation |
|---|---|---|
| Outbound link decay (404, paywalled, or redirected to spam) | High over multi-year horizon | Periodic link checks (Section 5 runbook). |
| Outbound link redirected to malicious content (domain hijack) | Low but non-zero | Periodic spot-checks of links, especially for low-traffic blogs. Reserve rel="noopener noreferrer" on outbound links rendered by Mintlify. |
| MDX injection via PR | Low (PRs are reviewed) | Maintainer review of every PR; no auto-merge. |
| Malicious dev-dependency (supply chain) | Low (3 dev deps, all reputable) | Pinning via package-lock.json; periodic npm audit. |
| Credential exposure in repo | None known | The repository ships no secrets; .env is not used. |
XSS via docs/schema-inject.js |
Very low | The script reads DOM content via safeText() (whitespace-collapse, trim) and emits JSON-LD via JSON.stringify — no innerHTML writes. |
Warning
The single most important security practice here is outbound-link hygiene. The repository does not own the domains it links to. A blog domain that lapses can be re-registered by a third party and used to serve malware. Periodically spot-check the curated reading lists, especially for older concept pages with many links to long-tail blogs.
Sensitive material
The repository contains no secrets, no credentials, no private user data, no personally identifiable information beyond the author's public GitHub handle. All content is intended to be public. There is no data classification beyond "all public, MIT-licensed."
Caution
If you fork this repo to build a commercial offering, do not copy contributor email addresses or PR comments without consent. Public PR metadata is technically public, but treating contributors' names and emails as bulk-extractable data invites GDPR exposure if you operate in or serve EU readers.
docs/schema-inject.js review
The injector's read-only DOM traversal uses defensive try/catch around every read and never executes user-supplied strings. It writes only:
- A single
<script type="application/ld+json">tag. - The
textproperty of that tag, set toJSON.stringify(...)output (safe — JSON cannot escape into HTML).
There is no eval, no Function constructor, no innerHTML. The script's only side effect is that <script> tag, scoped to the rendered docs site.
Dependency hygiene
Run npm audit periodically. The dev dependencies (vitest, @vitest/coverage-v8, jsdom) are well-maintained. Transitive vulnerabilities are common in node_modules but rarely affect a project that ships no runtime code — the only blast radius is the contributor's local machine when running tests.
Warning
Do not run
npm installagainst a fork's PR branch on a sensitive workstation. Use a sandbox (container, dedicated user) if you ever need to run a third-party fork's install scripts. Standard supply-chain hygiene applies.
Reporting a security issue
For genuine security concerns (e.g. a contributor PR that injects unsafe MDX, a schema-inject.js regression that allows DOM-XSS), open a private security advisory via GitHub. Do not file public issues describing exploitable bugs — coordinate with the maintainer first.
8. Developer Internals
Repository structure
33-js-concepts/
├── README.md Top-level curated index — the original deliverable.
├── CONTRIBUTING.md Contribution flow and standards.
├── CODE_OF_CONDUCT.md Contributor Covenant.
├── TRANSLATIONS.md Translation process and accepted languages.
├── LICENSE MIT.
├── github-image.png Open-Graph image for GitHub.
├── index.js Comment-only entry point — declares project intent.
├── package.json Scripts and dev dependencies.
├── package-lock.json Locked dependency tree.
├── vitest.config.js Test runner configuration.
├── opencode.jsonc OpenCode tooling configuration.
├── .gitignore Standard Node ignores.
│
├── docs/ Mintlify documentation site source.
│ ├── index.mdx Site home page.
│ ├── docs.json Mintlify navigation, theme, metadata.
│ ├── schema-inject.js JSON-LD structured-data injector.
│ ├── robots.txt Crawler directives.
│ ├── og-image.png Social card.
│ ├── favicon.ico Site favicon.
│ ├── 5c8wamucvfketshf1eyrw254gz94jwre.txt Domain-verification or static asset (deployment artefact).
│ ├── contributing.mdx Contribution flow rendered in-site.
│ ├── translations.mdx Translations index rendered in-site.
│ ├── getting-started/
│ │ ├── about.mdx What is this curriculum?
│ │ ├── how-to-learn.mdx Project's recommended approach.
│ │ ├── learning-paths.mdx Suggested orderings (interview prep, fundamentals first, async track, etc.).
│ │ └── prerequisites.mdx What you should know before starting.
│ ├── concepts/ The canonical 33 concept pages.
│ │ ├── call-stack.mdx
│ │ ├── primitive-types.mdx
│ │ ├── primitives-objects.mdx
│ │ ├── type-coercion.mdx
│ │ ├── equality-operators.mdx
│ │ ├── scope-and-closures.mdx
│ │ ├── javascript-engines.mdx
│ │ ├── event-loop.mdx
│ │ ├── factories-classes.mdx
│ │ ├── this-call-apply-bind.mdx
│ │ ├── object-creation-prototypes.mdx
│ │ ├── inheritance-polymorphism.mdx
│ │ ├── iife-modules.mdx
│ │ ├── es-modules.mdx
│ │ ├── http-fetch.mdx
│ │ ├── callbacks.mdx
│ │ ├── promises.mdx
│ │ ├── async-await.mdx
│ │ ├── higher-order-functions.mdx
│ │ ├── map-reduce-filter.mdx
│ │ ├── pure-functions.mdx
│ │ ├── currying-composition.mdx
│ │ ├── recursion.mdx
│ │ ├── data-structures.mdx
│ │ ├── algorithms-big-o.mdx
│ │ ├── dom.mdx
│ │ ├── design-patterns.mdx
│ │ ├── modern-js-syntax.mdx
│ │ ├── error-handling.mdx
│ │ ├── regular-expressions.mdx
│ │ ├── clean-code.mdx
│ │ ├── generators-iterators.mdx
│ │ └── web-workers.mdx
│ └── beyond/
│ ├── getting-started/overview.mdx
│ └── concepts/ The 29 Beyond pages, grouped by sub-theme in tests/.
│
└── tests/
├── fundamentals/ call-stack, equality-operators, javascript-engines, primitive-types, primitives-objects, scope-and-closures, type-coercion
├── functions-execution/ async-await, event-loop, generators-iterators, iife-modules, promises
├── functional-programming/ currying-composition, higher-order-functions, map-reduce-filter, pure-functions, recursion
├── object-oriented/ factories-classes, inheritance-polymorphism, object-creation-prototypes, this-call-apply-bind
├── advanced-topics/ algorithms-big-o, data-structures, design-patterns, error-handling, es-modules, modern-js-syntax, regular-expressions
├── async-javascript/ callbacks (.test.js + .dom.test.js)
├── web-platform/ dom, http-fetch
└── beyond/
├── browser-storage/ cookies (incl. .dom.test.js), indexeddb, localstorage-sessionstorage (incl. .dom.test.js)
├── data-handling/ blob-file-api (incl. .dom.test.js), json-deep-dive, requestanimationframe, typed-arrays-arraybuffers
├── events/ custom-events (incl. .dom.test.js), event-bubbling-capturing (.dom.test.js), 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 (incl. .dom.test.js), mutation-observer (.dom.test.js), performance-observer, resize-observer
└── type-system/ javascript-type-nuances
Adding a new concept (canonical 33 or Beyond)
The canonical procedure mirrors the existing files. Treat consistency as the highest virtue — readers expect every concept page to feel structurally identical.
- Pick the slug. Use kebab-case. Match the slug already used in
tests/if a test exists, or create both at once. - Create the MDX page. Open a sibling page (e.g.
docs/concepts/scope-and-closures.mdx) as a template. Copy its frontmatter (Mintlify-specific meta), its section structure (Definition → How it works → Examples → Articles → Videos → Cross-links), and adapt to the new concept. - Create the test file. Place under
tests/<theme>/<slug>/<slug>.test.js. If the concept needs the DOM (anything touchingdocument,window,localStorage, cookies, or events), use<slug>.dom.test.js. Each test file shouldimport { describe, it, expect } from 'vitest'(and any ofvi,beforeEach,afterEachit needs) —globals: falseis the project's convention. - Update
docs/docs.json. Add the new page to the appropriate Mintlify navigation group so it appears in the rendered sidebar. - Update the README. Add a row to the curated index in alphabetical-or-numbered order matching the existing pattern.
- Verify locally. Run
npm testandnpm run docsand confirm the new page is reachable from the rendered navigation.
The translation directory pattern
Translations historically lived at the repository root in translations/<lang-code>/ (per TRANSLATIONS.md). Each translation duplicates the README in the target language. Since the migration to a Mintlify-rendered site, translations may also live as language-prefixed routes (docs/<lang-code>/) — check TRANSLATIONS.md for the current canonical layout. Either way:
- Slugs must match the English originals so cross-links work.
- Image references should use the same paths.
- Code samples should not be translated (variable names, function names) — only prose.
Important
Translations are accepted on a best-effort basis. The maintainer may not speak the target language and relies on the translator's good faith and on community review. Open a PR even if the translation is incomplete — incremental translations are welcome.
Coding conventions in test files
Every test file follows the same shape:
import { describe, it, expect } from 'vitest'
// optionally: import { vi, beforeEach, afterEach } from 'vitest'
describe('<Concept Name>', () => {
// ============================================================
// SECTION HEADERS LIKE THIS GROUP RELATED BEHAVIOURS
// ============================================================
describe('<sub-topic>', () => {
it('should <expected behaviour>', () => {
// From: short comment quoting the concept page
// ...assertion...
})
})
// more describe blocks...
})
The big-comment-banner section markers (// ============) are deliberate — they make the test files browseable as study material, not just executable. When adding a new test file, mirror the banner style of an existing file in the same theme.
Code patterns and conventions
- Imports are explicit. No globals (
globals: false). - Tests read top-to-bottom as a study guide. Order
describeblocks from simple to complex. - Comments quote the concept page. Many tests include
// From: <quote>comments tying the assertion back to the prose. Maintain this — it is the project's anti-fabrication pattern. - DOM tests use the
.dom.test.jssuffix. Vitest's per-file environment override switches them to jsdom. - No external mocks. The tests target language and browser-platform behaviour, not third-party libraries. There are no API mocks, no network shims.
Testing strategy
| Layer | Strategy |
|---|---|
| Concept correctness | Each concept page has a sibling test file whose assertions exercise the same behaviour. The test file is the executable contract. |
| Cross-concept consistency | Tests are isolated per concept; cross-concept consistency is enforced by review, not by automation. |
| DOM correctness | .dom.test.js files run under jsdom. Some browser-only APIs (Performance Observer, Resize Observer) are partially polyfilled by jsdom; tests assert behaviour that jsdom actually implements. |
| Mintlify build | npm run docs:build should be part of CI. A failing build is almost always an MDX syntax error. |
| Outbound link health | Out of scope for the test suite; covered by periodic link-check runs (Section 5). |
Potential improvements
- CI configuration in the repo. A
.github/workflows/ci.ymlrunningnpm testandnpm run docs:buildon every PR would prevent regressions. - Automated link checker. A scheduled GitHub Action running
lycheeagainstdocs/concepts/anddocs/beyond/concepts/would surface decayed outbound links proactively. - Translation health dashboard. As translations accumulate, a per-language coverage table (which concept pages have been translated, which are stale) would help prioritise contribution effort.
- Concept-page frontmatter schema. Lock down the Mintlify frontmatter expected on every concept page (title, description, sidebar position, last-reviewed date) and validate via a small script in CI.
- Beyond-track stability. The Beyond directory's sub-theme structure has grown organically. A future cleanup pass could consolidate sub-themes (e.g. merge
modern-syntax-operatorsinto a broadersyntaxtheme) for clearer navigation.
Contributing guide (for engineers)
The high-level flow:
- Read
CONTRIBUTING.mdandCODE_OF_CONDUCT.md. - Open an issue describing your proposed change before sending a large PR.
- Fork, branch, edit, test, build docs.
- Open a PR with a clear description and link to the issue.
- Address review feedback.
Common PR types and expected effort:
| PR type | Typical review depth |
|---|---|
| Typo / grammar fix | Light. Approved within days. |
| Broken-link replacement | Light. Approved within days. |
| New outbound resource on an existing concept | Moderate. Reviewer checks link quality and relevance. |
| New Beyond topic | Moderate-to-heavy. Reviewer expects matching test file and Mintlify navigation update. |
| New canonical 33 entry | Heavy. Requires prior issue alignment. |
| Translation | Light-to-moderate. Reviewer checks slug conformance and high-level structure. |
Tip
The fastest way to get a PR merged is to mirror the structure of an existing accepted PR. The repository's PR history is the best reference for "what does a good contribution look like."
9. Integration Points
Outbound integrations
| Integration | Purpose | Replaceable? |
|---|---|---|
| Mintlify (docs renderer) | Builds the published documentation site from docs/. |
Yes — any MDX-aware static site generator (Docusaurus, Astro Starlight, VitePress) could replace it. The migration cost would be configuration (docs.json → equivalent), not content. |
| Vitest (test runner) | Runs the .test.js and .dom.test.js specs. |
Yes — Jest, Mocha, or node:test could run the suite with minimal changes. The import { describe, it, expect } from 'vitest' lines would need updating, and the per-file environment auto-detection (.dom.test.js → jsdom) would need an equivalent in the new runner. |
| jsdom | Provides a browser-like environment for .dom.test.js. |
Yes — happy-dom is a faster alternative that supports most APIs the project uses. |
@vitest/coverage-v8 |
Coverage instrumentation when npm run test:coverage runs. |
Yes — c8 (V8) or istanbul could replace it. |
| GitHub | Source-of-truth hosting, issues, PRs. | Yes in principle (GitLab, Codeberg) — practically, GitHub is where the contributors are. |
| OpenCode | Editor/agent tooling per opencode.jsonc. |
Optional — has no effect on the published deliverables. |
Inbound integrations
| Integration | Purpose |
|---|---|
| Search engines (Google, Bing, DuckDuckGo) | Index the published site. The docs/schema-inject.js injector emits Schema.org structured data to improve rich-result eligibility (TechArticle, BreadcrumbList, FAQPage, ItemList). |
https://web.archive.org (Wayback Machine) |
Archives the site over time. Useful as a fallback for decayed outbound links. |
| Curated lists / aggregators | Many "awesome-javascript" lists link to this repository. The README's curated index is the public-facing entry point. |
| Translators | The TRANSLATIONS.md flow is the inbound integration for community translations. |
Public URLs
| URL | Purpose |
|---|---|
https://github.com/leonardomso/33-js-concepts |
Source repository. |
https://github.com/leonardomso/33-js-concepts/issues |
Issue tracker. |
| The Mintlify-rendered docs site (project's primary public URL) | Published documentation. |
Schema.org / structured data
The docs/schema-inject.js injector emits a JSON-LD @graph containing:
| Page type | Top-level types |
|---|---|
| Home | WebSite (with SearchAction), ItemList of up to 33 concepts. |
| Concept article | TechArticle (headline, description, URL, author, publisher, datePublished, dateModified) + BreadcrumbList. Plus FAQPage if a "Frequently Asked Questions" <h2> is present on the page. |
| Other pages | WebPage + BreadcrumbList. |
This is consumed by search engines and AI crawlers to improve indexing and rich-result eligibility. It is not consumed by readers directly.
Note
The injector runs client-side. Server-rendered structured data (e.g. baked into the static HTML at build time) would be more robust for non-JavaScript crawlers — a future improvement could move the JSON-LD generation into a Mintlify plugin or build-time script.
Issue references — recent community signals
| Issue | Status | Lesson |
|---|---|---|
| #481 | Closed | An early version of the value-types/reference-types content was flagged as misleading. The page has since been revised. The lesson: even canonical pages can have errors; the test-file pairing is the project's anti-regression mechanism. |
| #544 | Closed | A request to add a dedicated topic for this in functions and objects. The material is now part of docs/concepts/this-call-apply-bind.mdx. The lesson: the canonical 33 cover the territory, even if the topic-naming differs from a reader's expectation. |