This guide is written for fork operators, translation maintainers, content stewards, and engineers integrating the catalogue into derivative tooling (interview platforms, training materials, quiz apps, Anki decks, search-engine sitemaps). It is a deliberate counterpart to the User Guide: where the User Guide says how to read, this document says how the repository works internally and how to keep it healthy as a piece of community infrastructure.
The repository itself ships no executable code, no build pipeline, no CI workflow, no test harness, and no runtime. The "platform" is GitHub itself: GFM rendering, the <details> disclosure widget, the issue tracker, and the pull-request system. Every operational concern below therefore reduces to one of five flavours: content correctness, translation drift, PR-review workflow, link rot, and fork hygiene.
Table of Contents
- Executive Summary
- Repository Architecture
- System Requirements
- Configuration Surface
- Question Schema (Implicit Template)
- Internationalization Implementation
- Operations Playbook
- Security & Threat Model
- Repository Structure
- Code Patterns and Conventions
- Quality Heuristics
- Improvements Roadmap
- Troubleshooting
- Quick Reference
1. Executive Summary
lydiahallie/javascript-questions is a community-maintained question catalogue of advanced JavaScript multiple-choice puzzles, distributed as plain markdown across one canonical English README.md and 22 locale-specific translation directories. The repository is content, not software — there is no service to operate, no version to release, no dependency tree to audit. The maintenance burden is editorial: vetting question correctness, propagating errata into translations, reviewing pull requests, and triaging issues.
Why this guide exists
Despite being "just markdown", the repository is non-trivial to fork or integrate. Surprises that bite operators of derivative platforms include:
- The H6 (
######) heading convention for question titles, which breaks markdown TOC generators that default to H1–H4. - The locale directory naming convention is not standardised — some directories ship a plain
README.md, others shipREADME-{locale}.md, others shipREADME_{LOCALE}.md. Each variation has historical reasons but trips up bulk discovery scripts. - The
<details>/<summary>answer disclosure relies on HTML inside markdown, which means tools that strip HTML (some LaTeX-via-pandoc paths, some sanitised CMS imports) lose all the answers in one pass. - Translation completeness ranges from 155 / 155 (100%) to 43 / 155 (28%). Treating all locales as interchangeable produces broken UX in derivative apps.
- The English edition is canonical. Errata corrections land in English first; propagation to 22 translations is best-effort. Operators of multilingual derivative apps must decide whether they prefer "freshness" (English-first display + on-the-fly translation) or "consistency" (display the local-language file even if it lags by months).
Who maintains it
A single primary maintainer (Lydia Hallie, @lydiahallie) reviews and merges PRs at her own cadence. Translation maintainership is informal — there is no CODEOWNERS file delegating per-locale review. Whoever opens the most recent PR for a translation is, in practice, that translation's de facto steward until someone else takes over.
Note
The single-maintainer model is a deliberate constraint. It keeps editorial voice consistent across the canonical English edition, which in turn keeps translations stable targets. The trade-off is that PR queues can sit for weeks. Forks that need faster review velocity should plan to maintain their own divergent branch rather than wait on upstream.
License
MIT, copyright © 2019 Lydia Hallie. Reuse is permitted with attribution. The LICENSE file in the repository root is the authoritative text.
Source documented here
This Admin Guide describes the repository at commit a8b427b (merged 2024-03-10), which carries the merge commit Merge pull request #767 from abbas-roholamin/fix-typos. The repository structure documented below is stable across surrounding commits — the catalogue's architecture has not shifted since 2019.
2. Repository Architecture
2.1 What "architecture" means for a content repo
There is no application, no module graph, and no runtime call tree to diagram. The "architecture" is the layout convention — which files exist, what they contain, how they reference each other — and the editorial conventions that govern how content is added or amended.
2.2 Component inventory
| Component | Path | Role |
|---|---|---|
| Canonical English content | README.md |
The 155-question source-of-truth catalogue. All translations are derived from this file. |
| Translation editions | {locale}/README*.md |
22 community-maintained mirrors of the English content, each in its own top-level directory. |
| License | LICENSE |
MIT, applies to the entire repository. |
| Issue tracker | https://github.com/lydiahallie/javascript-questions/issues |
Errata reports, feature requests, translation-update threads. No dedicated forum, mailing list, or Discord. |
| Pull-request queue | GitHub PRs | The only ingestion mechanism for changes. |
There is no package.json, no .github/workflows/*.yml, no CONTRIBUTING.md, no CODEOWNERS, no ISSUE_TEMPLATE, no Dockerfile, no Makefile, no test directory, and no generated artefacts (no dist/, no build/, no gh-pages branch tracking a deployed site). The repository is exactly what you see in git ls-files.
Note
The intentional minimalism is itself a design decision. Every file added to the repository is a file that has to be maintained across 22 translations. By keeping the surface to one markdown file per locale plus a license, the maintainer keeps drift to a manageable shape: "is each translation up to date with English?" instead of "is each translation up to date with English and with the contributor guide and with the issue templates?"
2.3 Data flow (such as it is)
┌──────────────────────────┐
│ Canonical English README │
│ lydiahallie/main │
└────────────┬─────────────┘
│ (typo fix, errata,
│ new question, edit)
▼
┌───────────────────────────────────┐
│ PR opened on lydiahallie/main │
│ - reviewed by maintainer │
│ - merged if accepted │
└────────────┬──────────────────────┘
│ (merged commit)
▼
┌────────────────────────────────────────┐
│ 22 translation files now LAG canonical │
│ Each translation maintainer must open │
│ a follow-up PR mirroring the change │
└────────────────────────────────────────┘
│
▼
Out-of-band coordination
(issue threads, none formal)
There is no automation that watches the English file and notifies translators. Mirroring is purely social — translators check the file's git history when they next pick up a maintenance pass. This is the dominant source of translation drift documented in Section 6.4.
2.4 Technology stack
| Layer | Technology |
|---|---|
| Format | GitHub-Flavoured Markdown (GFM) |
| Embedded HTML | <details>, <summary>, <div>, <p>, <b>, <i> |
| Syntax highlighting | GitHub's built-in linguist (uses ```javascript fences) |
| Hosting | github.com |
| Issue tracking | GitHub Issues |
| Build / generate | None — files are checked in as-is |
| Deploy | None — github.com IS the rendering layer |
Note
The decision to embed raw HTML inside markdown (specifically
<details>/<summary>) is what enables the "click to reveal answer" mechanic. CommonMark allows pass-through HTML; GFM does too; most derivative tools (pandoc, MkDocs, Hugo, etc.) handle it correctly as long as they don't sanitise embedded HTML. CMSes that strip HTML (Jekyll withoutallow_html: true, some Confluence importers) will lose every answer.
3. System Requirements
3.1 For readers
A web browser, or any markdown viewer that:
- Renders GitHub-Flavoured Markdown.
- Honours embedded
<details>/<summary>HTML. - Optionally honours
<div dir='rtl'>for the Arabic editions.
There is no minimum hardware requirement worth listing. The largest README is ~5,151 lines / ~340 KB; an entry-level smartphone renders it without issue.
3.2 For translation contributors
| Requirement | Notes |
|---|---|
| Native or fluent reading proficiency in target language | Translation quality matters more than English-side fluency. |
| Reading proficiency in English | To consume the canonical edition. |
| Working JavaScript knowledge | To preserve technical accuracy across translation choices. |
| Git + GitHub account | For PR submission. |
| Markdown viewer | To preview your changes before submitting. |
| Basic awareness of locale-specific quoting conventions | Smart quotes, dashes, RTL handling for Arabic / Hebrew / Persian. |
3.3 For maintainers
Single-maintainer model. The de facto requirements are GitHub repo-admin access, JavaScript expertise sufficient to vet question accuracy without help, and editorial bandwidth — no formal cadence is enforced.
3.4 For fork operators integrating into a quiz platform
| Requirement | Notes |
|---|---|
| Markdown parser supporting GFM + raw HTML | markdown-it with html: true works; vanilla CommonMark does not parse <details>. |
| HTML-to-data transformer | To extract question/options/answer triples from prose. |
| Storage for parsed catalogue | SQLite, JSON, whatever fits your platform. |
| Update / sync mechanism | Cron-pulling the upstream branch, or a manual quarterly sync. |
| Strategy for translation lag | Decide: serve English fallback, or hide untranslated questions, or mark them as "untranslated". |
3.5 Hardware
None. There is no service to deploy. Hosting your fork costs whatever your git host costs (free on github.com; cheap-to-free on most alternatives).
4. Configuration Surface
There is no configuration file in the repository. The only knobs are editorial conventions, enforced by review rather than by code.
4.1 Editorial knobs (review-enforced)
| Convention | Value | Enforced by |
|---|---|---|
| Question heading level | H6 (###### N. <text>?) |
PR review |
| Answer verdict heading | H4 (#### Answer: <letter>) |
PR review |
| Code fence language tag | javascript |
PR review |
| Option list style | - A: <code> (bulleted, not ordered) |
PR review |
| Disclosure tag | <details><summary><b>Answer</b></summary> (or localised) |
PR review |
| Closing triple | </p> then </details> then --- then blank line |
PR review |
| Section separator | --- (horizontal rule) between every question |
PR review |
| Question numbering | Continuous, monotonically increasing, never re-numbered | PR review |
Important
Renumbering questions is the breaking change for the entire ecosystem of translations and derivative apps. A reviewer must reject any PR that shifts existing question numbers, even to fix a "gap" (there are no gaps in the canonical edition; numbers run 1 to 155 sequentially).
4.2 What is NOT configurable
- The repository name (
lydiahallie/javascript-questions) is referenced by every translation's relative-link index. Renaming would break all those links. - The default branch name (
main) is referenced from the maintainer's blog and external mirrors. - The license (MIT) is the project-wide license; relicensing would require approval from every contributor whose changes are still in the history.
5. Question Schema (Implicit Template)
Every question in every translation conforms to a strict schema, even though no tooling validates it. This section formalises the schema so derivative parsers can rely on it.
5.1 Canonical structure
###### {N}. {QUESTION TEXT}?
```javascript
{SNIPPET}
- A:
{OPTION A} - B:
{OPTION B} - C:
{OPTION C} - D:
{OPTION D}
<details><summary><b>Answer</b></summary> <p>
Answer: {LETTER}
{EXPLANATION PARAGRAPH(S)}
</p> </details>
### 5.2 Field-by-field semantics
| Field | Allowed values | Notes |
|---|---|---|
| `{N}` | Integer 1–155 (canonical edition) | Translations may have fewer; numbers must align with canonical. |
| `{QUESTION TEXT}` | Free-form question | Always ends with `?`. Often "What's the output?" but see UG §4 for variants. |
| `{SNIPPET}` | Self-contained JavaScript | No imports, no external state. Must be runnable in any modern browser console. |
| `{OPTION X}` | Lettered option (A, B, C, D, occasionally E/F) | Wrapped in inline backticks **except** when the option is itself prose (e.g. "True" / "False" / "Throws an error"). |
| `Answer` summary text | Localised label | "Answer", "Antwort", "Cevap", "答え", "정답", "Ответ", etc. |
| `{LETTER}` | Single uppercase letter A–F | Matches one of the option labels above. |
| `{EXPLANATION}` | Free-form prose, 1–4 paragraphs | May contain inline `<i>`, `<b>`, additional code blocks, or nested examples. |
### 5.3 Required structural elements
Every question MUST contain:
1. The H6 numbered heading.
2. At least one fenced JavaScript code block.
3. At least two lettered options.
4. The `<details>` block enclosing the answer.
5. The H4 `#### Answer: <letter>` line inside the disclosure.
6. The `</p></details>` closing pair (note: in some editions the order is `</p>` then `</details>`; in others it is just `</details>` — both render correctly because GFM closes orphan `<p>` automatically).
7. The trailing `---` horizontal rule that separates the question from the next.
### 5.4 Forbidden modifications
- **Do not** change the H6 to H3 — it inflates the table of contents to unreadable size.
- **Do not** convert option bullets to ordered lists — letter labels become double-numbered ("1. A:", "2. B:") in many viewers.
- **Do not** drop the language tag from code fences — GitHub will not syntax-highlight, and pandoc derivatives lose semantic info.
- **Do not** translate the option **letters** (`A`, `B`, `C`, `D`) outside locales that have an established convention for it (Egyptian Arabic uses `أ`, `ب`, `ج`, `د`). Letter labels function as cross-translation indices.
- **Do not** introduce ` ```js `, ` ```jsx `, or ` ```ts ` — the canonical fence is ` ```javascript `.
> [!WARNING]
> **Schema drift breaks parsers.** A derivative quiz platform that grep-extracts the H6 heading + first ` ```javascript ` block + bulleted options + `#### Answer:` line will silently miss any question that uses a non-conforming variant. If you accept a PR that breaks the schema in one place, you have entered a slow-moving compatibility crisis with every downstream tool. Prefer rejecting the PR and asking the contributor to conform.
---
## 6. Internationalization Implementation
The translation system is the most operationally complex aspect of the repository. This section documents how it actually works.
### 6.1 Locale directory naming
The 22 translation directories use the **`{language}-{REGION}`** convention with a two-letter ISO 639-1 language code and a two-letter ISO 3166-1 region code, separated by a hyphen. Both halves are lowercased except where regional usage dictates uppercase (which is the dominant pattern here):
ar-AR ar-EG bs-BS de-DE es-ES fr-FR id-ID it-IT ja-JA ko-KR nl-NL pl-PL pt-BR ro-RO ru-RU sq-KS th-TH tr-TR uk-UA vi-VI zh-CN zh-TW
> [!NOTE]
> Two of these codes are arguably non-standard: `ar-AR` (the language code is `ar`, but `AR` is not a country region — Arabic is supranational) and `sq-KS` (Kosovo's ISO code is `XK`, not `KS`). The maintainer accepts these because changing them would break every existing inbound link to those translation files.
### 6.2 Filename convention matrix
There are **three filename patterns** in active use, plus a Romanian special case. Pattern is locale-specific and reflects whichever convention the original translator chose:
| Pattern | Used by | Example path |
|---|---|---|
| Plain `README.md` | de-DE, id-ID, it-IT, nl-NL, pl-PL, ru-RU, th-TH, uk-UA | `de-DE/README.md` |
| `README-{LOCALE_VAR}.md` | bs-BS, es-ES, ja-JA, ko-KR, tr-TR, vi-VI, zh-CN | `bs-BS/README-bs_BS.md`, `es-ES/README-ES.md` |
| `README_{LOCALE_VAR}.md` | ar-AR, ar-EG, fr-FR, pt-BR, sq-KS, zh-TW | `ar-AR/README_AR.md`, `pt-BR/README_pt_BR.md` |
| `README.ro.md` | ro-RO **only** | `ro-RO/README.ro.md` |
The Romanian filename is unique. It uses a `.ro.md` middle-dot suffix (which is a multi-extension pattern uncommon in this project but used elsewhere in software). It still ends in `.md` so GitHub renders it correctly, but auto-discovery scripts that hard-code `README.md` will miss it.
> [!IMPORTANT]
> If you are writing a fork-discovery script, treat the locale directory as the source of truth and accept ANY `README*.md` file inside it. Do not assume `README.md`. Concretely:
> ```bash
> find . -mindepth 2 -maxdepth 2 -name 'README*.md' -not -path './.git/*'
> ```
### 6.3 Translation discovery mechanism
There is no manifest file. The English README contains a `<details>` block titled *"See 20 Available Translations"* with a hand-maintained markdown list of relative links to each translation's path:
```markdown
- [🇸🇦 العربية](./ar-AR/README_AR.md)
- [🇪🇬 اللغة العامية](./ar-EG/README_ar-EG.md)
- [🇧🇦 Bosanski](./bs-BS/README-bs_BS.md)
- [🇩🇪 Deutsch](./de-DE/README.md)
- ...
Each translation file should reciprocally link back to peer translations near the top of the file (most do; some are inconsistent). The list is manually edited when a new locale is added — there is no script that walks the filesystem and regenerates it.
Note
The "20 Available Translations" header in the English README is stale by two locales — the actual count is 22. The maintainer hasn't updated the heading text as new translations have been added. The list itself is correct (22 entries); only the summary count is outdated. This is a known cosmetic drift; not a content bug.
6.4 Translation drift snapshot
Coverage (questions translated / 155) at commit a8b427b:
| Locale | Questions | Coverage | Drift class |
|---|---|---|---|
| English (canonical) | 155 | 100% | n/a |
it-IT |
155 | 100% | Caught up |
ko-KR |
155 | 100% | Caught up |
ro-RO |
155 | 100% | Caught up |
ru-RU |
155 | 100% | Caught up |
sq-KS |
155 | 100% | Caught up |
zh-TW |
155 | 100% | Caught up |
id-ID |
153 | 99% | Lagging by 2 |
vi-VI |
152 | 98% | Lagging by 3 |
zh-CN |
150 | 97% | Lagging by 5 |
nl-NL |
144 | 93% | Lagging by 11 |
de-DE |
127 | 82% | Stale |
es-ES |
115 | 74% | Stale |
th-TH |
107 | 69% | Stale |
tr-TR |
95 | 61% | Stale |
ja-JA |
83 | 54% | Heavily stale |
pt-BR |
80 | 52% | Heavily stale |
pl-PL |
75 | 48% | Heavily stale |
ar-AR |
~65 | 42% | Heavily stale |
fr-FR |
64 | 41% | Heavily stale |
uk-UA |
46 | 30% | Mostly empty |
bs-BS |
43 | 28% | Mostly empty |
ar-EG |
43 | 28% | Mostly empty |
Caution
If you fork the catalogue into a multilingual quiz platform, declare a coverage policy explicitly. Three reasonable policies: (1) hide untranslated questions in non-canonical locales; (2) show them in English when the local translation is missing; (3) display a "translation incomplete after Q{N}" banner. Silently truncating the catalogue at the locale's last translated question is the worst option — users see a working app that ends abruptly with no explanation.
6.5 Cross-locale errata propagation
When the canonical English answer is corrected, propagation to the 22 translations is not automatic. The historical pattern is:
- An issue is opened against the English answer (e.g. #782 against Q61).
- A PR fixes the English README. Merged.
- The English question now has a different correct answer than its 22 translation counterparts.
- The discrepancy persists until a translation maintainer notices and opens a follow-up PR for their locale.
Because there is no automation watching for English changes, the median time-to-propagation across locales is months to years. Forks that need timely propagation should script their own diff: monitor git log --follow README.md and emit a notification when a question's content (snippet, options, or answer) changes.
Tip
A useful audit query against the upstream repo: identify every commit that touches
README.mdsince a given date, then for each touched line, identify which question it falls inside (by walking backwards to the previous H6 heading). The output is a per-question changelog that translation maintainers can prioritise from.
7. Operations Playbook
7.1 New-question PR review
Inbound PRs adding a question (rare in 2024+; the catalogue is mostly stable) should be evaluated against a fixed checklist:
- [x] Numbered as N+1 where N is the current canonical maximum (currently 155).
- [x] Conforms to the schema in §5.
- [x] Snippet is runnable as-is in a browser console without errors.
- [x] Snippet does not depend on a feature post-2019 unless the maintainer explicitly opens that scope.
- [x] At least one option label maps to the correct answer.
- [x] Explanation cites the language behaviour, not a library or framework.
- [x] No copyright violations (the snippet is original or trivially small).
- [x] No PII in the snippet (no real-looking email addresses, API keys, etc.).
Reject (with comment) if any item fails.
7.2 Errata PR review
Inbound PRs fixing an existing question (the dominant PR type) should be evaluated against a different checklist:
- [x] PR description references the issue number (
Fixes #NNN). - [x] Change is scoped to a single question (or to a coordinated multi-question fix if the same bug affects several).
- [x] Updated explanation can be verified by running the snippet against a current JavaScript engine.
- [x] Question numbering is unchanged.
- [x] Translation files are untouched in this PR (translations get follow-up PRs).
- [x] Diff doesn't accidentally re-flow surrounding questions due to whitespace changes.
Accept if all check; merge with a squash commit so the history stays linear.
7.3 Translation PR review
Translations are reviewed by the primary maintainer because there is no formal per-locale CODEOWNER. The review is necessarily lighter on linguistic accuracy:
- [x] PR is scoped to one locale.
- [x] Question numbering aligns with the English edition for every translated question.
- [x] Code blocks are unchanged from the English source (variable names, string literals, output strings remain LTR JavaScript).
- [x] Heading levels match (H6 for question, H4 for answer verdict).
- [x] No Unicode-direction glitches (RTL Arabic doesn't accidentally pull the closing markdown fence into reverse direction).
- [x] No accidental untranslated stretches (a translation that reverts to English mid-explanation needs another pass).
7.4 Issue triage cadence
There is no formal SLA. The historical pattern is:
| Issue type | Typical time-to-first-response | Typical time-to-close |
|---|---|---|
| Typo / clear errata | Days | Weeks (when a PR lands) |
| Disputed answer | Weeks | Months (or never if community consensus shifts) |
| Translation request for new locale | Days (welcoming response) | Open until someone submits a PR |
| Vague "this is wrong" without specifics | Weeks if at all | Often closes stale |
| Author-personal link broken (e.g. #647) | Variable | Slow; these are not a high priority |
Forks that need predictable triage should fork rather than depend on upstream cadence.
7.5 Adding a new locale
- Open an issue titled
Translation request: {Language}. Wait for maintainer ack to avoid duplicating someone else's in-flight work. - Create a new top-level directory:
{lang}-{REGION}/following the convention in §6.1. - Pick a filename pattern matching one of the three patterns in §6.2. There is no formal preference; pick whichever pattern is closest to the prevailing style of similar locales.
- Translate at least the first 30 questions in the initial PR. PRs with fewer questions are sometimes accepted but get less review attention.
- Add an entry to the English README's translation index, in alphabetical order by locale code.
- Optionally add a peer-translation index inside your new file.
- Submit the PR with a description committing to maintenance ("I will keep this translation up to date with the English edition").
7.6 Maintaining the LICENSE
The LICENSE file is unchanged since the repository's creation. Modifications should be rejected unless there is a fundamental relicensing decision (which would require dual-licensing or explicit consent from significant historical contributors). The current MIT terms are sufficient for the catalogue's intended use.
8. Security and Threat Model
8.1 What this repository does NOT need
| Threat | Why it doesn't apply |
|---|---|
| Code injection | No user input flows anywhere — content is static. |
| Dependency vulnerabilities | Zero runtime dependencies. |
| Authentication / authorisation | No protected resources; everything is public. |
| Secret management | No secrets in the repository (verify with git log -p on a regular cadence anyway). |
| API rate limiting | No API. |
| DoS protection | github.com handles rendering. |
8.2 What it DOES benefit from
- Branch protection on
mainto prevent force pushes that would invalidate inbound links and historical permalinks. - Required PR review before merge — already enforced as the de facto policy.
- Two-factor authentication on the maintainer account. Compromise of the account would be the only realistic catastrophic failure mode.
- GitHub's secret-scanning to flag any accidental secret committed by a contributor (e.g. someone pasting an actual API key into a Q&A snippet for "realism"). Free for public repositories.
SECURITY.mddocumenting how to report security-flavoured issues. Currently absent. A content-correctness vulnerability (e.g. a question whose answer is silently wrong) can damage learners' careers; a reporting channel for those is worth having.
8.3 Fork-operator threats
Operators of derivative tools should consider:
- Question-stem injection. If you accept user-submitted questions in addition to the canonical catalogue, sanitise them for embedded
<script>/<iframe>HTML. The original repository can rely on github.com's renderer; a custom platform cannot. - Cross-locale spoofing. Don't trust user-supplied "language preference" cookies blindly to select a translation file — pick from a server-side allowlist of the 23 known locale codes.
- Stale-cache attacks. Aggressive caching of the catalogue can hide errata for weeks. Build cache-invalidation logic that respects errata-PR merge timestamps.
Warning
A particularly subtle integration bug: when serving a translation, several locales' files use the same filename (
README.md) inside their locale directory. Hard-coding a static path likei18n/{lang}/README.mdworks for some locales but produces 404s forbs-BS,es-ES,fr-FR, and a dozen others. Always discover translation files at run-time from the filesystem, not from a hard-coded path.
9. Repository Structure
9.1 Top-level layout
javascript-questions/
├── LICENSE # MIT, copyright (c) 2019 Lydia Hallie
├── README.md # Canonical English edition — 155 questions
├── ar-AR/
│ └── README_AR.md # Modern Standard Arabic — ~65 questions, RTL
├── ar-EG/
│ └── README_ar-EG.md # Egyptian colloquial Arabic — 43 questions
├── bs-BS/
│ └── README-bs_BS.md # Bosnian — 43 questions
├── de-DE/
│ └── README.md # German — 127 questions
├── es-ES/
│ └── README-ES.md # Spanish — 115 questions
├── fr-FR/
│ └── README_fr-FR.md # French — 64 questions
├── id-ID/
│ └── README.md # Indonesian — 153 questions
├── it-IT/
│ └── README.md # Italian — 155 questions (full)
├── ja-JA/
│ └── README-ja_JA.md # Japanese — 83 questions
├── ko-KR/
│ └── README-ko_KR.md # Korean — 155 questions (full)
├── nl-NL/
│ └── README.md # Dutch — 144 questions
├── pl-PL/
│ └── README.md # Polish — 75 questions
├── pt-BR/
│ └── README_pt_BR.md # Portuguese (Brazil) — 80 questions
├── ro-RO/
│ └── README.ro.md # Romanian — 155 questions (full)
├── ru-RU/
│ └── README.md # Russian — 155 questions (full)
├── sq-KS/
│ └── README_sq_KS.md # Albanian (Kosovo) — 155 questions (full)
├── th-TH/
│ └── README.md # Thai — 107 questions
├── tr-TR/
│ └── README-tr_TR.md # Turkish — 95 questions
├── uk-UA/
│ └── README.md # Ukrainian — 46 questions
├── vi-VI/
│ └── README-vi.md # Vietnamese — 152 questions
├── zh-CN/
│ └── README-zh_CN.md # Chinese (Simplified) — 150 questions
└── zh-TW/
└── README_zh-TW.md # Chinese (Traditional) — 155 questions (full)
Total: 24 tracked files (23 README markdowns + the LICENSE).
9.2 What's NOT in the repository
To save fork operators time investigating, here is what you will not find:
- No
package.json,package-lock.json,yarn.lock,pnpm-lock.yaml,bun.lockb— there are no JavaScript dependencies because there is no JavaScript code to run. - No
.github/directory — no Actions workflows, no issue templates, no PR templates, no CODEOWNERS, no dependabot config, no funding.yml. - No
CONTRIBUTING.md,CODE_OF_CONDUCT.md,SECURITY.md,SUPPORT.md. - No
tests/,__tests__/, or any test runner config. - No
Dockerfile,docker-compose.yml,.devcontainer/. - No
Makefile,justfile,Taskfile. - No
.eslintrc*,.prettierrc*,.editorconfig,tsconfig.json. - No
docs/,site/,website/, or generated documentation directories. - No image assets — every locale README links the JavaScript icon directly from
img.icons8.com. - No
.gitignore— all tracked files are markdown or LICENSE; nothing is generated.
Note
The absence of
.gitignoreis unusual for a top-1000 GitHub repository and reflects the genuinely empty nature of the build surface. Forks that introduce a build step (e.g. converting markdown into a custom format) should add a.gitignorefor their generated outputs.
9.3 Untracked / ignored files
Because no .gitignore exists, contributors should be cautious about:
- Editor temp files (
.swp,.DS_Store,Thumbs.db) accidentally committed. - OS-specific noise (
Icon\r,desktop.ini).
These have appeared in PRs historically. Reviewers should reject any PR that introduces non-content files.
10. Code Patterns and Conventions
The "code" in this project is prose plus embedded JavaScript snippets. Both have conventions worth documenting.
10.1 Markdown conventions in use
| Convention | Pattern | Rationale |
|---|---|---|
| Question heading | ###### N. {text}? (H6) |
Visual subordination so 155 headings don't dominate the document outline. |
| Answer verdict | #### Answer: {LETTER} (H4) |
Subordinate to the parent question heading. Visually distinct inside the disclosure. |
| Question separator | --- (thematic break) |
Renders as a horizontal rule in GitHub. |
| Code fence language | ```javascript (full word, not js) |
GitHub's linguist resolves both, but full-word is the catalogue's chosen consistency. |
| Inline code | `…` (single backticks) |
For variables, options labels (often), and short outputs. |
| Emphasis | *italic* and **bold** |
Standard GFM. |
| Lists | - A: ... (hyphen, not asterisk) |
Hyphen is the dominant style; some translations drift to *. |
10.2 Code-snippet style conventions
| Convention | Example | Rationale |
|---|---|---|
| 2-space indent | function f() {\n console.log(x);\n} |
Matches Lydia's broader code style. |
| Single quotes | console.log('hello') (mostly) |
Some snippets use double quotes — drift the maintainer hasn't normalised. |
| Semicolons | Mixed; varies per question | Not strictly enforced; readers shouldn't infer style guidance. |
No 'use strict' directive |
unless the question is specifically testing strict-mode behaviour | Matches the implicit "browser DevTools console" mental model. |
console.log for output |
console.log(x) |
Never print, never process.stdout.write — the platform is browser-aligned. |
| Variable names | Short and contextual: x, y, name, age, arr, obj, f, g, member, randomValue |
Consistent across questions; aids translation because translators don't have to mentally re-bind names. |
10.3 Explanation-prose conventions
- Inline backticks for technical terms at first use:
`var`,`let`,`Promise`, etc. - Italic for emphasis on conceptual labels: "This is called the temporal dead zone" — italics signal "term of art", not stress.
- Numbered lists rare; prose paragraphs preferred. Explanations are typically 1–3 paragraphs.
- Cross-references between questions are uncommon; each question stands alone. This is intentional — a reader should never need question N to understand question M.
- No screenshots, no diagrams. The runnable snippet plus prose is the entire mental model. A handful of questions reference a hypothetical browser console output; no visual rendering of it.
11. Quality Heuristics
When reviewing new content (or auditing an existing question for correctness), several heuristics distinguish a strong contribution from a weak one.
11.1 Strong-question signals
- The snippet is short (≤ 15 lines) and self-contained.
- The snippet runs without modification in a current browser console.
- At least one option is the plausible-but-wrong answer that catches readers who haven't internalised the relevant concept.
- The explanation reveals a single, identifiable language behaviour rather than a confluence of three quirks.
- The explanation cites a specific runtime mechanism (hoisting, scope chain, microtask queue) by name, anchoring the reader to a learnable concept.
11.2 Weak-question warning signs
- Snippet relies on engine-specific ordering that disagrees between V8, SpiderMonkey, and JavaScriptCore.
- Multiple correct answers exist depending on environment (browser vs Node, strict vs sloppy, module vs script).
- Explanation hand-waves with phrases like "because that's just how JavaScript works".
- Snippet uses a feature not yet in the catalogue's scope (top-level await, decorators, private fields).
- The "correct" answer is the literal text on the page rather than the runtime behaviour (e.g. answer is
'undefined'as a string vs the valueundefined). - Question depends on a Web API behaviour rather than a language behaviour.
11.3 Translation quality signals
- Translated explanation is a paraphrase, not a literal word-for-word translation. Literal translations of English idioms produce clumsy target-language prose.
- Technical terms use the target language's accepted vocabulary — Hebezeit vs hoisting in German, подъем vs хойстинг in Russian. Consult the existing translated questions for established terminology.
- RTL languages (Arabic) keep code blocks LTR with appropriate
<div>wrappers around the prose. - Number formatting in prose follows local conventions (1.000 vs 1,000 for "one thousand"); inside code blocks, JavaScript syntax (always
1000) is preserved.
Tip
The fastest way to spot a low-effort translation is to check whether the original Lydia anecdote in the README intro paragraph (e.g. "yes I'm sad lol") was translated. If it's still in English, the translation is likely a copy-paste-and-replace job rather than an idiomatic rewrite.
12. Improvements Roadmap
This section catalogues outstanding issues and the maintainer-stance on each, so derivative platforms can decide which to absorb into their forks.
12.1 Open content issues
| Issue | Stance | Notes |
|---|---|---|
| #820 (RU translation of Q98) | Awaiting PR | Russian-speaking contributor needed. |
| #819 (Q25 explanation incomplete) | Will accept improved explanation | The integer-key-then-string-key insertion-order rule should be added. |
| #797 (Q14 about object prototypes) | Discussion | Whether Object.create(null) counts as having "no prototype" or "a null prototype" is contested. |
| #831 (Q7 == vs ===) | Will accept improved explanation | Current text doesn't explain coercion explicitly enough. |
| #827 (Russian translation Q71/Q119/Q126) | Awaiting PR | Translation maintenance. |
| #824 (static class member inheritance) | Discussion | The behaviour is correct as documented; the issue is whether "inheritable" is the right word. |
| #814 ("Changes required.") | Closing stale | Author hasn't elaborated. |
| #835, #826, #829 ("V", "Oh?", "Hello") | Closing stale | Empty issue bodies; not actionable. |
12.2 Closed feature requests worth knowing about
| Issue | Resolution |
|---|---|
| #714 (rearrange topic-wise) | Declined. Renumbering breaks translation alignment. A topic index could be added without renumbering — see §12.3. |
| #647 (broken external link) | Closed. Author-personal site went private; the link in README has not been removed but is harmless. |
| #782 (Q61 wrong answer) | Resolved in earlier commit. |
12.3 Improvements appropriate for forks (not upstream)
These would not be merged upstream because they would expand scope, but a fork may want them:
- A topic index file (
TOPICS.md) that groups questions 1–155 by subject (closures, prototypes, etc.) without renumbering. Could live in a fork as a curated reading order. - Per-question difficulty tags (
Easy/Medium/Hard). The maintainer has not introduced difficulty labels because it would require relabelling 22 translations. Forks can do it client-side based on a single canonical mapping. - A scoring/quiz mode UI. The repository is content; building a quiz UI on top is a separate project.
- Modern-JavaScript supplement (Q156+) covering 2020–2025 features. If you fork to add this, you opt out of inheriting the upstream commitment to "frozen at 2019".
- Anki / SRS export. Question + answer + explanation map cleanly to flashcard front/back. A script can extract them — but you'll have to handle the
<details>HTML and the H6 numbering quirk. - Sitemap of permalinks. A
sitemap.xmlexposing each#N-question-textanchor would help search engines surface individual questions; not needed for the canonical README on github.com but useful for derivative sites.
12.4 Things not on the roadmap
- Build pipeline. Will not be added; the absence is intentional.
- CI for content validation. Could be added (a markdown linter that checks H6 numbering monotonicity, code-fence language tags,
<details>balance) but historically hasn't been. - Web app. Out of scope upstream. Forks have built quiz apps; the maintainer doesn't endorse any one of them.
- Internationalisation tooling. Tools like Crowdin or Weblate could replace the manual translation workflow but would impose process overhead the project hasn't needed at its current pace.
13. Troubleshooting
13.1 Common failure modes for fork operators
Error: <details> blocks render as plain text in my pipeline
Cause: Your markdown processor is sanitising HTML, or you're using a CommonMark parser without the GFM extensions.
Solution:
- If using
markdown-it: enablehtml: truein the constructor options. - If using
marked: ensurebreaksandgfmare enabled (they are by default in v4+). - If using pandoc: pass
-f gfm(not-f markdown) and--wrap=none. - If using a CMS importer (Confluence, Notion, etc.): check for an HTML allowlist setting; add
details,summary,p,b,i,divto the permitted tags.
Prevention: Test your pipeline against the canonical README before importing all 22 translations. If question 1's answer doesn't expand on click in your output, the disclosure is broken everywhere.
Error: Question count mismatch between English and translation in my parser
Cause: Your parser is counting ^###### \d+\. headings; the locale you're parsing uses a non-standard heading style (Modern Arabic ar-AR uses bold-numbered prose, no H6).
Solution: Build a locale-aware regex. For most locales, ^######\s+\d+\. works. For ar-AR, the pattern is ^\d+\.\s+ (no heading hashes — questions use plain numbered list items).
Prevention: Run a count audit per locale before relying on parsed output. The expected counts are in §6.4.
Error: My TOC generator includes 155 question titles, making the TOC unusable
Cause: Default markdown-TOC tools include H1–H6 by default. The catalogue's H6-per-question pattern explodes the TOC.
Solution: Limit TOC depth. In markdown-toc, pass --maxdepth 4. In MkDocs, set toc.permalink: false and toc.toc_depth: 4. In pandoc, --toc-depth=3.
Prevention: Choose a TOC depth that matches the catalogue's structural intent (H2/H3 only, never H6).
Error: 404 when clicking the Thai translation link
Cause: The English README links to ./th-TH/README-th_TH.md, but the actual file is ./th-TH/README.md.
Solution: Patch your fork's English README to use the correct relative path. Optionally upstream the fix.
Prevention: Validate all relative links during fork ingestion. A simple markdown-link-check invocation catches this in CI.
Error: Egyptian Arabic option labels (أ, ب, ج, د) don't map to English A/B/C/D in my answer-letter audit
Cause: ar-EG is the only locale that translates the option labels. Other locales preserve A/B/C/D.
Solution: Build a locale-specific letter map. For ar-EG: أ → A, ب → B, ج → C, د → D.
Prevention: Document the locale-specific exceptions in your data layer. Don't assume label uniformity.
Error: Russian translation contradicts the English answer for Q98
Cause: Issue #820 (open at the time of writing) — the Russian translation is wrong.
Solution: Trust the English answer until #820 is resolved. If your fork is multilingual, consider adding a maintainer note flag so users see "this question's translation has a known issue" until upstream resolves it.
Prevention: Subscribe to the upstream issue tracker for the questions your derivative platform highlights.
Error: My pandoc-to-PDF conversion produces a 600-page document because <details> blocks are all expanded
Cause: Pandoc renders <details> content unconditionally; the "click to expand" is a runtime behaviour of HTML, not a markdown semantic.
Solution: This is expected. If you want a printable version with all answers visible, accept the page count. If you want a "questions only" version, pre-process the markdown to strip the <details> blocks before conversion.
Prevention: Decide upfront whether your derivative artefact is interactive (HTML, render-time disclosure preserved) or printable (PDF/EPUB, all content visible).
Error: Git blame on a translation file shows unhelpful "Merge pull request" commits
Cause: Squash-merge PRs collapse the per-line authorship.
Solution: Use git log --follow {translation-file} | grep -A5 'Author:' to find the most recent non-merge commit touching the file. That author is usually the translation's de facto current maintainer.
Prevention: When opening a translation-update PR, include Co-authored-by: lines in your commit message to preserve credit through the squash.
13.2 Common content-side failure modes
Error: A question's answer doesn't match what I observe in Node
Cause: Many questions assume browser semantics (especially around the global object, strict mode default, and document.… references). A handful exhibit different ordering in Node due to microtask scheduling differences.
Solution: Test in a browser DevTools console first. If browser and the answer agree but Node disagrees, the discrepancy is a runtime difference, not a question bug.
Prevention: When discussing answers, note your runtime environment.
Error: A question's answer depends on a JavaScript engine version
Cause: Some edge-case behaviours have evolved across spec revisions. The catalogue's snapshot is roughly 2019.
Solution: Test with an engine close to the catalogue's vintage (Node 12+, Chrome 75+) for canonical-era behaviour. Most answers are stable across engines and versions.
Prevention: When in doubt, the canonical English answer is the authority — engines may behave differently in some Marian corner case, but the catalogue documents what the spec said.
14. Quick Reference
14.1 File / locale lookup
| Locale | Path |
|---|---|
| English | README.md |
| Arabic (Modern) | ar-AR/README_AR.md |
| Arabic (Egyptian) | ar-EG/README_ar-EG.md |
| Bosnian | bs-BS/README-bs_BS.md |
| German | de-DE/README.md |
| Spanish | es-ES/README-ES.md |
| French | fr-FR/README_fr-FR.md |
| Indonesian | id-ID/README.md |
| Italian | it-IT/README.md |
| Japanese | ja-JA/README-ja_JA.md |
| Korean | ko-KR/README-ko_KR.md |
| Dutch | nl-NL/README.md |
| Polish | pl-PL/README.md |
| Portuguese (Brazil) | pt-BR/README_pt_BR.md |
| Romanian | ro-RO/README.ro.md |
| Russian | ru-RU/README.md |
| Albanian | sq-KS/README_sq_KS.md |
| Thai | th-TH/README.md |
| Turkish | tr-TR/README-tr_TR.md |
| Ukrainian | uk-UA/README.md |
| Vietnamese | vi-VI/README-vi.md |
| Chinese (Simplified) | zh-CN/README-zh_CN.md |
| Chinese (Traditional) | zh-TW/README_zh-TW.md |
14.2 Schema cheat sheet
###### N. {QUESTION}?
```javascript
{SNIPPET}
- A:
{OPT_A} - B:
{OPT_B} - C:
{OPT_C} - D:
{OPT_D}
<details><summary><b>Answer</b></summary> <p>
Answer: {LETTER}
{EXPLANATION}
</p> </details>
### 14.3 Useful audit commands
Count questions per locale (assumes you're in the repo root):
```bash
for f in $(find . -mindepth 2 -maxdepth 2 -name 'README*.md'); do
printf "%-40s %d\n" "$f" "$(grep -cE '^###### [0-9]+\.' "$f")"
done | sort -k2 -n -r
./README.md 155
./it-IT/README.md 155
./ko-KR/README-ko_KR.md 155
./ro-RO/README.ro.md 155
./ru-RU/README.md 155
./sq-KS/README_sq_KS.md 155
./zh-TW/README_zh-TW.md 155
./id-ID/README.md 153
./vi-VI/README-vi.md 152
./zh-CN/README-zh_CN.md 150
…
Find every commit that changed a question's correctness (modifies a #### Answer: line):
git log -p --all -- 'README.md' | grep -E '^[+-]#### Answer:' | head -20
+#### Answer: A
-#### Answer: B
+#### Answer: C
…
(A +/- pair on the same question is the smoking gun for an answer correction.)
Verify that every question heading in the canonical README is monotonically numbered:
grep -E '^###### [0-9]+\.' README.md | grep -oE '[0-9]+' | awk '
NR==1 { prev=$1; next }
$1 != prev+1 { print "GAP at " prev " -> " $1; exit 1 }
{ prev=$1 }
END { print "OK: " prev " questions, monotonic" }'
OK: 155 questions, monotonic
14.4 Maintainer contacts
- Maintainer: Lydia Hallie (
@lydiahallieon GitHub). - Issue tracker: https://github.com/lydiahallie/javascript-questions/issues
- Pull-request queue: https://github.com/lydiahallie/javascript-questions/pulls
- License: MIT, copyright © 2019 Lydia Hallie. See
LICENSEin the repo root.
14.5 Glossary
Canonical edition
: The English README.md at the repository root. The source of truth for question content, numbering, and answer correctness.
Locale
: A {language}-{REGION} directory containing one translation file. There are 22 locales plus the canonical English at the root.
Translation drift
: The state where a translation file documents an older version of the canonical edition because errata or new questions have not yet been propagated.
Answer letter
: The single uppercase character (A/B/C/D, occasionally E/F) inside #### Answer: that names the correct option for a question.
Disclosure widget
: The HTML <details>/<summary> mechanism that hides the answer until clicked.
Schema
: The implicit per-question structural template documented in §5.
Stale link
: A relative link in the canonical README that points to a path that no longer exists (e.g. the Thai filename mismatch noted in §6 and §13.1).
Errata
: A correction to an existing question's answer or explanation, as opposed to the addition of a new question.
Renumbering
: Changing question numbers for any reason. Forbidden.